Android получает sms-разговор с именем или адресом
Я разрабатываю SMS-программу, и я хочу получить разговоры.
Я написал код ниже, и он отлично работает, но мне интересно, может ли он быть более эффективным
Это для получения цепочек цепочек
Uri SMS_INBOX = Uri.parse("content://sms/conversations/");
Cursor c = getContentResolver().query(SMS_INBOX, null, null, null, "date desc");
startManagingCursor(c);
String[] count = new String[c.getCount()];
String[] snippet = new String[c.getCount()];
String[] thread_id = new String[c.getCount()];
c.moveToFirst();
for (int i = 0; i < c.getCount(); i++) {
count[i] = c.getString(c.getColumnIndexOrThrow("msg_count"))
.toString();
thread_id[i] = c.getString(c.getColumnIndexOrThrow("thread_id"))
.toString();
snippet[i] = c.getString(c.getColumnIndexOrThrow("snippet"))
.toString();
//Toast.makeText(getApplicationContext(), count[i] + " - " + thread_id[i]+" - "+snippet[i] , Toast.LENGTH_LONG).show();
c.moveToNext();
}
c.close();
для получения адресов в соответствии с потоком беседы
for(int ad = 0; ad < thread_id.length ; ad++)
{
Uri uri = Uri.parse("content://sms/inbox");
String where = "thread_id="+thread_id[ad];
Cursor mycursor= getContentResolver().query(uri, null, where ,null,null);
startManagingCursor(mycursor);
String[] number = new String[mycursor.getCount()];
if(mycursor.moveToFirst()){
for(int i=0;i<mycursor.getCount();i++){
number[i]=mycursor.getString(mycursor.getColumnIndexOrThrow("address")).toString();
mycursor.moveToNext();
}
}
mycursor.close();
и, наконец, проверку адресов (если в списке контактов) и добавление в список
for(int i =0 ; i < numaralar.length ;i++)
{
String a = numaralar[i].substring(0,1);
if(!a.equals("+")){ kisiismi = numaralar[i]; }
ContentResolver localContentResolver = getApplicationContext().getContentResolver();
Cursor contactLookupCursor =
localContentResolver.query(
Uri.withAppendedPath(PhoneLookup.CONTENT_FILTER_URI,
Uri.encode(numaralar[i])),
new String[] {PhoneLookup.DISPLAY_NAME, PhoneLookup._ID},
null,
null,
null);
try {
while(contactLookupCursor.moveToNext()){
String contactName = contactLookupCursor.getString(contactLookupCursor.getColumnIndexOrThrow(PhoneLookup.DISPLAY_NAME));
kisiismi = contactName;
}
}catch (Exception e) {
kisiismi = numaralar[i].toString();
}
finally {
//Toast.makeText(getApplicationContext(), ad + kisiismi + " " + count[ad], Toast.LENGTH_LONG).show();
myArr.add(kisiismi);
contactLookupCursor.close();
}
}
Есть ли способ облегчить этот процесс?
Ответы
Ответ 1
Так как это простой запрос SQLite, и к контакту Contact можно обращаться аналогичным образом, вы должны попытаться выполнить задание в SQL с помощью GROUPING через число, timestamp и, возможно, thrad_id, а затем сопоставить результаты с запросом на поставщик контактов (также через SQLite)
Документация содержит довольно хорошее описание всех доступных столбцов.
https://developer.android.com/reference/android/provider/ContactsContract.PhoneLookupColumns.html
Ответ 2
Теперь из KitKat у нас есть определенный Uri для этого: content://mms-sms/messages/byphone
. Но до этого мы можем придумать:
Set<Integer> conversationIds = new HashSet<Integer>();
String numbers = "+xxxxxxxxxx,+yyyyyyyyyy";
final String[] PROJECTION = { Sms._ID, Sms.THREAD_ID };
final String SELECTION = Sms.ADDRESS + " IN (" + numbers.replaceAll("[^,]+", "?") + ")";
final String[] selectionArgs = numbers.split(",");
Cursor cursor = context.getContentResolver().query(Sms.CONTENT_URI, PROJECTION, SELECTION, selectionArgs, null);
int threadColumn = cursor.getColumnIndexOrThrow(Sms.THREAD_ID);
while (cursor.moveToNext())
conversationIds.add(cursor.getInt(threadColumn));
cursor.close();
return conversationIds;
Нет простого способа сделать то же самое с MMS-сообщениями, потому что они не сохраняют свой адрес в базе данных, вам нужно запрашивать каждый отдельно. Если вам нужно сделать это многократно, жизнеспособным решением является кэширование отношений номера MMS-to-phone в собственной базе данных.
Затем вы можете использовать идентификаторы, накопленные в conversationIds
, для запроса отдельных разговоров. Обратите внимание, что если вы хотите объединить различные покрытия, принадлежащие одному и тому же контакту, вы можете повторно использовать один и тот же шаблон выбора запроса выше, передав все идентификаторы как IN (?,...,?)
сразу.