is content providers the only way to read/write private data such SMS and contacts? I first try the easy and lazy way (copy sms and contacts SQLite databases files) but I faced some permission issues. I'm asking because I'm trying to backup and restore SMS and contacts and that would be a lot of work accessing data field one by one.
Getting Contacts:
How to call Android contacts list?
How to get contacts from native phonebook in android
How to obtain all details of a contact in Android
How to get the first name and last name from Android contacts?
How to import contacts from phonebook to our application
Android contacts extraction
How to get all android contacts but without those which are on SIM
and for sms:
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 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]));
String type = cursor1.getString(cursor1.getColumnIndex(columns[4]));
}
}
To get the contact
Cursor cursor = getContentResolver().query(ContactsContract.Contacts.CONTENT_URI,null, null, null, null);
ArrayList<HashMap<String,String>> contactData=new ArrayList<HashMap<String,String>>();
while (cursor.moveToNext()) {
try{
String contactId = cursor.getString(cursor.getColumnIndex(ContactsContract.Contacts._ID));
String name=cursor.getString(cursor.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME));
String hasPhone = cursor.getString(cursor.getColumnIndex(ContactsContract.Contacts.HAS_PHONE_NUMBER));
if (Integer.parseInt(cursor.getString(cursor.getColumnIndex(ContactsContract.Contacts.HAS_PHONE_NUMBER))) > 0) {
Cursor phones = getContentResolver().query( ContactsContract.CommonDataKinds.Phone.CONTENT_URI, null, ContactsContract.CommonDataKinds.Phone.CONTACT_ID +" = "+ contactId, null, null);
while (phones.moveToNext()) {
String phoneNumber = phones.getString(phones.getColumnIndex( ContactsContract.CommonDataKinds.Phone.NUMBER));
HashMap<String,String> map=new HashMap<String,String>();
map.put("name", name);
map.put("number", phoneNumber);
contactData.add(map);
}
phones.close();
}
}catch(Exception e){}
}
To read the sms from the inbox
Uri mSmsinboxQueryUri = Uri.parse("content://sms");
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()) {
out.write("<message>");
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]));
String type = cursor1.getString(cursor1
.getColumnIndex(columns[4]));
}
}
Related
I'm reading sms messages from inbox using content provider. See following code:
Uri uriSms = Uri.parse("content://sms/inbox");
Cursor cursor = this.getContentResolver().query(uriSms, null, null, null, SORT_ORDER);
Inside loop I'm fetching all required columns:
String body= cursor.getString(cursor.getColumnIndex("body"));
String person = cursor.getString(cursor.getColumnIndex("person"));
I'm getting all values properly but person's name is returning 'null' value. Please guide me why contact name is not being returned from above statement.
The person column's value, if it exists, is not the sender's name. It's an ID that you would use to query the Contacts Provider to get the name. If you're getting null for person, then you'll have to use the address, which is the phone number, to query against. For example:
String address = cursor.getString(cursor.getColumnIndex("address"));
final String[] projection = new String[] {ContactsContract.Data.DISPLAY_NAME};
String displayName = null;
Cursor contactCursor = null;
try {
Uri uri = Uri.withAppendedPath(ContactsContract.PhoneLookup.CONTENT_FILTER_URI,
Uri.encode(address));
contactCursor = getContentResolver().query(uri,
projection,
null,
null,
null);
if (contactCursor != null && contactCursor.moveToFirst()) {
displayName = contactCursor.getString(
contactCursor.getColumnIndex(ContactsContract.Data.DISPLAY_NAME));
}
}
catch(Exception e) {
e.printStackTrace();
}
finally {
if(contactCursor != null) {
contactCursor.close();
}
}
Try this:
Cursor cursor = getContentResolver().query(
uriSms,
new String[] { "_id", "thread_id", "address", "person", "date",
"body", "type" }, null, null, null);
I want to get the list of SMS in the phone by a specific sender. These SMS are sent from a SMS gateway so I don't have the sender's number. However, I know the sender's name such as "Google".
This is what I have tried so far
final String SMS_URI_INBOX = "content://sms/inbox";
Uri uri = Uri.parse(SMS_URI_INBOX);
String[] projection = new String[] { "_id", "address", "person", "body", "date", "type" };
Cursor cur = getContentResolver().query(uri, projection, "person LIKE'%" + "Google" + "'", null, "date asc");
However, the cursor is empty.
You are almost there
final String SMS_URI_INBOX = "content://sms/inbox";
Uri uri = Uri.parse(SMS_URI_INBOX);
String[] projection = new String[] { "_id", "address", "person", "body", "date", "type" };
Cursor cur = getContentResolver().query(uri, projection, "address LIKE '%Google%'", null, "date asc");
Instead of querying for "person", query for "address". SMS gateways use name as the address.
` Try this This is used to get the last mesage received from a address. if you want to read all the messages iterate this cursor.
Uri mSmsinboxQueryUri = Uri.parse("content://sms/inbox");
Cursor cursor1 = getContentResolver().query(mSmsinboxQueryUri,
new String[] { "body", "address" }, null, null, null);
if (cursor1.getCount() > 0) {
cursor1.moveToFirst();
String address = cursor1.getString(1);
if (address.contains("Google")) {
String body = cursor1.getString(0);
}
}
`
Is it possible using ContactsContract to get contacts with which the user talks often?
I know I can use the CallLog ContentProvider and try to figure that out, but I wanted to know if there is already a way to do it.
The number of times a contact has been contacted
ContactsContract.Contacts.times_contacted
static final String[] CONTACTS_SUMMARY_PROJECTION = new String[] {
ContactsContract.Contacts._ID,
ContactsContract.Contacts.DISPLAY_NAME,
ContactsContract.Contacts.STARRED,
ContactsContract.Contacts.TIMES_CONTACTED,
ContactsContract.Contacts.CONTACT_PRESENCE,
ContactsContract.Contacts.PHOTO_ID,
ContactsContract.Contacts.LOOKUP_KEY,
ContactsContract.Contacts.HAS_PHONE_NUMBER,
};
String name_to_search = "John Doe";
Cursor c = context.getContentResolver().query(ContactsContract.Contacts.CONTENT_URI, CONTACTS_SUMMARY_PROJECTION, null, null, ContactsContract.Contacts.TIMES_CONTACTED);
context.startManagingCursor(c);
if (c.moveToNext())
{
String id = c.getString(0);
ArrayList<String> phones = new ArrayList<String>();
Cursor pCur = context.getContentResolver().query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI, null, ContactsContract.CommonDataKinds.Phone.CONTACT_ID +" = ?", new String[]{id}, null);
while (pCur.moveToNext())
{
phones.add(pCur.getString(pCur.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER)));
Log.i("", name_to_search+ " has the following phone number "+ pCur.getString(pCur.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER)));
}
pCur.close();
}
I have this method to display the contact numbers in my inbox:
public ArrayList<String> fetchInboxNumbers() {
ArrayList<String> sms = new ArrayList<String>();
Uri uriSms = Uri.parse("content://sms/inbox");
Cursor cursor = getContentResolver().query(uriSms,
new String[] { "_id", "address", "date", "body" }, null, null, null);
cursor.moveToFirst();
while (cursor.moveToNext()) {
address = cursor.getString(1); // Displays phone number
Log.d("CONTACT", address);
sms.add(address); // + " " + body
}
Log.d("NAMES IN CALLLOG", sms.get(7));
return sms;
} // END FETCHINBOX
What I'm trying to do is change String address to its contact name.
From fetchContactNumbers() and 'fetchContactNames(), how can I changeaddress` to a contact name?
Its important to understand that fetchContactNumbers and fetchContactNames() are aligned, meaning fetchContactNumbers().get(5)'s contact name is fetchContactNames().get(5)`.
In the end, fetchInboxNumbers() populates a custom adapter.
This method returns a list of all contact names:
public ArrayList<String> fetchContactNames() {
ArrayList<String> names = new ArrayList<String>();
Cursor phones = getContentResolver().query(
ContactsContract.CommonDataKinds.Phone.CONTENT_URI, null, null,
null, null);
while (phones.moveToNext()) {
String name = phones
.getString(phones
.getColumnIndex(ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME));
names.add(name);
}
phones.close();
return names;
}
And this method lists all phone numbers:
public ArrayList<String> fetchContactNumbers() {
ArrayList<String> numbers = new ArrayList<String>();
Cursor phones = getContentResolver().query(
ContactsContract.CommonDataKinds.Phone.CONTENT_URI, null, null,
null, null);
while (phones.moveToNext()) {
String phoneNumber = phones
.getString(phones
.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER));
numbers.add(phoneNumber);
}
phones.close();
return numbers;
}
You can use CONTENT_FILTER_URI to get the display name, instead of getting all names and numbers separately, something like below:
public ArrayList<String> fetchInboxNumbers() {
String displayName = "";
ArrayList<String> sms = new ArrayList<String>();
Uri uriSms = Uri.parse("content://sms/inbox");
Cursor cursor = getContentResolver().query(uriSms,
new String[] { "_id", "address", "date", "body" }, null, null, null);
cursor.moveToFirst();
while (cursor.moveToNext()) {
address = cursor.getString(1); // Displays phone number
displayName = getDisplayName(address);
sms.add(displayName); // + " " + body
}
return sms;
} // END FETCHINBOX
private String getDisplayName(String phoneNumber) {
String displayName = "";
Uri uri = Uri.withAppendedPath(ContactsContract.PhoneLookup.CONTENT_FILTER_URI, Uri.encode(phoneNumber));
Cursor cursor = context.getContentResolver().query(uri, new String[] { Phone._ID, Phone.DISPLAY_NAME}, null, null, null);
if (cursor.moveToFirst()) {
displayName = cursor.getString(cursor.getColumnIndex(ContactsContract.PhoneLookup.DISPLAY_NAME));
}
return displayName;
}
Is it a spelling mistake? a variable mistake?
private String getDisplayName(String phoneNyumber) {
Uri uri = Uri.withAppendedPath(ContactsContract.PhoneLookup.
CONTENT_FILTER_URI, Uri.encode(phoneNumber));
.....
}
Your argument is having phoneNyumber and you are using phoneNumber.
Please tell me how can i get the name of message sender. i tried following .All field works fine but but name always 0. Please give me solution.
String SORT_ORDER = "date DESC";
int count = 0;
String[] str= new String[] { "_id", "thread_id", "address", "person", "date", "body" };
Cursor cursor = getContentResolver().query(
Uri.parse("content://sms"),
str,
null,
null,
SORT_ORDER);
Log.e("!!!!!!!!", ""+cursor.getCount());
while (cursor.moveToNext()) {
try {
// count = cursor.getCount();
long messageId = cursor.getLong(0);
long threadId = cursor.getLong(1);
String address = cursor.getString(2);
long contactId = cursor.getLong(3);
String contactId_string = String.valueOf(contactId);
long timestamp = cursor.getLong(4);
String body = cursor.getString(5);
Log.e("!!!!!!!!", "number"+address);
Log.e("!!!!!!!!", "name"+contactId_string);
I think you will get number of message sender which you have to search in PhoneLookup
Uri uri = Uri.withAppendedPath(PhoneLookup.CONTENT_FILTER_URI, Uri.encode(phoneNumber));
resolver.query(uri, new String[]{PhoneLookup.DISPLAY_NAME} .....)