Searching of messages from inbox is not successful - android

I want to get the information about the messages from the inbox on the basis of a particular number.I am using following code for achieving the goal but it is not working in the expected way:
public void SendTheSmsToTheFolder(String NameOfContact,String Number,String FolderAddress,long TimeLimit)
{
m_NameOfContact = NameOfContact;
String SMS_URI_INBOX = "content://sms/inbox";
Uri l_uri = Uri.parse(SMS_URI_INBOX);
Cursor l_SendTheSmsToTheFolderCursor = getContentResolver().query(l_uri, null, "address=?",new String[]{Number.trim()},null);
if (l_SendTheSmsToTheFolderCursor.moveToFirst())
{
int l_index_Address = l_SendTheSmsToTheFolderCursor.getColumnIndex("address");
int l_index_Person = l_SendTheSmsToTheFolderCursor.getColumnIndex("person");
int l_index_Body = l_SendTheSmsToTheFolderCursor.getColumnIndex("body");
int l_index_Date = l_SendTheSmsToTheFolderCursor.getColumnIndex("date");
do
{
String l_strAddress = l_SendTheSmsToTheFolderCursor.getString(l_index_Address);
String l_strbody = l_SendTheSmsToTheFolderCursor.getString(l_index_Body);
long l_longDate = l_SendTheSmsToTheFolderCursor.getLong(l_index_Date);
Log.v("Message: ","Body of the message is "+l_strbody);
} while (l_SendTheSmsToTheFolderCursor.moveToNext());
}
}
I am quite sure that the message having that particular phone number is present in the box and i have cross checked this fact.But the here,i cursor count is always showing 0.I don't know what is the problem.I have searched a lot but am not able to figure it out.Please help me.Thanks in advance.

If you want to search messages from a particular number, you can try this code.
Uri uri = Uri.parse("content://sms/inbox");
ContentResolver contentResolver = context.getContentResolver();
String where = "address="+ phNum; //here you can use that particular number
Cursor cursor = contentResolver.query(uri, new String[] { "_id", "thread_id"}, where, null,null);
It has worked for me. let me know if it solved your issue.

Related

DocumentsContract's buildChildDocumentsUriUsingTree(uri, DocumentsContract.getTreeDocumentId(uri)); returns parent Uri tree

I am trying to use DocumentsContract to traverse a directory recursively using the following method.
void traverseDirectoryEntries(Uri rootUri) {
ContentResolver contentResolver = activityMain.getContentResolver();
Uri childrenUri = DocumentsContract.buildChildDocumentsUriUsingTree(
rootUri, DocumentsContract.getTreeDocumentId(rootUri));
List<Uri> dirNodes = new LinkedList<>();
dirNodes.add(childrenUri);
while (!dirNodes.isEmpty()) {
childrenUri = dirNodes.remove(0); // get the item from top
try (Cursor cursor = contentResolver.query(childrenUri, new String[]{
DocumentsContract.Document.COLUMN_DOCUMENT_ID,
DocumentsContract.Document.COLUMN_DISPLAY_NAME,
DocumentsContract.Document.COLUMN_MIME_TYPE},
null, null, null)) {
if (cursor != null) {
while (cursor.moveToNext()) {
final String docId = cursor.getString(0);
final String name = cursor.getString(1);
final String mime = cursor.getString(2);
if (isDirectory(mime)) {
final Uri newNode = DocumentsContract.buildChildDocumentsUriUsingTree(
rootUri, docId);
traverseDirectoryEntries(newNode);
}
}
}
}
}
}
// Util method to check if the mime type is a directory
private static boolean isDirectory(String mimeType) {
return DocumentsContract.Document.MIME_TYPE_DIR.equals(mimeType);
}
Unfortunately, this does not work. It goes through the same root directory over and over despite the directory passed in being a child of the root. The line final Uri newNode = DocumentsContract.buildChildDocumentsUriUsingTree(rootUri, docId); returns a Uri with the child directory attached at the end. That works fine. The problem is the follwing line: Uri childrenUri = DocumentsContract.buildChildDocumentsUriUsingTree(rootUri, DocumentsContract.getTreeDocumentId(rootUri)); where rootUri is the newNode. I get the same childrenUri; the one I got from rootUri. Is this a bug? Did I make a mistake? Is the docId wrong? I tried getDocumentId(rootUri), but that throws an error because the id it returns is not a tree. It is almost like getTreeDocumentId(rootUri) is returning what getRootId(rootUri) should be returning. Is there a way to fix this?
The rootUri was obtained via ACTION_OPEN_DOCUMENT_TREE. I am running this on Android Pie. I left some code out where I am building a tree structure from the data.
You are abusing this well known void traverseDirectoryEntries(Uri rootUri) function.
You think it is recursive but it is not.
Remove the recursive call and instead add 'newNode' to the list.
// traverseDirectoryEntries(newNode);
dirNodes.add(newNode);
Then you make use of the list.
Then original code is restored.
Who changed it without telling so?
Of course you can adapt this function to make it recursiv.
Nice exercise ;-).

Restoring backed up messages, conversations times are incorrect

I am developing an android app which backs up and restores the messages/conversations from device. It backup the messages, export file in the form of xml, and then later restore it. The only problem I am facing is the date/times of conversations. It is changed to current time at the time of restoration, but when I open any conversation, there time is correct. Have a look at photos.
Before backup:
After backup:
Code I am using for backup:
Uri uri = Uri.parse("content://sms/inbox");
//Uri uri = Uri.parse("content://mms-sms/conversations/");
ContentResolver contentResolver = getContentResolver();
final String[] projection = new String[]{"*"};
Cursor SMSL = contentResolver.query(Telephony.Sms.Inbox.CONTENT_URI, projection, null, null, null);
int msgscount = SMSL.getCount();
if (msgscount>0) {
msgs = new String[SMSL.getCount()][5];
int i = 0;
while (SMSL.moveToNext()) {
address = SMSL.getString(SMSL.getColumnIndex("address"));
body = SMSL.getString(SMSL.getColumnIndex("body"));
read = SMSL.getString(SMSL.getColumnIndex("read"));
date = SMSL.getString(SMSL.getColumnIndex("date"));
type = SMSL.getString(SMSL.getColumnIndex("type"));
msgs[i][0] = address;
msgs[i][1] = body;
msgs[i][2] = date;
msgs[i][3] = read;
msgs[i][4] = type;
Log.i("Date: ", String.valueOf(SMSL.getLong(SMSL.getColumnIndex("date"))));
i++;
}
SMSL.close();
}else{
msgs = new String[0][0];
Toast.makeText(getApplicationContext(),"No messages found!",Toast.LENGTH_LONG).show();
}
Code for restoring:
ContentResolver contentResolver = getContentResolver();
Uri uri = Uri.parse("content://sms/inbox");
//Uri uri = Uri.parse("content://mms-sms/conversations/");
ContentValues values = new ContentValues();
for (int i = 0; i < readMsgsFromFile.length; i++) {
values.put("address",readMsgsFromFile[i][0]);
values.put("body",readMsgsFromFile[i][1]);
values.put("date",readMsgsFromFile[i][2]);
values.put("read",readMsgsFromFile[i][3]);
values.put("type",readMsgsFromFile[i][4]);
contentResolver.insert(Telephony.Sms.Inbox.CONTENT_URI, values);
Log.i("Restoring: ",readMsgsFromFile[i][2]);
}
Thanks Mike M. I did find a solution and you are right, the conversation table is updated whenever a new message is received or sent by a user and the time of conversation is same as that message's (whether received or sent) time. But in case of writing messages through contentresolver query it does not work and the conversation time is current time at the time of writing. So what I did is add a temporary message in all of the conversations, right after messages are restored. And after that delete all the temporary messages, this will update the conversations time to last message time.
HashSet hs = new HashSet();
hs.addAll(list);
//list is the ArrayList<String> which contains the addressess of all the messages and
//through hashset we remove all the duplicates to get only the addressess once and hence we know the number of conversations and their addressess.
list.clear();
list.addAll(hs);
//Add some dummy message to each conversation
ContentValues values2 = new ContentValues();
for (int i = 0; i < list.size(); i++) {
values2.put("address",list.get(i));
values2.put("date_sent",readMsgsFromFile[0][1]);
values2.put("date",readMsgsFromFile[0][2]);
values2.put("type",readMsgsFromFile[0][3]);
values2.put("body","temp"); //this should be more unique
values2.put("read",readMsgsFromFile[0][5]);
values2.put("service_center","01010101");
contentResolver.insert(Telephony.Sms.CONTENT_URI, values2);
}
//Now deleting that message with body 'temp' from each conversation
Cursor c = contentResolver.query(Telephony.Sms.CONTENT_URI,null,null,null,null);
while (c.moveToNext()){
String body = c.getString(c.getColumnIndex("body"));
String mid = c.getString(0);
if (body.equals("temp")){
Log.i("Deleting ",mid);
getContentResolver().delete(Uri.parse(Telephony.Sms.CONTENT_URI+"/"+mid),null,null);
}
}
c.close();
This word 'temp' could be and should be more unique so that it is not mixed with actual message.

How to get sms list depending on various devices

I tried to get sms list and below code works well in some devices but not working in other devices. Details tested with four devices using below code.
LG optimus one[android 2.2] - works well. SS galaxy s3[android4.0.4] - works well. SS galaxy s2[android
2.3.5] - not working. SS galaxy s2[android 4.0.4] - not working.
It seems that result depends on devices not android version because two devices with same android version[4.0.4] show differently. Symptom in the devices not working is that c.getCount() = 0 even if they have many sms. The query returns nothing. Why these are? How can I get sms list in galaxy s2 as well?
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
String smsMsgBody = null;
String smsMsgAddress = null;
String smsMsgDirection = null;
Uri uri = Uri.parse("content://sms");
// Uri uri = Uri.parse("content://sms/inbox");
// Uri uri = Uri.parse("content://sms/conversations/");
Cursor c= getContentResolver().query(uri, null, null,null,null);
// startManagingCursor(c);
if (c.getCount() > 0)
{
String count = Integer.toString(c.getCount());
while (c.moveToNext())
{
smsMsgBody = c.getString(c.getColumnIndex("body"));
smsMsgAddress = c.getString(c.getColumnIndex("address"));
smsMsgDirection = c.getString(c.getColumnIndex("type"));
// Do things using above sms data
}
}
c.close();
}
The content://sms/ is not a supported content provider. It is a hidden method, and may not be available in all devices. In Android 4.4 KitKat devices, you can use the code in this answer to do it:
public List<String> getAllSms() {
List<String> lstSms = new ArrayList<String>();
ContentResolver cr = mActivity.getContentResolver();
Cursor c = cr.query(Telephony.Sms.Inbox.CONTENT_URI, // Official CONTENT_URI from docs
new String[] { Telephony.Sms.Inbox.BODY }, // Select body text
null,
null,
Telephony.Sms.Inbox.DEFAULT_SORT_ORDER // Default sort order);
int totalSMS = c.getCount();
if (c.moveToFirst()) {
for (int i = 0; i < totalSMS; i++) {
lstSms.add(c.getString(0));
c.moveToNext();
}
}
else {
throw new RuntimeException("You have no SMS in Inbox");
}
c.close();
return lstSms;
}
I don't believe that there is a documented method that will work across all devices right now.

Reading mms details programmatically and display in listview

i need to get all the MMS Data detalis like mms_image, address,date and type.
i am using following logic. In this i am using two cursors, one for images and other for remaining fields. but the size of two cursors are different. so, i am unable to match both image and other fields.
//for date,address,type
Cursor curPdu = getContentResolver ().query(Uri.parse("content://mms"), null, null, null, null);
while(curPdu.moveToNext())
{
String id = curPdu.getString (curPdu.getColumnIndex ("_id"));
String date = curPdu.getString (curPdu.getColumnIndex ("date"));
mms_add.add(getAddressNumber(Integer.parseInt(id)));
int type = Integer.parseInt(curPdu.getString(curPdu.getColumnIndex("m_type")));
mms_type.add((type==128)?"2":"1");
mms_date.add(getDate(Long.parseLong(date)));
}
//for image
Cursor curPart = getContentResolver (). query (Uri.parse ("content://mms/part"), null, null, null, null);
while(curPart.moveToNext())
{
coloumns = curPart.getColumnNames();
if(values == null)
values = new String[coloumns.length];
for(int i=0; i< curPart.getColumnCount(); i++)
{
values[i] = curPart.getString(i);
}
if(values[3].equals("image/jpeg"))
{
mms_image.add(GetMmsAttachment(values[0],values[12],values[4]));
}else{
mms_image.add("null");
}
}
so, please guide me how to get all the details using one cusor if possible.
You can try the solution and url provided here.
And may i know why you need 2 cursor ? I assume there is some mms without image attached so that's the reason you get a different count.

How to get the number of unread gmail mails (on android)

Please note there is a new way of doing this
I've been trying to get the number of unread gmail mails with no luck.
I've read Gmail.java and gmail4j both links taken out of this site from this question: Android - How can I find out how many unread email the user has?
But still after having read all of that and a couple of other sites that talked about this particular subject my question remains:
Q: How can I get the Gmail Unread Count?
Sorry if it seams a bit insistent but I clearly lack the knowledge to find this out on my own from the source.
PS: I would like to clarify that I want to do it without having to ask the user for credentials.
Just 2 add some colors to the question let me show you the looks of my app.
Please note there is a new way of doing this
Here's some code snippet. Not sure it works and can't test it. But I hope it will help you to continue the investigation.
public static final class LabelColumns {
public static final String CANONICAL_NAME = "canonicalName";
public static final String NAME = "name";
public static final String NUM_CONVERSATIONS = "numConversations";
public static final String NUM_UNREAD_CONVERSATIONS = "numUnreadConversations";
}
public void queryLabels(){
String account="email#company.com";
Uri LABELS_URI = Uri.parse("content://gmail-ls/labels/");
Uri ACCOUNT_URI = Uri.withAppendedPath(LABELS_URI, account);
ContentResolver contentResolver=myActivity.getContentResolver();
Cursor cursor = contentResolver.query(ACCOUNT_URI, null, null, null, null);
//iterate over all labels in the account
if (cursor.moveToFirst()) {
int unreadColumn = cursor.getColumnIndex(LabelColumns.NUM_UNREAD_CONVERSATIONS);
int nameColumn = cursor.getColumnIndex(LabelColumns.NAME);
do {
String name = cursor.getString(nameColumn);
String unread = cursor.getString(unreadColumn);//here's the value you need
} while (cursor.moveToNext());
}
}
Requires permission
<uses-permission android:name="com.google.android.gm.permission.READ_GMAIL"/>
This is how I've seen it done in a simple widget for the awesome window manager (yes, that's its name :)). Original script is here: gmail.lua.
The basic concept is to just use the inbox feed and get all the mails (you'll get just the summaries, not the whole content) for the special 'unread' tag. The URL is https://mail.google.com/mail/feed/atom/unread, you just have to fetch it (after authentication, of course), and then parse it. You can either use some sort of XML parser or just a simple regexp (<fullcount>([%d]+)</fullcount>) - the number you are looking for is at the beginning, in the <fullcount> tag.
So, that's one way of doing it, quite simple and "dumb", but hey, it works :D It might not be the best solution, as it requires you to fetch the whole feed (depending on the number of your unread messages and the type/quality of connection, it might not be as fast as just fetching the number of unread messages), but as usual, real-life testing should clear that up :)
There is new way how to do it. Old way doesn´t work anymore (21.01.2013).
Check following link:
Gmail Public Labels API
Maybe you can use the Gmail ContentProvider, please see http://www.google.com/codesearch/p?hl=en#uX1GffpyOZk/core/java/android/provider/Gmail.java&q=Gmail.java&sa=N&cd=1&ct=rc
There is a method getNumUnreadConversations or you could use a Observer.
static final String AUTHORITY = "com.google.android.gm";
static final String BASE_URI_STRING = "content://" + AUTHORITY;
static final String LABELS_PARAM = "/labels";
static final String ACCOUNT_TYPE_GOOGLE = "com.google";
public static final String NUM_UNREAD_CONVERSATIONS = "numUnreadConversations";
public static final String CANONICAL_NAME = "canonicalName";
public static final String CANONICAL_NAME_INBOX_CATEGORY_PRIMARY = "^sq_ig_i_personal";
static String[] GMAIL_PROJECTION = {
CANONICAL_NAME, NUM_UNREAD_CONVERSATIONS
};
public static Uri getLabelsUri(String account) {
return Uri.parse(BASE_URI_STRING + "/" + account + LABELS_PARAM);
}
static String[] getAllAccountNames(Context context) {
final Account[] accounts = AccountManager.get(context).getAccountsByType(
ACCOUNT_TYPE_GOOGLE);
final String[] accountNames = new String[accounts.length];
for (int i = 0; i < accounts.length; i++) {
accountNames[i] = accounts[i].name;
}
return accountNames;
}
protected static int getGmail(Context context) {
ContentResolver cr = context.getContentResolver();
Cursor cursor = cr.query(Launcher.getLabelsUri(BadgeUtils.getAllAccountNames(context)[0]),
GMAIL_PROJECTION,
null, null,
null);
if (cursor == null || cursor.isAfterLast()) {
Log.d(TAG, "No Gmail inbox information found for account.");
if (cursor != null) {
cursor.close();
}
return 0;
}
int count = 0;
while (cursor.moveToNext()) {
if (CANONICAL_NAME_INBOX_CATEGORY_PRIMARY.equals(cursor.getString(cursor.getColumnIndex(CANONICAL_NAME)))) {
count = cursor.getInt(cursor.getColumnIndex(NUM_UNREAD_CONVERSATIONS));;
break;
}
}
cursor.close();
return count;
}
Hope above code helps. This should work on Android 2.2+.

Categories

Resources