Android:将位图从本地存储加载到应用程序小部件(RemoteViews)

drm*_*wer 2 android remoteview android-appwidget android-remoteview

到目前为止,我一直在RemoteViews使用remoteViews.setImageViewBitmap(). 它总体上运行良好。

但是一些用户遇到了问题,我认为这是在加载非常大的位图时。无论如何,我已经将位图缓存到本地存储,所以我的想法是改用setImageViewUri()其他地方的建议。

但我无法让它工作......我只是得到一个空白的小部件。以下代码段说明了我在做什么(省略了一些上下文,但希望留下足够的内容)...

// 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")));
Run Code Online (Sandbox Code Playgroud)

编辑

尝试FileProvider按照以下 CommonsWare 的建议使用...

显现:

<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>
Run Code Online (Sandbox Code Playgroud)

xml/file_paths.xml:

<paths xmlns:android="http://schemas.android.com/apk/res/android">
    <files-path name="cache" path="."/>
</paths>
Run Code Online (Sandbox Code Playgroud)

代码:

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));
Run Code Online (Sandbox Code Playgroud)

但是我仍然像以前一样留下一个空白小部件,并且 logcat 中没有错误。

Com*_*are 5

您的应用小部件正在由主屏幕呈现。主屏幕无法访问您的应用程序的内部存储。

相反,尝试使用FileProvider从内部存储Uri提供文件,并FileProvider在您的setImageViewUri()呼叫中提供。

更新:我忘记了FileProvider的权限限制。我不知道Uri通过RemoteViews. 理想情况下,您只允许导出提供程序,但FileProvider不支持。

那么,您的选择是:

  1. 编写你自己的流ContentProvider,类似于这个,提供者被导出,所以任何人都可以使用这些Uri值。

  2. 把文件放在外部存储,而不是内部存储,然后希望主屏幕有READ_EXTERNAL_STORAGE或WRITE_EXTERNAL_STORAGE权限。

  3. 确保您的图像始终相当小,以便您的 IPC 事务保持在 1MB 限制以下,并采用您原来的setImageViewBitmap()方法。

我很抱歉忘记了FileProvider不允许导出提供程序。