I am working on an ANdroid application.In my app I have to list all the conversations and i did that part.Each conversation is containing all sms to that number. So i have to differtiate inbox and sentsms from all sms.I know about the following api's can use to find inbox and sent.
content://sms/inbox
content://sms/sent
But i don't want to use this.I listed all sms by using the api
content://sms/
I tested with the columnindex's type,address but it always gives the same result for inbox and outbox.And my sample code is
Uri SMS_INBOX = Uri.parse("content://sms");
c = getContentResolver().query(SMS_INBOX, null, "thread_id" + " = "
+ "3", null,
"date" + " ASC");
if(c.moveToFirst()){
count.add(c.getCount());
for(int j=0;j<c.getCount();j++){
System.out.println(c.getString(c.getColumnIndexOrThrow("body")).toString());
System.out.println("new person=="+c.getColumnIndex("person")+"type=="+c.getColumnIndexOrThrow("type"));
c.moveToNext();
}
}
c.close();
Please help me.
You can use ContentObserver here to track sent and received message,
Override onChange() method of ContentObserver and get the sms type and work accordingly. Psuedo code can be as below.
Cursor cursor = mContext.getContentResolver().query(Uri
.parse("content://sms"), null, null, null, null);
String type = cursor.getColumnIndex("type");
if(cursor.getString(type).equalsIgnoreCase("1")){
// sms received
}
else if(cursor.getString(type).equalsIgnoreCase("2")){
//sms sent
}
Registering ContentObserver for SMS,
ContentResolver observer = this.getContentResolver();
observer.registerContentObserver(Uri.parse("content://sms"),
true, new MySMSObserver(new Handler(),this));
Where MySMSObserver will be your class extending ContentObserver with Constructor having argument as Handler and Context,
public MySMSObserver(Handler handler, Context context) {
super(handler);
this.context = context;
}
Related
this is my sample code for sending message i want to use not show this message in sent item.
String strPhone = "XXXXXXXXXXX";
String strMessage = "Lorem\nIpsum";
SmsManager sms = SmsManager.getDefault();
sms.sendTextMessage(strPhone, null, strMessage, null, null);
Toast.makeText(this, "Sent.", Toast.LENGTH_SHORT).show();
i want to delete this sended message from sent items or now show in sent item.
in all version.
please help me to solve out.
Query your conversations after sending the message. Then fetch that particular message by comparing the message contents using any unique keyword in your sent message.I have tried this code in my phone running Marshmallow.
Uri uriSMS = Uri.parse("content://sms/conversations");
Cursor cur = getContentResolver().query(uriSMS, null, null, null, null);
if(cur != null && cur.moveToNext()) {
do {
String smsContent = cur.getString(2);
if(smsContent.contains("your sms keyword")) {
String pid = cur.getString(0); // Get id;
String uri = "content://sms/" + pid;
getContentResolver().delete(Uri.parse(uri), null, null);
}
} while (cur.moveToNext());
}
Sorry if i did not come up with a suitable title.
I want to know that is it possible to mark SMS as read in the default SMS Application through my Application?
i.e. i am developing my own application in which i am storing sms that are not from the contact list but the problem is that when ever sms received it received on my app and also on the default sms app so i want that when ever sms received then i can mark the sms as read(of the default SMS App) so that there is no need for go to default sms app and mark SMS as read.
Can i do that from my Application?
try this code
private void markMessageASRead(Context context, String numb, String body) {
Uri uri = Uri.parse("content://sms/inbox");
Cursor cursor = context.getContentResolver().query(uri, null, null, null, null);
try{
while (cursor.moveToNext()) {
if ((cursor.getString(cursor.getColumnIndex("address")).equals(number)) && (cursor.getInt(cursor.getColumnIndex("read")) == 0)) {
if (cursor.getString(cursor.getColumnIndex("body")).startsWith(body)) {
String SmsMessageId = cursor.getString(cursor.getColumnIndex("_id"));
ContentValues values = new ContentValues();
values.put("read", true);
context.getContentResolver().update(Uri.parse("content://sms/inbox"), values, "_id=" + SmsMessageId, null);
return;
}
}
}
}catch(Exception e)
{
Log.e("Mark Read", "Error in Read: "+e.toString());
}
}
I am trying to create app, that will get the text from SMS, and use it in textview. So something like this, message is recived, i check if it is message I want, then i extract text, save it to string, and then show this string in textview. Any suggestions from where should i start, any examples plese ??
You can start here for handling received SMS.
First I would listen for SMS incoming, and on incoming SMS show a notification. Then if the user opens your app, update your display using this to get the data you want:
Uri allMessage = Uri.parse("content://sms/inbox");
ContentResolver cr = getContentResolver();
Cursor c = cr.query(allMessage, null, null, null, null);
//shows one message
c.moveToNext();
//uncomment to cycle thru ALL messages... This will take AWHILE
//while (c.moveToNext()) {
for(int i = 0; i != c.getColumnCount(); i++){
String columnName = c.getColumnName(i);
String columnValue = c.getString(i);
Log.v(TAG, "Col: " + columnName);
Log.v(TAG, "Val: " + columnValue);
}
//}
Play around with it a little. It Should have all of the data you need (distinguish SMSs by timestamp)
I am writing my own SMS application that will display a toast of my message once it arrive. Now is it possible to delete the message after the display of the toast, so that it will not go into the native SMS application?
Thanks In Advance,
Perumal
Use BroadcastReceiver to trap the incoming SMS.
Read the message body and store it somewhere or show it in the Toast you mentioned.
use the following code to delete SMS's in your inbox. It will be deleted immidiately .
ContentResolver cr = _context.getContentResolver();
Uri inbox = Uri.parse( "content://sms/inbox" );
Cursor cursor = cr.query(
inbox,
new String[] { "_id", "thread_id", "body" },
null,
null,
null);do {
String body = cursor.getString( 2 );
long thread_id = cursor.getLong( 1 );
Uri thread = Uri.parse( "content://sms/conversations/" + thread_id );
cr.delete( thread, null, null );
count++;
} while ( cursor.moveToNext() );
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?
This was already discussed.
To read SMS from the Content provider check:
- android-1-5-reading-sms-messages
Check this threads:
delete-sms-in-android-1-5
how-to-delete-sms-from-inbox-in-android-programmatically
can-we-delete-an-sms-in-android-before-it-reaches-the-inbox
About your comment saying that you are deleting a whole thread instead of a single sms:
Have you tried out this code?
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.