I can see in LogCat that ActivityManager is reporting something about a particular content provider. I use the following code to try to access that content provider in order to learn more about it:
Cursor cursor = context.getContentResolver().query(uriDSDS, null, null, null, null);
String[] columnNames = cursor.getColumnNames();
Log.d(TAG, "columnNames=" + columnNames.toString());
Unfortunately, after trying to get the cursor, I see the following error in LogCat:
Failed to find provider for __
What's the problem? Why can I not access this provider? Could it be that access is restricted to certain apps? Is there a way to go into ADB or something else to see all of the available content providers on the device?
make sure that you add correct Uri
for example
Uri uriDSDS = Uri.parse(
"content://aaa.aaa/values");
As in the working example below, do check if your uriDSDSis correct.
Cursor people = getContentResolver().query(
ContactsContract.Contacts.CONTENT_URI, null, null, null,
null);
// get contact id
while (people.moveToNext()) {
if (people != null) {
int numberFieldColumnIndex = people
.getColumnIndex(PhoneLookup._ID);
String number = people.getString(numberFieldColumnIndex);
contactId.add(number);
}
}
people.close();
Related
I need to get a link from auto-sent-SMS, but this SMS is always from a different number, so it's not like Retriever API.
I wanted to know - is it even possible for Android 8-9 and higher to programmatically read SMS via app?
If you know some examples on how - appreciate if you'll share :)
*most of the topics here are outdated or related to Retriever API so I wanted to know for sure about the latest Android versions.
There are Telephony.Sms.Inbox and Telephony.Sms.Sent content providers to access incoming and outgoing sms data. I used this far far way ago, but now i got my old code, and it still working in api 29. Here is my sample code to get basic data from inbox table, it's full text, but better way is to access content_uri and columns via content provider classes. If you want to get more columns, check docs. Remember, you need to grant READ_SMS permission.
Uri inboxUri = Uri.parse("content://sms/inbox");
String[] projection = new String[] { "_id", "date", "date_sent", "address", "body" };
String sortOrder = "date";
String limit = " DESC";
Cursor cursor = mContext.getApplicationContext().getContentResolver().
query(inboxUri, projection, null, null, sortOrder + limit);
if (cursor != null) {
if (cursor.moveToFirst()) {
do {
//read sms data
} while (cursor.moveToNext());
}
cursor.close();
}
Im trying to make some changes to an app that i've downloaded, the app uses ContactContracts to show the list of contacts stored in the phone,
what im trying to do is using a content provider to show a list of contacts that i've stored in my database
the original app uses this method to load contacts from the phone and store the in "contact" object:
public void loadContactsData(){
if(SmsSchedulerApplication.contactsList.size()==0){
System.currentTimeMillis();
String[] projection = new String[] {Groups._ID};
Uri groupsUri = ContactsContract.Groups.CONTENT_URI;
groupCursor = managedQuery(groupsUri, projection, null, null, null);
ContentResolver cr = getContentResolver();
Cursor cursor = cr.query(ContactsContract.Contacts.CONTENT_URI, null, null, null, null);
if(cursor.moveToFirst()){
do{
if(!(cursor.getString(cursor.getColumnIndex(ContactsContract.Contacts.HAS_PHONE_NUMBER)).equals("0"))){
String id = cursor.getString(cursor.getColumnIndex(ContactsContract.Contacts._ID));
Cursor phones = cr.query(Phone.CONTENT_URI, null, Phone.CONTACT_ID + " = " + id, null, null);
if(phones.moveToFirst()){
Contact contact = new Contact();
contact.content_uri_id = cursor.getString(cursor.getColumnIndex(ContactsContract.Contacts._ID));
contact.name = cursor.getString(cursor.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME));
contact.number = phones.getString(phones.getColumnIndex(Phone.NUMBER));
Cursor cur = cr.query(ContactsContract.Data.CONTENT_URI, new String[]{ContactsContract.CommonDataKinds.GroupMembership.GROUP_ROW_ID}, ContactsContract.CommonDataKinds.GroupMembership.CONTACT_ID + "=" + contact.content_uri_id, null, null);
if(cur.moveToFirst()){
do{
if(!String.valueOf(cur.getLong(cur.getColumnIndex(ContactsContract.CommonDataKinds.GroupMembership.GROUP_ROW_ID))).equals(contact.number) && cur.getLong(cur.getColumnIndex(ContactsContract.CommonDataKinds.GroupMembership.GROUP_ROW_ID))!=0){
boolean isValid = false;
if(groupCursor.moveToFirst()){
do{
if(!cur.isClosed() && !groupCursor.isClosed() && cur.getLong(cur.getColumnIndex(ContactsContract.CommonDataKinds.GroupMembership.GROUP_ROW_ID)) == groupCursor.getLong(groupCursor.getColumnIndex(Groups._ID))){
isValid = true;
break;
}
}while(groupCursor.moveToNext());
}
if(isValid){
contact.groupRowId.add(cur.getLong(cur.getColumnIndex(ContactsContract.CommonDataKinds.GroupMembership.GROUP_ROW_ID)));
}
}
}while(cur.moveToNext());
}
cur.close();
Uri uri = ContentUris.withAppendedId(ContactsContract.Contacts.CONTENT_URI, Long.parseLong(contact.content_uri_id));
InputStream input = ContactsContract.Contacts.openContactPhotoInputStream(cr, uri);
try{
contact.image = BitmapFactory.decodeStream(input);
contact.image.getHeight();
} catch (NullPointerException e){
contact.image = BitmapFactory.decodeResource(getApplicationContext().getResources(), R.drawable.no_image_thumbnail);
}
SmsSchedulerApplication.contactsList.add(contact);
}
}
}while(cursor.moveToNext());
}
}
}
im not familiar with using content provider so im not sure what should i define in my content provider class
You don't have to use a content provider if you don't want to. Also using a contacts provider example to realize an own user database management is the wrong approach here. The provider was evolved multiple times to support all kind of use cases. I mean, just look at the documentation of it. All this tables and and micromanagement. I doubt that you need all of this.
I suggest you do the following. First create you database scheme. Find out what tables do you need and what columns are required for the application to work. Then put it into an sqlite database and define the queries to store and retrieve the contents. This should be all necessary to make the app work.
Then if everything works and you still have the motivation or requirements, create a content provider by using the existing database as the data store withing the provider and declaring URI's to access and modify the content. Of course you then have to rewrite some portions of the existing code. But if you were using the query, update, delete and insert methods of the database, it should be no problem.
Or you do it the hard way and insert your contacts in the contacts provider by inserting raw contacts. But it you don't have to share your contacts with the system (to crate custom actions on existing contacts for example) or other apps, then just don't do it.
Gmail.java link as referred to in one of the questions on SO is broken.
My code is
String account="abc.xyz#gmail.com";
Uri LABELS_URI = Uri.parse("content://gmail-ls/unread/");
Log.d("pavan","label "+LABELS_URI );
Uri ACCOUNT_URI = Uri.withAppendedPath(LABELS_URI, account);
Log.d("pavan","label "+ACCOUNT_URI );
ContentResolver contentResolver= this.getContentResolver();
Log.d("pavan","contentResolver "+contentResolver );
Cursor cursor = contentResolver.query(ACCOUNT_URI, null, null, null, null);
but the contentResolver line is throwing an error, the logcat says:
cannot find provider info for gmail-ls.
Any ideas how to solve this?
Use the Android Gmail API, if it meets your needs. Otherwise, the Gmail application no longer supports access such as what you are doing.
When picking out contact details, is there a built in domain class they can be mapped to? Or, do you have to create your own?
For example I do the following :
ContentResolver cr = getContentResolver();
Cursor cur = cr.query(ContactsContract.Contacts.CONTENT_URI,
null, null, null, null);
String s = null;
if (cursor.getCount() > 0)
{
while (cursor.moveToNext())
{
s = cursor.getString(cursor.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME));
}
}
With s, can I put that into a "contact" object/domain class, perhaps something like :
Contact myContact = new Contact();
myContact.setName(s);
AFAIK There is no built in Contacts class, besides with extensible Contacts model in android it will soon become a Bean around CommonDataKinds plus Map for everything else, besides I believe it's also true for the most of data provided by Android SDK
They give you access to Data how you handle it is yours choice
I am trying to get the sender's name from the contacts database using a content provider.
The problem is I don't know how to implement it. Like now I can only pull the phone number from the smsMessage. I need to check to see if the phone number that is calling is in the users contacts first and if it is display the name if it is not then display the number.
Yes, this is possible using ContactsContract.PhoneLookup.CONTENT_FILTER_URI in Android 2.0 and higher and Contacts.Phones.CONTENT_FILTER_URL in Android 1.6 and earlier.
For example usage, see the documentation for ContactsContract.PhoneLookup. Excerpt below:
// Android 1.6 and earlier (backwards compatible for Android 2.0+)
Uri uri = Uri.withAppendedPath(Contacts.Phones.CONTENT_FILTER_URL, Uri.encode(phoneNumber));
// Android 2.0 and later
Uri uri = Uri.withAppendedPath(ContactsContract.PhoneLookup.CONTENT_FILTER_URI, Uri.encode(phoneNumber));
// Query the filter URI
String[] projection = new String[]{ PhoneLookup.DISPLAY_NAME, ...
Cursor cursor = context.getContentResolver().query(uri, projection, ...
UPDATE: The format of the phone number does not matter. Comparison is robust and highly optimized on Android; it's done using a native sqlite function named PHONE_NUMBERS_EQUAL. For more details, search the codebase for this method. By the way, I'm not certain if it's safe to use that function directly in your own apps, but I wouldn't.
Here's what I did
ContentResolver localContentResolver = this.mContext.getContentResolver();
Cursor contactLookupCursor =
localContentResolver.query(
Uri.withAppendedPath(PhoneLookup.CONTENT_FILTER_URI,
Uri.encode(phoneNumber)),
new String[] {PhoneLookup.DISPLAY_NAME, PhoneLookup._ID},
null,
null,
null);
try {
while(contactLookupCursor.moveToNext()){
String contactName = contactLookupCursor.getString(contactLookupCursor.getColumnIndexOrThrow(PhoneLookup.DISPLAY_NAME));
String contactId = contactLookupCursor.getString(contactLookupCursor.getColumnIndexOrThrow(PhoneLookup._ID));
Log.d(LOGTAG, "contactMatch name: " + contactName);
Log.d(LOGTAG, "contactMatch id: " + contactId);
}
} finally {
contactLookupCursor.close();
}
Passing in your phone number you already have into Uri.encode(phoneNumber)