从Marshmallow中的SDCard在小部件中显示图像

16

我在一个小部件中使用remoteView.setImageViewUri()方法显示SD卡中的图片。这种方法在Marshmallow以外的版本中都能正常工作:

错误信息为:

Unable to open content:  file:///storage/emulated/0/Android/data/applicaitonPackage/files/file.png
open failed: EACCESS (Permission denied)

很明显这是一个权限问题,但我不知道如何授予小部件容器权限,在理论上(见注1),图片已经存储在共享存储中。

注1:图像存储的目录是Environment.getExternalStorageDirectory()下的共享存储。

注2:应用程序未适配MarshMallow并使用targetSdkVersion = 15

注3:请不要只回复解释MarshMallow中的新运行时权限。我已经知道权限更改并且这不是问题,因为应用程序针对SDK版本15,并且该应用程序没有任何访问外部存储的问题,问题出在小部件容器上,我怀疑它没有权限。

3个回答

2

@Docs 说

在 Android 6.0(API 级别 23)及以上版本中,用户授予应用程序权限时,应用程序正在运行,而不是安装应用程序时。 这种方法简化了应用程序的安装过程,因为用户无需在安装或更新应用程序时授予权限。它还使用户对应用程序的功能拥有更多控制权;

因此,尽管在清单中声明权限但仍然被拒绝权限是有意义的。

我建议您阅读如何获取运行时权限

http://developer.android.com/training/permissions/requesting.html

这是文档提供的示例

    if (ContextCompat.checkSelfPermission(thisActivity,
            Manifest.permission.READ_CONTACTS)
    != PackageManager.PERMISSION_GRANTED) {

// Should we show an explanation?
if (ActivityCompat.shouldShowRequestPermissionRationale(thisActivity,
        Manifest.permission.READ_CONTACTS)) {

    // Show an expanation to the user *asynchronously* -- don't block
    // this thread waiting for the user's response! After the user
    // sees the explanation, try again to request the permission.

} else {

    // No explanation needed, we can request the permission.

    ActivityCompat.requestPermissions(thisActivity,
            new String[]{Manifest.permission.READ_CONTACTS},
            MY_PERMISSIONS_REQUEST_READ_CONTACTS);

    // MY_PERMISSIONS_REQUEST_WRITE_EXTERNAL_STORAGE is an
    // app-defined int constant. The callback method gets the
    // result of the request.
}

根据您的需求更改权限

希望这会引导您走向正确的方向


1
请注意注释2。当目标SDK小于23时,运行时权限不会生效。 - lujop

0

你在清单文件中有这个权限吗?

<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />

1
我拥有WRITE_EXTERNAL_STORAGE权限,根据文档,这授予了READ权限。 但问题不在应用程序中,而是在WidgetContainer中,它由操作系统在另一个进程中运行。 - lujop

0

如果我将targetSdkVersion设置为15而不是23——那么安卓M用户能看到这个应用并且可以下载它吗(在运行时授予所有权限)?

是的,该应用将对M用户可用,并且每个权限都会在安装时被授予。

`targetSdkVersion=15` 

该应用程序的版本必须小于23。用户可以下载并使用该应用程序,它将在运行时授予所有权限。如果您想检查权限,请转到设置并授予权限。如果您想在运行时使用Android M权限模块,则必须将目标SDK版本设置为23。 如果在Android M及更高版本设备上设置targetSdkVersion=15,则应用程序会崩溃。

如果您想支持Android M用户,请设置targetSdkVersion=23并处理运行时权限。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接