Читать все SMS от определенного отправителя

Как прочитать мне все SMS от определенного отправителя? Например. Я хочу отсканировать а) тело и б) дату/время всех SMS, пришедших от TM-MYAMEX на телефон.

Некоторые веб-сайты указывают, что это можно прочитать из «content://sms/inbox». Я не мог понять, как именно. Также не уверен, поддерживается ли он на большинстве телефонов. Я использую Galaxy S2.


person KalEl    schedule 03.06.2012    source источник


Ответы (5)


попробуйте так:

StringBuilder smsBuilder = new StringBuilder();
       final String SMS_URI_INBOX = "content://sms/inbox"; 
        final String SMS_URI_ALL = "content://sms/";  
        try {  
            Uri uri = Uri.parse(SMS_URI_INBOX);  
            String[] projection = new String[] { "_id", "address", "person", "body", "date", "type" };  
            Cursor cur = getContentResolver().query(uri, projection, "address='123456789'", null, "date desc");
             if (cur.moveToFirst()) {  
                int index_Address = cur.getColumnIndex("address");  
                int index_Person = cur.getColumnIndex("person");  
                int index_Body = cur.getColumnIndex("body");  
                int index_Date = cur.getColumnIndex("date");  
                int index_Type = cur.getColumnIndex("type");         
                do {  
                    String strAddress = cur.getString(index_Address);  
                    int intPerson = cur.getInt(index_Person);  
                    String strbody = cur.getString(index_Body);  
                    long longDate = cur.getLong(index_Date);  
                    int int_Type = cur.getInt(index_Type);  

                    smsBuilder.append("[ ");  
                    smsBuilder.append(strAddress + ", ");  
                    smsBuilder.append(intPerson + ", ");  
                    smsBuilder.append(strbody + ", ");  
                    smsBuilder.append(longDate + ", ");  
                    smsBuilder.append(int_Type);  
                    smsBuilder.append(" ]\n\n");  
                } while (cur.moveToNext());  

                if (!cur.isClosed()) {  
                    cur.close();  
                    cur = null;  
                }  
            } else {  
                smsBuilder.append("no result!");  
            } // end if  
            }
        } catch (SQLiteException ex) {  
            Log.d("SQLiteException", ex.getMessage());  
        }  

AndroidManifest.xml:

<uses-permission android:name="android.permission.READ_SMS" />
person ρяσѕρєя K    schedule 03.06.2012
comment
Это работает очень хорошо, спасибо! я даже пробовал с предложением IN, и он работает, как и ожидалось... но... как насчет формата адреса? В инструкции sql where, если я ищу адрес 3485152182, он работает, но если я ищу 348 5152182 или 348 5152 182 или +393485152182 (тот же адрес с международным префиксом), запрос завершится ошибкой. Есть ли элегантный способ решить эту проблему? Благодарность! - person GiveEmTheBoot; 17.12.2012
comment
@GiveEmTheBoot: я думаю, что нет общего способа сделать это, вы можете просто использовать некоторые строковые методы, такие как 348 5152 182, в этом случае вы можете сначала обрезать этот номер, а затем выполнить его поиск или +393485152182, если вы сначала удалите знак + из номера, а затем выполните поиск - person ρяσѕρєя K; 17.12.2012
comment
@ProsperK... большое спасибо! Я надеялся сделать это более простым и элегантным способом... возможно, если смс-адреса будут храниться в том же формате/формате, что и в контактах, я смогу лучше достичь своей цели. Кто-то это знает? - person GiveEmTheBoot; 18.12.2012
comment
Я хотел бы знать, совпадают ли адреса, хранящиеся в поле адреса таблицы sms, с адресами, хранящимися в таблице контактов. Если у моего контакта Джека в качестве номера телефона в моих контактах есть 348 8591236, будет ли моя таблица смс содержать точно 348 8591236 в поле адреса? Надеюсь, теперь я выразился яснее. - person GiveEmTheBoot; 18.12.2012
comment
@GiveEmTheBoot: да, вы правы, так как номер хранится в списке контактов, тот же пользователь увидит в списке SMS, если SMS придет с того же номера. - person ρяσѕρєя K; 18.12.2012
comment
@ProsperK Хорошо, понял! Большое спасибо за вашу помощь! - person GiveEmTheBoot; 19.12.2012
comment
Во-первых, использовать этот sql, где предложение strrev(address) как + android.telephony.PhoneNumberUtils.toCallerIDMinMatch(3435158138) +%. Он просто переворачивает последние N цифр телефонного номера. - person GiveEmTheBoot; 23.12.2012
comment
Или используйте функцию sql PHONE_NUMBERS_EQUAL следующим образом: PHONE_NUMBERS_EQUAL (адрес, 3435158138). Эта функция sql работает отлично (она используется в огромном количестве классов в android, таких как ContactInfoCache), но она является частью непубличного API, поэтому лучше использовать ее только в случае крайней необходимости. - person GiveEmTheBoot; 23.12.2012
comment
@ρяσѕρєяK что представляет type в массиве projection? - person Gopal Gopi; 22.03.2014
comment
@ρяσѕρєяK может запустить его как сервис и следить за входящим смс. - person Sagar Devanga; 15.01.2015
comment
@GopalGopi: type представляет MESSAGE_TYPE_SENT (постоянное значение = 2), MESSAGE_TYPE_INBOX (постоянное значение = 1) и т. д. (developer.android.com/reference/android/provider/) - person Bugs Happen; 24.08.2016
comment
Можем ли мы передать более одного числа или массива по адресу. Чтобы получать все сообщения с этих номеров @ρяσѕρєяK - person Anjali Patel; 06.10.2017
comment
как добавить несколько условий. я хочу указать условия адреса и даты (uri, проекция, адрес = '123456789', ноль, дата desc); здесь адрес только условие, я хочу только сегодняшние сообщения и с определенного номера - person Usman; 07.02.2018
comment
У меня 2 симки в телефоне! Можно ли проверить, какой сим получает сообщение? - person Huzaifa Asif; 03.10.2019

попробуйте это, это простой способ прочитать сообщение из почтового ящика.

public class ReadMsg extends AppCompatActivity {

ListView listView;
private static final int PERMISSION_REQUEST_READ_CONTACTS = 100;
ArrayList smsList;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_read_msg);
    listView = (ListView)findViewById(R.id.idList);

    int permissionCheck = ContextCompat.checkSelfPermission(this, Manifest.permission.READ_SMS);

    if (permissionCheck == PackageManager.PERMISSION_GRANTED){
        showContacts();
    }else{
        ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.READ_SMS},PERMISSION_REQUEST_READ_CONTACTS);
    }
}

private void showContacts() {
    Uri inboxURI = Uri.parse("content://sms/inbox");
    smsList = new ArrayList();
    ContentResolver cr = getContentResolver();


    Cursor c = cr.query(inboxURI,null,null,null,null);
    while (c.moveToNext()){
        String Number = c.getString(c.getColumnIndexOrThrow("address")).toString();
        String Body= c.getString(c.getColumnIndexOrThrow("body")).toString();
        smsList.add("Number: "+ Number + "\n" + "Body: "+ Body );
    }
        c.close();
    ArrayAdapter adapter = new ArrayAdapter(this, android.R.layout.simple_list_item_1, smsList);
    listView.setAdapter(adapter);
}

}

Добавьте это разрешение в манифесты.

<uses-permission android:name="android.permission.READ_SMS"></uses-permission>
person Tabish khan    schedule 06.07.2017

 protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        inbox = (Button) findViewById(R.id.inbox);
        list = (ListView) findViewById(R.id.list);
        arlist = new ArrayList<String>();
        inbox.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Uri inboxUri = Uri.parse("content://sms/inbox");
                String[] reqCols = {"_id", "body", "address"};
                ContentResolver cr = getContentResolver();
                Cursor cursor = cr.query(inboxUri, reqCols, "address='+919456'", null, null);
                adapter = new SimpleCursorAdapter(getApplicationContext(), R.layout.msg_content_layout, cursor,
                        new String[]{"body", "address"}, new int[]{R.id.txt1, R.id.txt2});
                list.setAdapter(adapter);
            }
        });

    }

Здесь я добавил число +919456 в качестве значения поля адреса.

Помимо этого вам нужно добавить разрешение READ_SMS на манифест:

person Anubhav    schedule 04.07.2015
comment
Будет ли это соответствовать номеру телефона в любом его формате, с пробелами и без, с международным кодом страны и без? - person Flimm; 23.11.2018

вы можете сделать это в несколько строк кода

String[] phoneNumber = new String[] { "+923329593103" }; 
Cursor cursor1 = getContentResolver().query(Uri.parse("content://sms/inbox"), new String[] { "_id", "thread_id", "address", "person", "date","body", "type" }, "address=?", phoneNumber, null);
                 StringBuffer msgData = new StringBuffer();
                if (cursor1.moveToFirst()) { 
                    do {


                       for(int idx=0;idx<cursor1.getColumnCount();idx++)
                       {
                           msgData.append(" " + cursor1.getColumnName(idx) + ":" + cursor1.getString(idx));
                       }

                    } while (cursor1.moveToNext());
                } else {

                     edtmessagebody.setText("no message from this contact"+phoneNumber);
                }
person Adiii    schedule 11.07.2015
comment
Будет ли это соответствовать номеру телефона в любом его формате, с пробелами и без, с международным кодом страны и без? - person Flimm; 23.11.2018

public class SmsController extends BroadcastReceiver {

@Override
public void onReceive(Context context, Intent intent) {
SmsMessage msgs[] = null;
Bundle bundle = intent.getExtras();
try {
    Object pdus[] = (Object[]) bundle.get("pdus");
    msgs = new SmsMessage[pdus.length];
    for (int n = 0; n < pdus.length; n++) {
        byte[] byteData = (byte[]) pdus[n];
        msgs[n] = SmsMessage.createFromPdu(byteData);
    }
} catch (Exception e) {

}
for (int i = 0; i < msgs.length; i++) {
    String message = msgs[i].getDisplayMessageBody();
    if (message != null && message.length() > 0) {
        String from = msgs[i].getOriginatingAddress();
        if(FROM.contains("TM-MYAMEX")){
            String  body = message ;
            Date datetime = new Date() ;
            } 
        }
    }
  }
 }
}

Я не уверен, что означает «TM-MYAMEX», но вот код для получения всех SMS.

Date = new Date()потому что это под BroadcastReceiverтогда время, когда вы получаете сообщение, это текущее время.

Надеюсь, это поможет.

person 113408    schedule 03.06.2012
comment
TM-MYAMEX означает, что это сообщение получено от American Express. Я просто хотел знать, передаете ли вы это значение в адресе при таком запросе cr.query(inboxUri, null, "address='TM-MYAMEX'", null, null); возвращает 0 SMS. Кто-нибудь знает, как получить смс от этих отправителей?? - person yashhy; 14.04.2017