Использование нового поставщика контента Telephony для чтения SMS

В соответствии с 4.4 SMS API новая версия предоставляет функциональные возможности:

позволяют приложениям читать и записывать SMS и MMS-сообщения на устройстве

Я не могу найти никакой информации об этой функциональности, ни каких-либо образцов в новом SDK. Это то, что я до сих пор читал для новых входящих сообщений.

Однако я хотел бы читать существующие сообщения, хранящиеся в процессе:

// Can I only listen for incoming SMS, or can I read existing stored SMS?
SmsMessage[] smsList = Telephony.Sms.Intents.getMessagesFromIntent(intent);
for(SmsMessage sms : smsList) {
    Log.d("Test", sms.getMessageBody())
}

Обратите внимание: Я знаю об использовании поставщика контента SMS, однако этот метод не поддерживается. Согласно связанным API, я должен иметь возможность сделать это поддерживаемым способом.

Ответы

Ответ 1

Похоже, вы сможете использовать этот класс, чтобы заставить его работать. Пакет Telephony.Sms.Conversations.

Хотя в следующем коде используется метод поставщика контента, теперь это официальный API, добавленный в API 19 (KitKat) для чтения SMS-сообщений.

public List<String> getAllSmsFromProvider() {
  List<String> lstSms = new ArrayList<String>();
  ContentResolver cr = mActivity.getContentResolver();

  Cursor c = cr.query(Telephony.Sms.Inbox.CONTENT_URI, // Official CONTENT_URI from docs
                      new String[] { Telephony.Sms.Inbox.BODY }, // Select body text
                      null,
                      null,
                      Telephony.Sms.Inbox.DEFAULT_SORT_ORDER); // Default sort order

  int totalSMS = c.getCount();

  if (c.moveToFirst()) {
      for (int i = 0; i < totalSMS; i++) {
          lstSms.add(c.getString(0));
          c.moveToNext();
      }
  } else {
      throw new RuntimeException("You have no SMS in Inbox"); 
  }
  c.close();

  return lstSms;
}

Ответ 2

Я сделал это следующим образом. Создать SMSObject:

public class SMSObject {
  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;

  //+ getter and setter methods and 

  @Override
  public String toString() {
    return "SMSObject [_id=" + _id + ", _address=" + _address + ", _msg="
            + _msg + ", _readState=" + _readState + ", _time=" + _time
            + ", _folderName=" + _folderName + "]";
}

И здесь простая функция, которая просто регистрирует все текущие SMS-объекты

private void readSMS() {
    List<SMSObject> lstSms = new ArrayList<SMSObject>();
    SMSObject objSms = new SMSObject();
    Uri message = Uri.parse("content://sms/");
    ContentResolver cr = this.getContentResolver();

    Cursor c = cr.query(message, null, null, null, null);
    // this.startManagingCursor(c);
    int totalSMS = c.getCount();
    Log.d("SMS Count->", "" + totalSMS);
    if (c.moveToFirst()) {
        for (int i = 0; i < totalSMS; i++) {

            objSms = new SMSObject();
            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);

            Log.d("SMS at " + i, objSms.toString());

            c.moveToNext();
        }
    }
    // else {
    // throw new RuntimeException("You have no SMS");
    // }
    c.close();

    // return lstSms;

}

Ответ 3

Я нашел это несколько дней назад, не могу вспомнить с какого сайта; Вы можете восстановить сообщения только в том случае, если пользователь решил сделать приложение стандартным смс-приложением. Это может или не может полностью ответить на ваш вопрос. Я еще не пробовал это

  • Запросить текущее имя пакета SMS-приложений по умолчанию и сохранить его.

    String defaultSmsApp = Telephony.Sms.getDefaultSmsPackage(context);
    
  • Попросите пользователя изменить приложение SMS по умолчанию для вашего приложения, чтобы восстановить SMS-сообщения (вы должны быть стандартным SMS-приложением, чтобы писать поставщику SMS-сообщений).

    Intent intent = new Intent(context, Sms.Intents.ACTION_CHANGE_DEFAULT);
    intent.putExtra(Sms.Intents.EXTRA_PACKAGE_NAME, context.getPackageName());
    startActivity(intent);