Je veux récupérer les messages SMS de l'appareil et les afficher?
Je veux récupérer les messages SMS de l'appareil et les afficher?
Réponses:
Utilisez Content Resolver ( "content: // sms / mailbox" ) pour lire les SMS qui se trouvent dans la boîte de réception.
// public static final String INBOX = "content://sms/inbox";
// public static final String SENT = "content://sms/sent";
// public static final String DRAFT = "content://sms/draft";
Cursor cursor = getContentResolver().query(Uri.parse("content://sms/inbox"), null, null, null, null);
if (cursor.moveToFirst()) { // must check the result to prevent exception
do {
String msgData = "";
for(int idx=0;idx<cursor.getColumnCount();idx++)
{
msgData += " " + cursor.getColumnName(idx) + ":" + cursor.getString(idx);
}
// use msgData
} while (cursor.moveToNext());
} else {
// empty box, no SMS
}
Veuillez ajouter l' autorisation READ_SMS .
J'espère que ça aide :)
moveToFirst
comme moi.
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
final String myPackageName = getPackageName();
if (!Telephony.Sms.getDefaultSmsPackage(this).equals(myPackageName)) {
Intent intent = new Intent(Telephony.Sms.Intents.ACTION_CHANGE_DEFAULT);
intent.putExtra(Telephony.Sms.Intents.EXTRA_PACKAGE_NAME, myPackageName);
startActivityForResult(intent, 1);
}else {
List<Sms> lst = getAllSms();
}
}else {
List<Sms> lst = getAllSms();
}
Définir l'application comme application SMS par défaut
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == 1) {
if (resultCode == RESULT_OK) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
final String myPackageName = getPackageName();
if (Telephony.Sms.getDefaultSmsPackage(mActivity).equals(myPackageName)) {
List<Sms> lst = getAllSms();
}
}
}
}
}
Fonction pour recevoir des SMS
public List<Sms> getAllSms() {
List<Sms> lstSms = new ArrayList<Sms>();
Sms objSms = new Sms();
Uri message = Uri.parse("content://sms/");
ContentResolver cr = mActivity.getContentResolver();
Cursor c = cr.query(message, null, null, null, null);
mActivity.startManagingCursor(c);
int totalSMS = c.getCount();
if (c.moveToFirst()) {
for (int i = 0; i < totalSMS; i++) {
objSms = new Sms();
objSms.setId(c.getString(c.getColumnIndexOrThrow("_id")));
objSms.setAddress(c.getString(c
.getColumnIndexOrThrow("address")));
objSms.setMsg(c.getString(c.getColumnIndexOrThrow("body")));
objSms.setReadState(c.getString(c.getColumnIndex("read")));
objSms.setTime(c.getString(c.getColumnIndexOrThrow("date")));
if (c.getString(c.getColumnIndexOrThrow("type")).contains("1")) {
objSms.setFolderName("inbox");
} else {
objSms.setFolderName("sent");
}
lstSms.add(objSms);
c.moveToNext();
}
}
// else {
// throw new RuntimeException("You have no SMS");
// }
c.close();
return lstSms;
}
La classe SMS est ci-dessous:
public class Sms{
private String _id;
private String _address;
private String _msg;
private String _readState; //"0" for have not read sms and "1" for have read sms
private String _time;
private String _folderName;
public String getId(){
return _id;
}
public String getAddress(){
return _address;
}
public String getMsg(){
return _msg;
}
public String getReadState(){
return _readState;
}
public String getTime(){
return _time;
}
public String getFolderName(){
return _folderName;
}
public void setId(String id){
_id = id;
}
public void setAddress(String address){
_address = address;
}
public void setMsg(String msg){
_msg = msg;
}
public void setReadState(String readState){
_readState = readState;
}
public void setTime(String time){
_time = time;
}
public void setFolderName(String folderName){
_folderName = folderName;
}
}
N'oubliez pas de définir l'autorisation dans votre AndroidManifest.xml
<uses-permission android:name="android.permission.READ_SMS" />
String receiveDayTime = Functions.dateFromMilisec(Long.valueOf(c.getColumnIndexOrThrow("date")), "hh:mm a MMM dd, yyyy");
new SimpleDateFormat("hh:mm", Locale.US).format(new Date(Long.parseLong(_time)));
Cela vous donnera 24 heures.
mActivity
n'est pas défini. Qu'est-ce que c'est?
C'est un processus trivial. Vous pouvez voir un bon exemple dans le code source SMSPopup
Examinez les méthodes suivantes:
SmsMmsMessage getSmsDetails(Context context, long ignoreThreadId, boolean unreadOnly)
long findMessageId(Context context, long threadId, long _timestamp, int messageType
void setMessageRead(Context context, long messageId, int messageType)
void deleteMessage(Context context, long messageId, long threadId, int messageType)
c'est la méthode de lecture:
SmsMmsMessage getSmsDetails(Context context,
long ignoreThreadId, boolean unreadOnly)
{
String SMS_READ_COLUMN = "read";
String WHERE_CONDITION = unreadOnly ? SMS_READ_COLUMN + " = 0" : null;
String SORT_ORDER = "date DESC";
int count = 0;
// Log.v(WHERE_CONDITION);
if (ignoreThreadId > 0) {
// Log.v("Ignoring sms threadId = " + ignoreThreadId);
WHERE_CONDITION += " AND thread_id != " + ignoreThreadId;
}
Cursor cursor = context.getContentResolver().query(
SMS_INBOX_CONTENT_URI,
new String[] { "_id", "thread_id", "address", "person", "date", "body" },
WHERE_CONDITION,
null,
SORT_ORDER);
if (cursor != null) {
try {
count = cursor.getCount();
if (count > 0) {
cursor.moveToFirst();
// String[] columns = cursor.getColumnNames();
// for (int i=0; i<columns.length; i++) {
// Log.v("columns " + i + ": " + columns[i] + ": " + cursor.getString(i));
// }
long messageId = cursor.getLong(0);
long threadId = cursor.getLong(1);
String address = cursor.getString(2);
long contactId = cursor.getLong(3);
String contactId_string = String.valueOf(contactId);
long timestamp = cursor.getLong(4);
String body = cursor.getString(5);
if (!unreadOnly) {
count = 0;
}
SmsMmsMessage smsMessage = new SmsMmsMessage(context, address,
contactId_string, body, timestamp,
threadId, count, messageId, SmsMmsMessage.MESSAGE_TYPE_SMS);
return smsMessage;
}
} finally {
cursor.close();
}
}
return null;
}
À partir de l'API 19, vous pouvez utiliser la classe de téléphonie pour cela; Étant donné que les valeurs enregistrées en dur ne récupèrent pas les messages sur tous les appareils, car le fournisseur de contenu Uri change d'appareil et de fabricant.
public void getAllSms(Context context) {
ContentResolver cr = context.getContentResolver();
Cursor c = cr.query(Telephony.Sms.CONTENT_URI, null, null, null, null);
int totalSMS = 0;
if (c != null) {
totalSMS = c.getCount();
if (c.moveToFirst()) {
for (int j = 0; j < totalSMS; j++) {
String smsDate = c.getString(c.getColumnIndexOrThrow(Telephony.Sms.DATE));
String number = c.getString(c.getColumnIndexOrThrow(Telephony.Sms.ADDRESS));
String body = c.getString(c.getColumnIndexOrThrow(Telephony.Sms.BODY));
Date dateFormat= new Date(Long.valueOf(smsDate));
String type;
switch (Integer.parseInt(c.getString(c.getColumnIndexOrThrow(Telephony.Sms.TYPE)))) {
case Telephony.Sms.MESSAGE_TYPE_INBOX:
type = "inbox";
break;
case Telephony.Sms.MESSAGE_TYPE_SENT:
type = "sent";
break;
case Telephony.Sms.MESSAGE_TYPE_OUTBOX:
type = "outbox";
break;
default:
break;
}
c.moveToNext();
}
}
c.close();
} else {
Toast.makeText(this, "No message to show!", Toast.LENGTH_SHORT).show();
}
}
Ce message est un peu ancien, mais voici une autre solution simple pour obtenir des données liées au SMS
fournisseur de contenu dans Android:
Utilisez cette lib: https://github.com/EverythingMe/easy-content-providers
Obtenez tout SMS
:
TelephonyProvider telephonyProvider = new TelephonyProvider(context);
List<Sms> smses = telephonyProvider.getSms(Filter.ALL).getList();
Chaque Sms possède tous les champs, vous pouvez donc obtenir toutes les informations dont vous avez besoin:
adresse, corps, date de réception, type (INBOX, SENT, DRAFT, ..), threadId, ...
Gel tout MMS
:
List<Mms> mmses = telephonyProvider.getMms(Filter.ALL).getList();
Gel tout Thread
:
List<Thread> threads = telephonyProvider.getThreads().getList();
Gel tout Conversation
:
List<Conversation> conversations = telephonyProvider.getConversations().getList();
Il fonctionne avec List
ou Cursor
et il existe un exemple d'application pour voir à quoi il ressemble et fonctionne.
En fait, il existe un support pour tous les fournisseurs de contenu Android tels que: contacts, journaux d'appels, calendrier, ... Doc complet avec toutes les options: https://github.com/EverythingMe/easy-content-providers/wiki/Android- fournisseurs
J'espère que cela a également aidé :)
Étape 1: nous devons d'abord ajouter des autorisations dans le fichier manifeste comme
<uses-permission android:name="android.permission.RECEIVE_SMS" android:protectionLevel="signature" />
<uses-permission android:name="android.permission.READ_SMS" />
Étape 2: puis ajoutez la classe de récepteur SMS de service pour recevoir des SMS
<receiver android:name="com.aquadeals.seller.services.SmsReceiver">
<intent-filter>
<action android:name="android.provider.Telephony.SMS_RECEIVED"/>
</intent-filter>
</receiver>
Étape 3: ajouter l'autorisation d'exécution
private boolean checkAndRequestPermissions()
{
int sms = ContextCompat.checkSelfPermission(this, Manifest.permission.READ_SMS);
if (sms != PackageManager.PERMISSION_GRANTED)
{
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.READ_SMS}, REQUEST_ID_MULTIPLE_PERMISSIONS);
return false;
}
return true;
}
Étape 4: Ajoutez ces classes dans votre application et testez la classe Interface
public interface SmsListener {
public void messageReceived(String messageText);
}
SmsReceiver.java
public class SmsReceiver extends BroadcastReceiver {
private static SmsListener mListener;
public Pattern p = Pattern.compile("(|^)\\d{6}");
@Override
public void onReceive(Context context, Intent intent) {
Bundle data = intent.getExtras();
Object[] pdus = (Object[]) data.get("pdus");
for(int i=0;i<pdus.length;i++)
{
SmsMessage smsMessage = SmsMessage.createFromPdu((byte[]) pdus[i]);
String sender = smsMessage.getDisplayOriginatingAddress();
String phoneNumber = smsMessage.getDisplayOriginatingAddress();
String senderNum = phoneNumber ;
String messageBody = smsMessage.getMessageBody();
try
{
if(messageBody!=null){
Matcher m = p.matcher(messageBody);
if(m.find()) {
mListener.messageReceived(m.group(0)); }
else {}} }
catch(Exception e){} } }
public static void bindListener(SmsListener listener) {
mListener = listener; }}
Il y a beaucoup de réponses déjà disponibles mais je pense que toutes manquent une partie importante de cette question. Avant de lire les données d'une base de données interne ou de sa table, nous devons comprendre comment les données y sont stockées et ensuite nous pouvons trouver la solution de la question ci-dessus qui est:
Comment puis-je lire les messages SMS de l'appareil par programmation dans Android?
Donc, dans la table SMS Android, c'est comme ça
Sachez que nous pouvons sélectionner ce que nous voulons dans la base de données. Dans notre cas, nous
identifiant, adresse et corps
En cas de lecture de SMS:
1.Demander des autorisations
int REQUEST_PHONE_CALL = 1;
if (ContextCompat.checkSelfPermission(MainActivity.this, Manifest.permission.READ_SMS) != PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(MainActivity.this, new String[]{Manifest.permission.READ_SMS}, REQUEST_PHONE_CALL);
}
ou
<uses-permission android:name="android.permission.READ_SMS" />
Maintenant, votre code va comme ça
// Create Inbox box URI
Uri inboxURI = Uri.parse("content://sms/inbox");
// List required columns
String[] reqCols = new String[]{"_id", "address", "body"};
// Get Content Resolver object, which will deal with Content Provider
ContentResolver cr = getContentResolver();
// Fetch Inbox SMS Message from Built-in Content Provider
Cursor c = cr.query(inboxURI, reqCols, null, null, null);
// Attached Cursor with adapter and display in listview
adapter = new SimpleCursorAdapter(this, R.layout.a1_row, c,
new String[]{"body", "address"}, new int[]{
R.id.A1_txt_Msg, R.id.A1_txt_Number});
lst.setAdapter(adapter);
J'espère que celui-ci vous sera utile. Merci.
Les services Google Play disposent de deux API que vous pouvez utiliser pour rationaliser le processus de vérification par SMS
Fournit une expérience utilisateur entièrement automatisée, sans obliger l'utilisateur à taper manuellement les codes de vérification et sans nécessiter d'autorisations d'application supplémentaires et doit être utilisé lorsque cela est possible. Cependant, il vous oblige à placer un code de hachage personnalisé dans le corps du message, vous devez donc également contrôler le côté serveur .
Demander une vérification par SMS dans une application Android
Effectuer une vérification SMS sur un serveur
API de consentement de l'utilisateur SMS
Ne nécessite pas le code de hachage personnalisé, mais oblige l'utilisateur à approuver la demande de votre application pour accéder au message contenant le code de vérification. Afin de minimiser les chances de faire apparaître le mauvais message à l'utilisateur, SMS User Consent
filtrera les messages des expéditeurs dans la liste des contacts de l'utilisateur.
The SMS User Consent API
fait partie des services Google Play. Pour l'utiliser, vous aurez besoin d'au moins une version 17.0.0
de ces bibliothèques:
implementation "com.google.android.gms:play-services-auth:17.0.0"
implementation "com.google.android.gms:play-services-auth-api-phone:17.1.0"
Étape 1: Commencez à écouter les messages SMS
Le consentement de l'utilisateur SMS écoutera les messages SMS entrants contenant un code à usage unique pendant cinq minutes maximum. Il ne regardera aucun message envoyé avant son démarrage. Si vous connaissez le numéro de téléphone qui enverra le code à usage unique, vous pouvez spécifier le senderPhoneNumber
, ou si vous ne null
correspondez à aucun numéro.
smsRetriever.startSmsUserConsent(senderPhoneNumber /* or null */)
Étape 2: demander le consentement pour lire un message
Une fois que votre application reçoit un message contenant un code à usage unique, elle sera notifiée par une diffusion. À ce stade, vous n'avez pas le consentement pour lire le message - à la place, vous obtenez un Intent
que vous pouvez commencer à inviter l'utilisateur à donner son consentement. Dans votre BroadcastReceiver
, vous affichez l'invite en utilisant le Intent
dans le extras
. Lorsque vous démarrez cette intention, il demandera à l'utilisateur l'autorisation de lire un seul message. Ils verront l'intégralité du texte qu'ils partageront avec votre application.
val consentIntent = extras.getParcelable<Intent>(SmsRetriever.EXTRA_CONSENT_INTENT)
startActivityForResult(consentIntent, SMS_CONSENT_REQUEST)
Étape 3: analyser le code unique et terminer la vérification SMS
Lorsque l'utilisateur clique “Allow”
- il est temps de lire le message! À l'intérieur de onActivityResult
vous, vous pouvez obtenir le texte intégral du message SMS à partir des données:
val message = data.getStringExtra(SmsRetriever.EXTRA_SMS_MESSAGE)
Vous analysez ensuite le message SMS et passez le code à usage unique à votre backend!
4-10 digit alphanumeric code containing at least one number
Pouvez-vous expliquer ce que cela signifie? Cela signifie-t-il que la longueur du message entier doit être de 4 à 10 caractères uniquement du code sms?
String WHERE_CONDITION = unreadOnly ? SMS_READ_COLUMN + " = 0" : null;
changé par:
String WHERE_CONDITION = unreadOnly ? SMS_READ_COLUMN + " = 0 " : SMS_READ_COLUMN + " = 1 ";
Code Kotlin pour lire les SMS:
1- Ajoutez cette autorisation à AndroidManifest.xml:
<uses-permission android:name="android.permission.RECEIVE_SMS"/>
2-Créez une classe BroadCastreceiver:
package utils.broadcastreceivers
import android.content.BroadcastReceiver
import android.content.Context
import android.content.Intent
import android.telephony.SmsMessage
import android.util.Log
class MySMSBroadCastReceiver : BroadcastReceiver() {
override fun onReceive(context: Context?, intent: Intent?) {
var body = ""
val bundle = intent?.extras
val pdusArr = bundle!!.get("pdus") as Array<Any>
var messages: Array<SmsMessage?> = arrayOfNulls(pdusArr.size)
// if SMSis Long and contain more than 1 Message we'll read all of them
for (i in pdusArr.indices) {
messages[i] = SmsMessage.createFromPdu(pdusArr[i] as ByteArray)
}
var MobileNumber: String? = messages[0]?.originatingAddress
Log.i(TAG, "MobileNumber =$MobileNumber")
val bodyText = StringBuilder()
for (i in messages.indices) {
bodyText.append(messages[i]?.messageBody)
}
body = bodyText.toString()
if (body.isNotEmpty()){
// Do something, save SMS in DB or variable , static object or ....
Log.i("Inside Receiver :" , "body =$body")
}
}
}
3-Obtenez l'autorisation SMS si Android 6 et supérieur:
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M &&
ActivityCompat.checkSelfPermission(context!!,
Manifest.permission.RECEIVE_SMS
) != PackageManager.PERMISSION_GRANTED
) { // Needs permission
requestPermissions(arrayOf(Manifest.permission.RECEIVE_SMS),
PERMISSIONS_REQUEST_READ_SMS
)
} else { // Permission has already been granted
}
4- Ajoutez ce code de demande à l'activité ou au fragment:
companion object {
const val PERMISSIONS_REQUEST_READ_SMS = 100
}
5- Override Check permissionstion Request result fun:
override fun onRequestPermissionsResult(
requestCode: Int, permissions: Array<out String>,
grantResults: IntArray
) {
when (requestCode) {
PERMISSIONS_REQUEST_READ_SMS -> {
if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
Log.i("BroadCastReceiver", "PERMISSIONS_REQUEST_READ_SMS Granted")
} else {
// toast("Permission must be granted ")
}
}
}
}
La fonction la plus simple
Pour lire le sms j'ai écrit une fonction qui retourne un objet Conversation:
class Conversation(val number: String, val message: List<Message>)
class Message(val number: String, val body: String, val date: Date)
fun getSmsConversation(context: Context, number: String? = null, completion: (conversations: List<Conversation>?) -> Unit) {
val cursor = context.contentResolver.query(Telephony.Sms.CONTENT_URI, null, null, null, null)
val numbers = ArrayList<String>()
val messages = ArrayList<Message>()
var results = ArrayList<Conversation>()
while (cursor != null && cursor.moveToNext()) {
val smsDate = cursor.getString(cursor.getColumnIndexOrThrow(Telephony.Sms.DATE))
val number = cursor.getString(cursor.getColumnIndexOrThrow(Telephony.Sms.ADDRESS))
val body = cursor.getString(cursor.getColumnIndexOrThrow(Telephony.Sms.BODY))
numbers.add(number)
messages.add(Message(number, body, Date(smsDate.toLong())))
}
cursor?.close()
numbers.forEach { number ->
if (results.find { it.number == number } == null) {
val msg = messages.filter { it.number == number }
results.add(Conversation(number = number, message = msg))
}
}
if (number != null) {
results = results.filter { it.number == number } as ArrayList<Conversation>
}
completion(results)
}
En utilisant:
getSmsConversation(this){ conversations ->
conversations.forEach { conversation ->
println("Number: ${conversation.number}")
println("Message One: ${conversation.message[0].body}")
println("Message Two: ${conversation.message[1].body}")
}
}
Ou obtenez uniquement la conversation d'un numéro spécifique:
getSmsConversation(this, "+33666494128"){ conversations ->
conversations.forEach { conversation ->
println("Number: ${conversation.number}")
println("Message One: ${conversation.message[0].body}")
println("Message Two: ${conversation.message[1].body}")
}
}