2

I'm trying to create a contact widget that displays a GridView with the contacts' pictures and names, opening the information of the appropriate contact when the view is pressed, but I'm getting permission denial when displaying the picture in the widget.

First I just created an app to test displaying GridViews and querying contacts. I mention this because it means that I had to include to the correct permissions (android.permission.READ_CONTACTS) for the app to work. Once that was working, I tried to create a widget that did the same thing. Everything worked on that except for displaying the pictures of contacts that have pictures, which didn't work because of the following exception:

07-05 22:43:16.934: E/DatabaseUtils(17897): java.lang.SecurityException: Permission Denial: reading com.android.providers.contacts.ContactsProvider2 uri content://com.android.contacts/contacts/165/photo from pid=710, uid=10065 requires android.permission.READ_CONTACTS

The corresponding application was com.teslacoilsw.launcher (Nova?) as opposed to my package name, in case that matters. But I am confused: The app read everything fine and displayed the photo. The widget read the contacts' display names and lookup URIs just fine, but it's getting these exceptions when trying to read the pictures. Is there some way I'm supposed to add additional permissions to widgets?

Here is the code where I create the RemoteView and add the information

RemoteViews rv = new RemoteViews(mContext.getPackageName(), R.layout.contact_widget_row);
contactCursor.moveToPosition(position);
String contactName = contactCursor.getString(
        contactCursor.getColumnIndexOrThrow(ContactsContract.Contacts.DISPLAY_NAME_PRIMARY));
rv.setTextViewText(R.id.text1, contactName);
String uriString = contactCursor.getString(
        contactCursor.getColumnIndexOrThrow(ContactsContract.Contacts.PHOTO_URI));
if(uriString != null)
{
    rv.setImageViewUri(R.id.image1, Uri.parse(uriString));
}
else
{
    rv.setImageViewResource(R.id.image1, R.drawable.ic_contacts_holo_dark);
}

FWIW the image for the null URIs displays just fine, but that doesn't require displaying a URI from the contacts.

How do I need to set the permissions to display the contact photos in my widget?

wile_e8
  • 337
  • 2
  • 12

1 Answers1

0

Just playing around with possible solutions, and I found something that works. Instead of creating the image in the RemoteViews with the URI, use the URI to create a Bitmap and then set the image in the RemoteViews with that:

if(uriString != null)
{
    //rv.setImageViewUri(R.id.image1, Uri.parse(uriString));
    try
    {
        Bitmap bm = MediaStore.Images.Media.getBitmap(mContext.getContentResolver(), Uri.parse(uriString));
        rv.setImageViewBitmap(R.id.image1, bm);
    }
    catch(Exception e)
    {
        rv.setImageViewResource(R.id.image1, R.drawable.ic_contacts_holo_dark);
    }
}
else
{
    rv.setImageViewResource(R.id.image1, R.drawable.ic_contacts_holo_dark);
}

The catch block is because the Bitmap creation call throws FileNotFoundException and IOException.

I don't know why this works, but it does. I'm guessing because the image is read from the URI in the contacts when creating the Bitmap (inside my package that has READ_CONTACTS permissions), as opposed to when the launcher draws the widget (outside my package).

I would like to credit the answer at this link for showing me how to create a Bitmap from a URI.

Community
  • 1
  • 1
wile_e8
  • 337
  • 2
  • 12