views:

2106

answers:

2

I currently register a content observer on the following URI "content://sms/" to listen out for incoming and outgoing messages being sent.

This seems to work ok and I have also tried deleting from the sms database but I can only delete an entire thread from the following URI "content://sms/conversations/"

Here is the code I use for that

String url = "content://sms/"; 
        Uri uri = Uri.parse(url); 
        getContentResolver().registerContentObserver(uri, true, new MyContentObserver(handler));                    

}

class MyContentObserver extends ContentObserver { 

    public MyContentObserver(Handler handler) { 

        super(handler); 

    }

@Override public boolean deliverSelfNotifications() { 
    return false; 
    }

@Override public void onChange(boolean arg0) { 
    super.onChange(arg0);

     Log.v("SMS", "Notification on SMS observer"); 

    Message msg = new Message(); 
    msg.obj = "xxxxxxxxxx";

    handler.sendMessage(msg);

    Uri uriSMSURI = Uri.parse("content://sms/");
    Cursor cur = getContentResolver().query(uriSMSURI, null, null,
                 null, null);
    cur.moveToNext();
    String protocol = cur.getString(cur.getColumnIndex("protocol"));
    if(protocol == null){
           Log.d("SMS", "SMS SEND"); 
           int threadId = cur.getInt(cur.getColumnIndex("thread_id"));

           Log.d("SMS", "SMS SEND ID = " + threadId); 
           Cursor c = getContentResolver().query(Uri.parse("content://sms/outbox/" + threadId), null, null,
                   null, null);
           c.moveToNext();
           int p = cur.getInt(cur.getColumnIndex("person"));
           Log.d("SMS", "SMS SEND person= " + p); 
           //getContentResolver().delete(Uri.parse("content://sms/conversations/" + threadId), null, null);

    }
    else{
        Log.d("SMS", "SMS RECIEVE");  
         int threadIdIn = cur.getInt(cur.getColumnIndex("thread_id"));

         getContentResolver().delete(Uri.parse("content://sms/conversations/" + threadIdIn), null, null);
    }

 }


} 

However I want to be able to get the recipricant and the message text from the SMS Content Provider, can anyone tell me how to do this?

And also how to delete one message instead of an entire thread?

+2  A: 

This was already discussed.

To read SMS from the Content provider check: - android-1-5-reading-sms-messages

Check this threads:

About your comment saying that you are deleting a whole thread instead of a single sms: Have you tried out this code?

Macarse
Thanks but those threads only deal with the deletion of an SMS which is only part of my question and not the main part, also they dont specifically deal with deleting a single message but instead do what I have already posted in my code above, that is they delete an entire conversation thread and not a single message within a thread from the Uri "content://sms/outbox/". As in my question my priority is to find out how to retrieve the message text and receiver from the SMS content provider
Donal Rafferty
@Donal: I just edited my answer.
Macarse
Thanks Macarse, some interesting reading and code snippets there
Donal Rafferty
I have been making some progress on this in 1.5 but I ran it on 1.6 and my content observer stops working, in 1.5 its set up for "content://sms/" but should it be something different for 1.6?
Donal Rafferty
not sure, but I guess you can check this out: http://developer.android.com/intl/fr/resources/articles/backward-compatibility.html
Macarse
+1  A: 

The address column contains the telephone number of the sms sender.

Use cursor.getString(cursor.getColumnIndex("address")) to pull the telephone number as a String. Pop a cursor on content://sms and sort it in date descending order to get the most recent message. You will have to wait for the new message to enter the table otherwise you will pull information from the wrong message. In an incomingSMS broadcastReceiver use a while loop, in a thread, polling for the cursor.getCount() to change. Then after the while loop cursor.moveToFirst will be the new message.

For example:

Cursor cur = getContentResolver().query(Uri.parseUri(content://sms), null, null, null, null);
int count = cur.getCount();
while (cur.getCount() == count)
{
     Thread.sleep(1000);
     cur = getContentResolver().query(Uri.parseUri(content://sms), null, null, null, null);
}

Then get the address of the sms sender:

cur = getContentResolver().query(Uri.parseUri(content://sms), null, null, null, "date DESC");

cur.MoveToFirst();
String telephoneNumber = cur.getString(cur.getColumnIndex("address");

This while loop will pause the thread until the new message arrives. You can also use a contentObserver, but this while loop is simple and does not require registration, unregistration, and a separate class.

Frankly I think its faster to pull the address and the body of the message directly from the pdu of the incoming intent. This way you dont have to wait for the message to enter the table to get the address and the body. The Android class SmsMessage has a variety of useful methods.

Noah Seidman