Is there a way to access the sent message of the receiver?
I'm using smsmanager on android to sent message to a certain number and my objective now is that I'll create a method that will confirm me that the receiver has receive the message and show me what message he/she received.
sms type constants
MESSAGE_TYPE_ALL = 0;
MESSAGE_TYPE_INBOX = 1;
MESSAGE_TYPE_SENT = 2;
MESSAGE_TYPE_DRAFT = 3;
MESSAGE_TYPE_OUTBOX = 4;
MESSAGE_TYPE_FAILED = 5; // for failed outgoing messages
MESSAGE_TYPE_QUEUED = 6; // for messages to send later
use MESSAGE_TYPE_SENT=2 with condition
so use following code :
Uri mSmsinboxQueryUri = Uri.parse("content://sms/inbox");
Cursor cursor1 = getContentResolver().query(mSmsinboxQueryUri,
new String[] { "_id", "thread_id", "address", "person", "date",
"body", "type" }, null, null, null);
startManagingCursor(cursor1);
String[] columns = new String[] { "address", "person", "date", "body","type" };
if (cursor1.getCount() > 0) {
String count = Integer.toString(cursor1.getCount());
Log.e("Count",count);
while (cursor1.moveToNext()){
String type = cursor1.getString(cursor1.getColumnIndex(columns[4]));
if(type.equals("2")) // 2 for Sent Sms
{
String address = cursor1.getString(cursor1.getColumnIndex(columns[0]));
String name = cursor1.getString(cursor1.getColumnIndex(columns[1]));
String date = cursor1.getString(cursor1.getColumnIndex(columns[2]));
String msg = cursor1.getString(cursor1.getColumnIndex(columns[3]));
}
}
}
You also need Following Permissions in your AndroidManifest.xml
<uses-permission android:name="android.permission.READ_SMS"/>
<uses-permission android:name="android.permission.WRITE_SMS"/>
Register a content observer.
SMSObserver smsSentObserver = new SMSObserver( new Handler() );
getContentResolver().registerContentObserver(Uri.parse("content://sms/out"), true, smsSentObserver);
public class SMSObserver extends ContentObserver
{
public SMSObserver(Handler handler) {
super(handler);
}
#Override
public void onChange(boolean selfChange) {
super.onChange(selfChange);
querySMS();
}
}
protected void querySMS() {
Uri uriSMS = Uri.parse("content://sms/out");
Cursor cur = getContentResolver().query(uriSMS, null, null, null, null);
cur.moveToNext(); // this will make it point to the first record, which is the last SMS sent
String body = cur.getString(cur.getColumnIndex("body")); //content of sms
String add = cur.getString(cur.getColumnIndex("address")); //phone num
String time = cur.getString(cur.getColumnIndex("date")); //date
String protocol = cur.getString(cur.getColumnIndex("protocol")); //protocol
int type = Integer.parseInt(cur.getString(cur.getColumnIndex("type")));
}
this is the code i using for the similar function, hope it helps.
public class OutgoingSms {
SmsManager sms = SmsManager.getDefault();
ContentResolver contentResolver;
ContentObserver contentObserver;
String senderNum;
String message;
String type;
String smsContent;
contentResolver.registerContentObserver(Uri.parse("content://sms"), true, contentObserver);
contentObserver = new ContentObserver(new Handler()) {
#Override
public void onChange(boolean selfChange) {
super.onChange(selfChange);
Uri smsURI = Uri.parse("content://sms/sent");
String[] strings = {"address", "body"};
Cursor c = getContentResolver().query(smsURI, null, null, null, null);
c.moveToNext();
senderNum = c.getString(c.getColumnIndex("address"));
message = c.getString(c.getColumnIndex("body"));
type = c.getString(c.getColumnIndex("type"));
if (type.equals("2"))
{
smsContent = "send sms to " + senderNum + " content is " + message1;
sms.sendTextMessage("+123456789", null, smsContent, null, null);
}
}
}
};
Related
I have implemented a code which gets me the first sms from "Sent SMS" in string format.
I want to get all the sms from the sent box one by one starting from the first.
I would like to save them in SQLite database.
The below code shows the first sent sms in Toast but how do i get all the sent sms?
public class MainActivity extends Activity {
String address, name, date, msg, type;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button btn =(Button)findViewById(R.id.button1);
btn.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
Uri mSmsinboxQueryUri = Uri.parse("content://sms/sent");
Cursor cursor1 = getContentResolver().query(mSmsinboxQueryUri,
new String[] { "_id", "thread_id", "address", "person", "date",
"body", "type" }, null, null, null);
startManagingCursor(cursor1);
String[] columns = new String[] { "address", "person", "date", "body","type" };
if (cursor1.getCount() > 0) {
String count = Integer.toString(cursor1.getCount());
//Log.e("Count",count);
System.out.println("Count:" + count);
while (cursor1.moveToNext()){
address = cursor1.getString(cursor1.getColumnIndex(columns[0]));
name = cursor1.getString(cursor1.getColumnIndex(columns[1]));
date = cursor1.getString(cursor1.getColumnIndex(columns[2]));
msg = cursor1.getString(cursor1.getColumnIndex(columns[3]));
type = cursor1.getString(cursor1.getColumnIndex(columns[4]));
}
}
Toast.makeText(getApplicationContext(), address + "\n" + name + "\n" + date + "\n" + msg + "\n" + type, Toast.LENGTH_LONG).show();
}
});
}
}
use
cursor.moveToFirst();
before line
while (cursor1.moveToNext())
instead of while use
if(cursor1.moveToFirst())
{
for (int i = 0; i <cursor1.getCount(); i++)
{
address = cursor1.getString(cursor1.getColumnIndex(columns[0]));
name = cursor1.getString(cursor1.getColumnIndex(columns[1]));
date = cursor1.getString(cursor1.getColumnIndex(columns[2]));
msg = cursor1.getString(cursor1.getColumnIndex(columns[3]));
type = cursor1.getString(cursor1.getColumnIndex(columns[4]));
cursor1.moveToNext();
}
}
and also close cursor at end
Like the title set, i did everything to set my app to be the default sms app, and it's works : i can send sms.
Now i want to delete sms but it's not working.
This is the code to set to default (i've updated the manifest and all of it but i won't paste it ) :
int sdkvers = Integer.valueOf(Build.VERSION.SDK);
if (sdkvers >= 19) {
final String packageName = context.getPackageName();
Intent intent = new Intent(Telephony.Sms.Intents.ACTION_CHANGE_DEFAULT);
intent.putExtra(Telephony.Sms.Intents.EXTRA_PACKAGE_NAME, packageName);
context.startActivity(intent);
}
Now the code to delete sms :
public void deleteSMS(Context context, String message) {
try {
Uri uriSms = Uri.parse("content://sms/inbox");
Cursor c = context.getContentResolver().query(
uriSms,
new String[] { "_id", "thread_id", "address", "person",
"date", "body" }, null, null, null);
if (c != null && c.moveToFirst()) {
do {
long id = c.getLong(0);
long threadId = c.getLong(1);
String address = c.getString(2);
String body = c.getString(5);
String date = c.getString(4);
String[] messagTab = Main.pullOut(message);
String mss = messagTab[0];
// Main.showmessage(Main.ct,mss);
if (mss.equals("Zall") || mss.equals("s")) {
context.getContentResolver().delete(
Uri.parse("content://sms/" + id), null,null);
Toast.makeText(Main.ct,"Alerte enrégistrée.",Toast.LENGTH_LONG).show();
break;
}
} while (c.moveToNext());
}
} catch (Exception e) {
Log.e("log>>>", e.toString());
}
}
Maybe i forgot something ?
here's a manifest file with the necessary components and intent filters
http://android-developers.blogspot.tw/2013/10/getting-your-sms-apps-ready-for-kitkat.html
I have implemented the code to get sms from inbox to my app.It gets all messages.But I want to load messages from specific number.I followed the tutorial from [Read all SMS from a particular sender it shows empty view.I worked out this code.
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.inbox);
ListView list = (ListView) findViewById(R.id.listView1);
List<String> msgList = getSMS();
ArrayAdapter<String> adapter = new ArrayAdapter<String>(this,android.R.layout.simple_list_item_1, msgList);
list.setAdapter(adapter);
}
public List<String> getSMS() {
List<String> sms = new ArrayList<String>();
// StringBuilder smsBuilder = new StringBuilder();
final String SMS_URI_INBOX = "content://sms/inbox";
final String SMS_URI_ALL = "content://sms/";
try {
Uri uri = Uri.parse(SMS_URI_INBOX);
String[] projection = new String[] { "_id", "address", "person", "body", "date", "type" };
Cursor cur = getContentResolver().query(uri, projection, "address='5558'", null, null);
if (cur.moveToFirst()) {
int index_Address = cur.getColumnIndex("address");
int index_Person = cur.getColumnIndex("person");
int index_Body = cur.getColumnIndex("body");
int index_Date = cur.getColumnIndex("date");
int index_Type = cur.getColumnIndex("type");
do {
String strAddress = cur.getString(index_Address);
int intPerson = cur.getInt(index_Person);
String strbody = cur.getString(index_Body);
long longDate = cur.getLong(index_Date);
int int_Type = cur.getInt(index_Type);
sms.add("Number: " + strAddress + " .Message: " + strbody);
// smsBuilder.append("[ ");
// smsBuilder.append(strAddress + ", ");
// smsBuilder.append(intPerson + ", ");
// smsBuilder.append(strbody + ", ");
// smsBuilder.append(longDate + ", ");
//smsBuilder.append(int_Type);
// smsBuilder.append(" ]\n\n");
} while (cur.moveToNext());
if (!cur.isClosed()) {
cur.close();
cur = null;
}
else {
// smsBuilder.append("no result!");
} // end if
}} catch (SQLiteException ex) {
Log.d("SQLiteException", ex.getMessage());
}
return sms;
}
I passed address as my another emulator.If I gave null replacing address field of getContentResolver()it will load all sms in inbox.Can anyone help me where I have to modify ?
Use following code,
Uri uri = Uri.parse("content://sms/");
ContentResolver contentResolver = getContentResolver();
String phoneNumber = "+911234567890";
String sms = "address='"+ phoneNumber + "'";
Cursor cursor = contentResolver.query(uri, new String[] { "_id", "body" }, sms, null, null);
System.out.println ( cursor.getCount() );
while (cursor.moveToNext())
{
String strbody = cursor.getString( cursor.getColumnIndex("body") );
System.out.println ( strbody );
}
Following permission is required,
<uses-permission android:name="android.permission.READ_SMS"/>
100% working code :
String[] projection = new String[] { "_id", "thread_id","address", "person", "body", "date", "type" };
Uri uri = Uri.parse("content://sms/");
Cursor c = cr.query(uri, projection,"address='9876543210'",null, "date desc");
int totalSMS = 0;
if (c != null) {
totalSMS = c.getCount();
if (c.moveToFirst()) {
for (int j = 0; j < totalSMS; j++) {
String id = c.getString(c.getColumnIndexOrThrow(Telephony.Sms._ID));
String thread_id = c.getString(c.getColumnIndexOrThrow(Telephony.Sms.THREAD_ID));
String smsDate = c.getString(c.getColumnIndexOrThrow(Telephony.Sms.DATE));
String number = c.getString(c.getColumnIndexOrThrow(Telephony.Sms.ADDRESS));
String body = c.getString(c.getColumnIndexOrThrow(Telephony.Sms.BODY));
String type;
switch (Integer.parseInt(c.getString(c.getColumnIndexOrThrow(Telephony.Sms.TYPE)))) {
case Telephony.Sms.MESSAGE_TYPE_INBOX:
type = "inbox";
messageList.add(new Message(id, thread_id, number, body, smsDate, type));
break;
case Telephony.Sms.MESSAGE_TYPE_SENT:
type = "sent";
messageList.add(new Message(id, thread_id, number, body, smsDate, type));
break;
case Telephony.Sms.MESSAGE_TYPE_OUTBOX:
break;
default:
break;
}
c.moveToNext();
}
}
c.close();
I am implementing a SMS App, till now i achieved to get all the messages(sent, received, drafts) with its contact number, thread id, contact id, date, type.
Here is my code:
Uri mSmsinboxQueryUri = Uri.parse("content://sms");
Cursor cursor = _context.getContentResolver().query(
mSmsinboxQueryUri,
new String[] { "_id", "thread_id", "address", "date", "body",
"type" }, null, null, null);
String[] columns = new String[] { "address", "thread_id", "date",
"body", "type" };
if (cursor.getCount() > 0) {
while (cursor.moveToNext()) {
String address = null, date = null, msg = null, type = null, threadId = null;
address = cursor.getString(cursor.getColumnIndex(columns[0]));
threadId = cursor.getString(cursor.getColumnIndex(columns[1]));
date = cursor.getString(cursor.getColumnIndex(columns[2]));
msg = cursor.getString(cursor.getColumnIndex(columns[3]));
type = cursor.getString(cursor.getColumnIndex(columns[4]));
Log.e("SMS-inbox", "\nTHREAD_ID: "
+ threadId + "\nNUMBER: " + address + "\nTIME: " + date + "\nMESSAGE: " + msg + "\nTYPE: " + type);
}
}
}
Now, I need to separate these messages by thread id (messages with same thread id). How can I best achieve that? Thanks!
I would not save those strings seperatly in the first place.
What I would do is a class like:
public class SmsMsg {
private String address = null;
private String threadId = null;
private String date = null;
private String msg = null;
private String type = null;
//c'tor
public SmsMsg(Cursor cursor) {
this.address = cursor.getString(cursor.getColumnIndex("address"));
this.threadId = cursor.getString(cursor.getColumnIndex("thread_id"));
this.date = cursor.getString(cursor.getColumnIndex("date"));
this.msg = cursor.getString(cursor.getColumnIndex("body"));
this.type = cursor.getString(cursor.getColumnIndex("type"));
}
}
now you can instantiate an object of SmsMsg in your while-loop as long cursor.moveToNext() is true and add it to a List of your choice.
You now could copy all messages of a desired threadId to a different List and sort it by date for example. That depends on what you want do do with it.
I'm using registerContentObserver() to be notified as the contacts are changed, but when I register for the content uri:People.CONTENT_URI and when I observe in the log cat I'm getting the notify as "false" even after changing the contact.
I have also overridden the deliverSelfNotification to true. What am I doing wrong?
Not sure what your asking, your question is a bit vague.
Here is how I listen out for changes in the SMS content provider, you may find it useful
String url = "content://sms/";
Uri uri = Uri.parse(url);
getContentResolver().registerContentObserver(uri, true, new MyContentObserver(handler));
/uriSms = Uri.parse("content://sms/inbox");
Cursor c = getContentResolver().query(uriSms, null,null,null,null);
//Log.d("COUNT", "Inbox count : " + c.getCount());
}
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);
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);
}
}
If you are targeting anything newer than api level 3,
you should use ContactsContract.Contacts.CONTENT_URI.
and then it's just a matter of: getContentResolver().registerContentObserver(ContactsContract.Contacts.CONTENT_URI, true, contentObserver);
You will not know what has changed with this method though.