Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Android getting sms conversation with name or address

Tags:

android

sms

I'm developing an SMS program and I want to get conversations.
I wrote the code below and it works fine, but I wonder if it could be more efficient

This is for geting conversation threads

       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 getting addresses according to conversation thread

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

and finally checking the adresses (if in contact list) and adding to a list

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

    }    

Are there any way to make this process easier?

like image 257
Sercan Aktan Avatar asked Oct 06 '12 14:10

Sercan Aktan


2 Answers

Since it is a simple SQLite query and the Contact provider can be accessed in a similar way, you should try to get the job done in SQL by GROUPING via number, timestamp and maybe thrad_id and then matching the results to a query to the contact provider (also via SQLite)

The documentation holds a pretty good description of all available columns. https://developer.android.com/reference/android/provider/ContactsContract.PhoneLookupColumns.html

like image 50
DooMMasteR Avatar answered Oct 07 '22 02:10

DooMMasteR


From KitKat onwards, we have a specific Uri for this: content://mms-sms/messages/byphone. But before that, this is what we can come up with:

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;

There is no easy way to do the same with MMS messages because they don't keep their address in the database, you have to query each and every one separately. If you need to do it repeatedly, a viable solution is to cache MMS-to-phone number relations in a database of your own.

You can then use the identifiers accumulated in conversationIds to query the individual conversations. Note that if you want to merge different coversations belonging to the same contact, you can reuse the same query selection pattern above with passing in all ids as IN (?,...,?) at once.

like image 36
Gábor Avatar answered Oct 07 '22 02:10

Gábor