2009-05-11 7 views

Répondre

56

C'est un processus trivial. Vous pouvez voir un bon exemple dans le code source SMSPopup

Examiner 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; 
} 
+40

Cela ne fait pas partie du SDK Android. Ce code fait l'hypothèse incorrecte que tous les périphériques prennent en charge ce fournisseur de contenu non documenté et non pris en charge. Google a explicitement indiqué que s'appuyer sur ce n'est pas une bonne idée: http://android-developers.blogspot.com/2010/05/be-careful-with-content-providers.html – CommonsWare

+5

@CommonsWare ce qui serait une solution correcte pour ça? – Janusz

+0

@Janusz: Il n'existe aucun moyen documenté et pris en charge qui fonctionne sur tous les clients SMS sur tous les périphériques. – CommonsWare

123

Utiliser le contenu résolveur (« Contenu:// sms/inbox ") pour lire les SMS qui sont 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 
} 

S'il vous plaît ajouter READ_SMS permission.

J'espère que cela aide :)

+7

Merci! Vous avez mal orthographié "getColumnName", sinon que cela fonctionne comme un charme. Oh, et si quelqu'un va utiliser ceci, n'oubliez pas d'ajouter l'autorisation android.permission.READ_SMS. – qwerty

+1

Merci. Je l'ai modifié :) –

+5

Est-ce que cela utilise aussi l'API non documentée que @CommonsWare a spécifiée dans son commentaire à la réponse acceptée? – Krishnabhadra

55
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(); 
    } 

Set application comme application de 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 obtenir 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; 
} 

Sms classe 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; 
} 

} 

Ne pas oublier de définir l'autorisation dans votre AndroidManifest.xml

<uses-permission android:name="android.permission.READ_SMS" /> 
+3

où est la classe Sms utilisée dans ce code? – mSafdel

+2

C'est un bon morceau de code. Juste une chose, le temps est obtenu en millisecondes. Je pense qu'il vaudra mieux en faire un format lisible par l'homme comme 'String receiveDayTime = Fonctions.dateFromMilisec (Long.valueOf (c.getColumnIndexOrThrow ("date")), "hh: mm un MMM jj, aaaa"); ' –

+1

quel est le but de tout faire avec getter et setter, je ne comprends vraiment pas pourquoi il suffit d'utiliser un tableau assoc ou une classe dont les éléments sont directement accessibles –

2
String WHERE_CONDITION = unreadOnly ? SMS_READ_COLUMN + " = 0" : null; 

modifié par:

String WHERE_CONDITION = unreadOnly ? SMS_READ_COLUMN + " = 0 " : SMS_READ_COLUMN + " = 1 "; 
+1

Est-ce une réponse à http://stackoverflow.com/a/851668/1470607? – Nit

19

Ce poste est un peu vieux, mais voici une autre solution facile pour Obtenir des données relatives au fournisseur de contenu SMS dans Android:

Utilisez cette lib: https://github.com/EverythingMe/easy-content-providers

  • Obtenez tous SMS:

    TelephonyProvider telephonyProvider = new TelephonyProvider(context); 
    List<Sms> smses = telephonyProvider.getSms(Filter.ALL).getList(); 
    

    Chaque Sms a tous les domaines, de sorte que vous pouvez obtenir toute information dont vous avez besoin:
    adresse, corps, receivedDate, le type (INBOX, SENT, DRAFT, ..), threadId, ...

  • Gel tous MMS:

    List<Mms> mmses = telephonyProvider.getMms(Filter.ALL).getList(); 
    
  • Gel tous 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.

il y a En fait, un soutien à tous les fournisseurs de contenu Android comme: contacts, les journaux d'appels, le calendrier ... doc complète avec toutes les options: https://github.com/EverythingMe/easy-content-providers/wiki/Android-providers

espère que cela a aussi aidé :)

+1

Le code source et les exemples sur le github sont très utiles. C'est un bon emballage/façade pour la plupart des fournisseurs communs. Je vous remercie. – erm3nda

8

É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 classe de service de réception de sms pour recevoir 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 exécuter l'autorisation de temps

private boolean checkAndRequestPermissions() 
{ 

    int sms = ContextCompat.checkSelfPermission(this, Manifest.permission.READ_SMS); 
    int loc = ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION); 
    int loc2 = ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION); 
    List<String> listPermissionsNeeded = new ArrayList<>(); 

    if (sms != PackageManager.PERMISSION_GRANTED) 
    { 
     listPermissionsNeeded.add(Manifest.permission.READ_SMS); 
    } 
    if (loc != PackageManager.PERMISSION_GRANTED) { 
     listPermissionsNeeded.add(android.Manifest.permission.ACCESS_FINE_LOCATION); 
    } 
    if (loc2 != PackageManager.PERMISSION_GRANTED) { 
     listPermissionsNeeded.add(Manifest.permission.ACCESS_COARSE_LOCATION); 
    } 
    if (!listPermissionsNeeded.isEmpty()) 
    { 
     ActivityCompat.requestPermissions(this,listPermissionsNeeded.toArray(new 
       String[listPermissionsNeeded.size()]),REQUEST_ID_MULTIPLE_PERMISSIONS); 
     return false; 
    } 
    return true; 
} 

Étape 4: Ajouter cette classe dans votre application et tester Interface classe

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; }} 

CODAGE HEUREUX

+0

Que fait le motif? –

+1

il est en lecture seule les chiffres dans ce message 6 chiffres –

+0

Eh bien ... est-ce ("com.aquadeals.seller.services.SmsReceiver") le nom du service commun? – erm3nda

9

A partir de 19 API partir vous pouvez utiliser la classe de téléphonie pour cela; Étant donné que les valeurs en dur ne récupèrent pas les messages dans tous les appareils, car le fournisseur de contenu Uri change d'appareils et de fabricants.

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(); 
      } 
     } 
    } else { 
     Toast.makeText(this, "No message to show!", Toast.LENGTH_SHORT).show(); 
    } 
} 
+3

Semble être la seule réponse qui n'utilise pas d'API non documentée et ne se réfère pas à des bibliothèques tierces. – Ishamael

+0

J'ai essayé d'utiliser ce code pour obtenir des messages SMS de Hangouts (qui est mon application SMS par défaut). Au lieu de cela, il a récupéré le dernier message sortant que j'ai envoyé via Messenger ... Savez-vous ce qui cause cela? –

+0

@MikiP en utilisant mes pouvoirs devinettes Je vais dire que Messenger App vous a demandé de remplacer la gestion des SMS avec Messenger. Cela arrive avec une autre application de messagerie. Je n'ai pas d'autre explication. – erm3nda

1

Il y a beaucoup de réponses sont déjà disponibles mais je pense que tous manquent une partie importante de cette question. Avant de lire les données à partir d'une base de données interne ou sa table, nous devons comprendre comment les données sont stockées dans et alors nous pouvons trouver la solution de la question ci-dessus qui est:

Comment puis-je lire des messages SMS à partir du périphérique programme dans Android?

Ainsi, Dans le tableau android SMS est comme ressembler à ceci

enter image description here

savoir, nous pouvons choisir ce que nous voulons de la database.In notre cas, nous avons seulement besoin

identification, adresse et corps

En cas de lecture SMS:

1.Ask pour les 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" /> 

2.Now votre code va comme ceci

// 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 sera utile. Merci.

Questions connexes