I am wondering how to read last five SMS received from a particular mobile number on a particular date.
I know how to read all SMS from a particular sender, and how to read the last SMS, but I am unable to fetch and read the last few SMS. I tried to read them by using
"date DESC LIMIT 5"
My code is like below
Uri mSmsinboxQueryUri = Uri.parse("content://sms/inbox");
String[] projection = {"address", "body"};
Cursor cursor1 = MainActivity.this.getContentResolver().query(mSmsinboxQueryUri,
null,
"address = ?",
new String[]{phoneNumber},
"date DESC LIMIT 5");
if (cursor1 != null && cursor1.moveToFirst()) {
body = cursor1.getString(cursor1.getColumnIndex("body"));
totalBody = totalBody + body;
Log.d("Registration", totalBody);
}
But every time it's showing only the last message.
You're only seeing one message because your code is only handling the first record in the returned Cursor. You need to loop over the Cursor to handle the rest. For example:
if (cursor != null && cursor.moveToFirst()) {
do {
body = cursor1.getString(cursor1.getColumnIndex("body"));
totalBody = totalBody + body;
Log.d("Registration", totalBody);
} while (cursor.moveToNext());
}
Also, if you want to restrict the query to one day, you can use a Calendar to figure the starting and ending times for that day in milliseconds - as that is how dates are stored in the SMS table - and add the appropriate comparison to the where clause. For example:
private static final int DAY_MILLISECONDS = 24 * 60 * 60 * 1000;
private static final Uri inboxUri = Uri.parse("content://sms/inbox");
// Months are zero-based; i.e., JANUARY == 0
// Phone number must be exact in this example
private void listMessages(String phoneNumber, int year, int month, int day) {
Calendar cal = Calendar.getInstance();
cal.set(Calendar.YEAR, year);
cal.set(Calendar.MONTH, month);
cal.set(Calendar.DATE, day);
cal.set(Calendar.HOUR_OF_DAY, 0);
cal.set(Calendar.MINUTE, 0);
cal.set(Calendar.SECOND, 0);
cal.set(Calendar.MILLISECOND, 0);
String[] projection = {"address", "body"};
String whereAddress = "address = ?";
String whereDate = "date BETWEEN " + cal.getTimeInMillis() +
" AND " + (cal.getTimeInMillis() + DAY_MILLISECONDS);
String where = DatabaseUtils.concatenateWhere(whereAddress, whereDate);
Cursor cursor = null;
try {
cursor = getContentResolver().query(inboxUri,
projection,
where,
new String[]{phoneNumber},
"date DESC LIMIT 5");
if (cursor != null && cursor.moveToFirst()) {
do {
Log.d("Message", cursor.getString(cursor.getColumnIndex("body")));
} while (cursor.moveToNext());
}
}
catch (Exception e) {
e.printStackTrace();
}
finally {
if (cursor != null) {
cursor.close();
}
}
}
Related
I have created a service that reads user messages after every 15 minutes , code is working fine for all messages but the problem is that i want to read messages sent for last 15 minutes not all messages , here is my code for service
public class MessageReadingService extends Service {
ScheduledExecutorService scheduler = Executors.newSingleThreadScheduledExecutor();
int happy,sad,lonely,joyful=0;
Cursor cur;
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
scheduler.scheduleWithFixedDelay(new Runnable() {
#Override
public void run() {
Uri uriSMSURI = Uri.parse("content://sms/sent");
cur = getContentResolver().query(uriSMSURI, new String[]{"_id", "thread_id", "address", "person", "date", "body"}, null, null, "DATE desc");
if (cur.getCount() > 0) {
while (cur.moveToNext()) {
String smsBody = cur.getString(5);
String body=smsBody.toString().toLowerCase();
if (body.contains("happy") || body.contains("yay") || body.contains("I am well") || body.contains("excited")) {
happy++;
//Toast.makeText(getApplicationContext(), "found"+s, Toast.LENGTH_SHORT).show();
}
if (body.contains("sad") || body.contains("not well") || body.contains("crying")|| body.contains("ill") || body.contains("leave me alone") || body.contains("i hate people")){
sad++;
}
if (body.contains("alone") ||body.contains("lonely") || body.contains("heart broken") || body.contains("Extremely sad")){
lonely++;
}
if (body.contains("joyful") || body.contains("exited") || body.contains("")){
joyful++;
}
}
}
}
}, 60*15, 60*15, SECONDS);
return super.onStartCommand(intent, flags, startId);
}
Create a calendar object and set the condition for where clause
private static final int FIFTEEN_MINUTES= 15 * 60 * 1000;
Calendar cal = Calendar.getInstance();
cal.set(Calendar.YEAR, year);
cal.set(Calendar.MONTH, month);
cal.set(Calendar.DATE, day);
cal.set(Calendar.HOUR_OF_DAY, 0);
cal.set(Calendar.MINUTE, 0);
cal.set(Calendar.SECOND, 0);
cal.set(Calendar.MILLISECOND, 0);
String[] projection = {"address", "body"};
String whereAddress = "address = ?";
String whereDate = "date BETWEEN " + cal.getTimeInMillis() +
" AND " + (cal.getTimeInMillis() + FIFTEEN_MINUTES);
String where = DatabaseUtils.concatenateWhere(whereAddress, whereDate);
and then use the query like this
cursor = getContentResolver().query(inboxUri,
projection,
where,
new String[]{phoneNumber},
"date DESC");
This gets the latest messages of the last 15 minutes.
mCursor = getContentResolver().query(
UserDictionary.Words.CONTENT_URI, // The content URI of the words table
mProjection, // The columns to return for each row
mSelectionClause // Selection criteria
mSelectionArgs, // Selection criteria
mSortOrder);
You set select criteria to NULL;
Replace mSelectionClause with a WHERE clause: WHERE col = value
"date>=" + dateStart.getTime();
I am wondering how to read last five SMS received from a particular mobile number on a particular date.
I know how to read all SMS from a particular sender, and how to read the last SMS, but I am unable to fetch and read the last few SMS. I tried to read them by using
"date DESC LIMIT 5"
My code is like below
Uri mSmsinboxQueryUri = Uri.parse("content://sms/inbox");
String[] projection = {"address", "body"};
Cursor cursor1 = MainActivity.this.getContentResolver().query(mSmsinboxQueryUri,
null,
"address = ?",
new String[]{phoneNumber},
"date DESC LIMIT 5");
if (cursor1 != null && cursor1.moveToFirst()) {
body = cursor1.getString(cursor1.getColumnIndex("body"));
totalBody = totalBody + body;
Log.d("Registration", totalBody);
}
But every time it's showing only the last message.
You're only seeing one message because your code is only handling the first record in the returned Cursor. You need to loop over the Cursor to handle the rest. For example:
if (cursor != null && cursor.moveToFirst()) {
do {
body = cursor1.getString(cursor1.getColumnIndex("body"));
totalBody = totalBody + body;
Log.d("Registration", totalBody);
} while (cursor.moveToNext());
}
Also, if you want to restrict the query to one day, you can use a Calendar to figure the starting and ending times for that day in milliseconds - as that is how dates are stored in the SMS table - and add the appropriate comparison to the where clause. For example:
private static final int DAY_MILLISECONDS = 24 * 60 * 60 * 1000;
private static final Uri inboxUri = Uri.parse("content://sms/inbox");
// Months are zero-based; i.e., JANUARY == 0
// Phone number must be exact in this example
private void listMessages(String phoneNumber, int year, int month, int day) {
Calendar cal = Calendar.getInstance();
cal.set(Calendar.YEAR, year);
cal.set(Calendar.MONTH, month);
cal.set(Calendar.DATE, day);
cal.set(Calendar.HOUR_OF_DAY, 0);
cal.set(Calendar.MINUTE, 0);
cal.set(Calendar.SECOND, 0);
cal.set(Calendar.MILLISECOND, 0);
String[] projection = {"address", "body"};
String whereAddress = "address = ?";
String whereDate = "date BETWEEN " + cal.getTimeInMillis() +
" AND " + (cal.getTimeInMillis() + DAY_MILLISECONDS);
String where = DatabaseUtils.concatenateWhere(whereAddress, whereDate);
Cursor cursor = null;
try {
cursor = getContentResolver().query(inboxUri,
projection,
where,
new String[]{phoneNumber},
"date DESC LIMIT 5");
if (cursor != null && cursor.moveToFirst()) {
do {
Log.d("Message", cursor.getString(cursor.getColumnIndex("body")));
} while (cursor.moveToNext());
}
}
catch (Exception e) {
e.printStackTrace();
}
finally {
if (cursor != null) {
cursor.close();
}
}
}
I am trying to read SMS stored in sim card . That is why I have written the following function .
void read_sms()
{
Cursor cursor = getContentResolver().query(Uri.parse("content://sms/icc"), null, null, null, null);
int indexBody = cursor.getColumnIndex("body");
int indexAddress = cursor.getColumnIndex("address");
if (indexBody < 0 || !cursor.moveToFirst())
return;
String fromNumber,smsMessageId;
try{
do {
SMSItem smsItem = new SMSItem();
String sms = cursor.getString(indexBody);
String str = "SMS From: " + cursor.getString(indexAddress)
+ "\n" + sms + " \n";
fromNumber = cursor.getString(indexAddress);
// arrayAdapter.add(str);
smsItem.sms = sms;
smsItem.status = false;
long millis = cursor.getLong(cursor
.getColumnIndexOrThrow("date"));
Date date = new Date(millis);
Calendar c = Calendar.getInstance();
// set the calendar to start of today
c.set(Calendar.HOUR_OF_DAY, 0);
c.set(Calendar.MINUTE, 0);
c.set(Calendar.SECOND, 0);
c.set(Calendar.MILLISECOND, 0);
// and get that as a Date
Date today = c.getTime();
String smsDate;
if (date.before(today)) {
smsDate = (String) DateFormat.format(" MMMM dd ", new Date(
millis));
} else {
smsDate = (String) DateFormat.format(" h:mm ",
new Date(millis));
}
smsItem.time = smsDate;
smsMessageId = cursor.getString(cursor.getColumnIndex("_id"));
smsItem.ID = smsMessageId;
// Toast.makeText(this, "The id is "+smsMessageId,
// Toast.LENGTH_LONG).show();
smsBody.add(smsItem);
Toast.makeText(this, " "+smsItem.sms, Toast.LENGTH_LONG).show();
} while (cursor.moveToNext());
}
catch(Exception e)
{
Toast.makeText(this, "Message: "+e.getMessage(), Toast.LENGTH_LONG).show();
}
cursor.close();
}
But I am getting null pointer exception . Why am I getting null pointer exception ? How can I solve this ?
I tried putting your code in a test app and also got NPE (Null Pointer Exception). The trace tells me that the following line has a problem and returning NPE.
Cursor cursor = getContentResolver().query(Uri.parse("content://sms/icc"), null, null, null, null);
When I changed replaced line with following, things started working fine.
Cursor cursor = managedQuery(Uri.parse("content://sms"), null, null, null, null);
I am reading unread sms from a particular number by the following code .
public void getUnreadMessage() {
Cursor smsInboxCursor1 = getContentResolver().query(
Uri.parse("content://sms/inbox"), new String[] {},
"read = 0 and address='" + pre_address + "'", null, null);
int indexBody = smsInboxCursor1.getColumnIndex("body");
int indexAddress = smsInboxCursor1.getColumnIndex("address");
if (indexBody < 0 || !smsInboxCursor1.moveToFirst())
return;
// arrayAdapter.clear();
do {
String str = "SMS From: " + smsInboxCursor1.getString(indexAddress)
+ "\n" + smsInboxCursor1.getString(indexBody) + " \n";
fromNumber = smsInboxCursor1.getString(indexAddress);
smsBody.add(smsInboxCursor1.getString(indexBody));
// arrayAdapter.add(str);
status.add(false);
} while (smsInboxCursor1.moveToNext());
}
Now I want to get the time of receiving sms from this particular number . How can I do that ?
There is a column named DATE that contains the date the message was received. You can get directly like the other fields you already retrieve:
int indexData = smsInboxCursor1.getColumnIndex("data");
...
long dateReceived = smsInboxCursor1.getLong(indexData);
Since it's a timestamp you need to convert in a human readable string. You can do it with this code:
private String getDate(long time) {
Calendar cal = Calendar.getInstance(Locale.ENGLISH);
cal.setTimeInMillis(time);
String date = DateFormat.format("dd-MM-yyyy HH:mm:ss", cal).toString();
return date;
}
So when I query the CalendarProvider for a list of events for my personal calendar, I'm getting some really strange start and end times. For example I see a result in the query that is 1970-01-13, but in my Google Calendar app it appears properly as 2015-02-01. All the events I got as a result have strange times like this.
My query is below.
String[] mProjection = new String[]{
Events.CALENDAR_ID,
Events.ORGANIZER,
Events.TITLE,
Events.DTSTART,
Events.DTEND,
Events._ID
};
ContentResolver cr = getActivity().getContentResolver();
Uri uri = Events.CONTENT_URI;
String selection = Events.CALENDAR_ID + " = ?";
String[] selectionArgs = new String[] {"2"};
Cursor cur = cr.query(uri, mProjection, selection, selectionArgs, null);
Log.i(TAG, "events " + cur.getCount());
TextView textView = (TextView) rootView.findViewById(R.id.dummy_text);
while (cur.moveToNext()) {
int calID = cur.getInt(0);
String organizer = cur.getString(1);
String title = cur.getString(2);
int start = cur.getInt(3);
int end = cur.getInt(4);
int event_id = cur.getInt(5);
Calendar startCal = Calendar.getInstance();
startCal.setTimeInMillis(start);
Calendar endCal = Calendar.getInstance();
endCal.setTimeInMillis(end);
Here's my code for converting the times to be readable.
public static String getHumanDate(int year, int month, int dayOfMonth) {
String monthZero = "";
String dayOfMonthZero = "";
if ((month + 1) < 10)
monthZero = "0";
if (dayOfMonth < 10)
dayOfMonthZero = "0";
return year + "-" + monthZero + (month + 1) + "-" + dayOfMonthZero + dayOfMonth;
}
Figured it out. Should have used
long start = cur.getLong(3);
long end = cur.getLong(4);
Rather than int.