Until now I've been loading a bitmap into my RemoteViews directly using remoteViews.setImageViewBitmap(). It's working fine in general.
But a couple of users are having issues, and I think it is when loading in a bitmap that is very large. I cache the bitmap to local storage already anyway, so my idea is to use setImageViewUri() instead, as recommended elsewhere.
But I can't get it to work... I just get a blank widget. The following snippet illustrates what I'm doing (leaving out some the context but hopefully leaving enough)...
// Bitmap bmp is fetched from elsewhere... and then...
FileOutputStream fos = context.openFileOutput("img.png", Context.MODE_PRIVATE);
bmp.compress(Bitmap.CompressFormat.PNG, 100, fos);
fos.flush();
fos.close();
// ... later ...
// this works...
remoteViews.setImageViewBitmap(R.id.imageView, bmp);
// but this doesn't...
remoteViews.setImageViewUri(R.id.imageView, Uri.fromFile(new File(context.getFilesDir().getPath(), "img.png")));
EDIT
Trying to use FileProvider as suggested by CommonsWare below...
Manifest:
<provider
android:name="android.support.v4.content.FileProvider"
android:authorities="com.xyz.fileprovider"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/file_paths" />
</provider>
xml/file_paths.xml:
<paths xmlns:android="http://schemas.android.com/apk/res/android">
<files-path name="cache" path="."/>
</paths>
code:
File imagePath = new File(context.getFilesDir(), ".");
File newFile = new File(imagePath, "img.png"); // img.png created as above, in top level folder
remoteViews.setImageViewUri(R.id.imageView, FileProvider.getUriForFile(context, "com.xyz.fileprovider", newFile));
But still I'm left with a blank widget, as before, and without an error in the logcat.
Your app widget is being rendered by the home screen. The home screen cannot access internal storage of your app.
Instead, try using FileProvider to serve up files from internal storage, with a Uri supplied by FileProvider in your setImageViewUri() call.
UPDATE: I forgot about FileProvider's permission limitations. I do not know of a reliable way to grant permissions to the Uri to the home screen process via RemoteViews. Ideally, you would just allow the provider to be exported, but FileProvider does not support that.
Your options, then, are:
Write your own streaming ContentProvider, akin to this one, where the provider is exported, so anyone can consume the Uri values.
Put the file on external storage, instead of internal storage, then hope that the home screen has READ_EXTERNAL_STORAGE or WRITE_EXTERNAL_STORAGE permissions.
Ensure that your image is always fairly small, so your IPC transaction stays below the 1MB limit, and go with your original setImageViewBitmap() approach.
I apologize for having forgotten about FileProvider not allowing the provider to be exported.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With