从MarshMallow的Widget中显示来自SDCard的图像

在一个小部件中,我使用remoteView.setImageViewUri()从SDCard显示图像。 除MarshMallow之外,此策略正常工作:

错误是:

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

很显然,这是一个权限问题,但是我不知道如何给Widget容器赋予权限,理论上(见注1)这些图像已经存储在共享存储中。

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

注2 :应用程序不适用于MarshMallow,并使用targetSdkVersion = 15

注意3 :不要只回复关于MarshMallow中的新运行时权限的解释。 我已经知道权限的变化,这不是问题,因为应用程序是针对SDKVersion 15和应用程序访问外部存储没有任何问题,问题是与小部件容器,我怀疑是没有权限。

Solutions Collecting From Web of "从MarshMallow的Widget中显示来自SDCard的图像"

嗨,这里是几个安装程序权限的步骤,并记住你应该声明相同的权限在清单文件以及。

步骤1.声明全局variables:

 public static final int MY_PERMISSIONS_REQUEST_LOCATION = 0; 

第2步。在你的主要活动中使用这个代码

 private void locationpermission() { // Here, thisActivity is the current activity if (ContextCompat.checkSelfPermission(activity , Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) { // Should we show an explanation? if (ActivityCompat.shouldShowRequestPermissionRationale(activity, Manifest.permission.ACCESS_COARSE_LOCATION)) { // 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(activity, new String[]{Manifest.permission.ACCESS_COARSE_LOCATION}, MY_PERMISSIONS_REQUEST_LOCATION); // MY_PERMISSIONS_REQUEST_READ_CONTACTS is an // app-defined int constant. The callback method gets the // result of the request. } } } @Override public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) { switch (requestCode) { case MY_PERMISSIONS_REQUEST_LOCATION: { // If request is cancelled, the result arrays are empty. if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) { // permission was granted, yay! Do the // contacts-related task you need to do. } else { // permission denied, boo! Disable the // functionality that depends on this permission. } return; } // other 'case' lines to check for other // permissions this app might request } } 

第3步。在你的oncreate方法中调用这个方法,

locationpermission(); 和任何人的权限,你可以从这里调用,每一个结果,你可以在覆盖方法onRequestPermissionsResult这一个。

谢谢

希望这会帮助你(Y)。

请从这里举例

https://www.dropbox.com/s/w29sljy0zpwwm61/MyApplication.zip?dl=0

@Docs说

在运行时请求权限

从Android 6.0(API级别23)开始,用户在应用程序运行时向应用程序授予权限,而不是在安装应用程序时授予应用程序权限。 此方法简化了应用程序安装过程,因为用户在安装或更新应用程序时无需授予权限。 它还使用户能够更好地控制应用程序的function;

因此,尽pipe您在清单中声明了权限,但仍然获得了权限的拒绝

我build议你阅读如何获得运行时权限

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

这是Docs提供的示例

  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. } 

}

根据您的要求更改权限

希望它能引导你走向正确的方向

你在Manifest文件中有这个许可吗?

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

如果我将targetSdkVersion设置为15而不是23,那么android M用户将看到该应用程序并能够下载它(在运行时授予所有权限)?

是的,该应用程序将提供给M个用户,并在安装时授予每个权限。

 `targetSdkVersion=15` 

小于23.用户将能够下载应用程序并使用它授予在运行时的所有权限。 如果你想检查权限去设置和授予权限。 如果要在运行时使用android M权限模块,则必须将目标SDK版本设置为23.如果在android M和更高版本的设备应用程序上设置targetSdkVersion=15targetSdkVersion=15崩溃。

如果你想支持android M用户设置targetSdkVersion=23并处理权限运行时。