在 MarshMallow 的小部件中显示来自 SDCard 的图像

Posted

技术标签:

【中文标题】在 MarshMallow 的小部件中显示来自 SDCard 的图像【英文标题】:Displaying images from SDCard in a Widget from MarshMallow 【发布时间】:2016-07-07 18:24:06 【问题描述】:

在一个小部件中,我使用remoteView.setImageViewUri() 显示来自 SDCard 的图像。除 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 中新的运行时权限。我已经知道权限更改,这不是问题,因为应用程序的目标是 SDKVersion 15,并且应用程序访问外部存储没有任何问题,问题出在我怀疑没有的小部件容器上权限。

【问题讨论】:

【参考方案1】:

您好,这里是为 android M 设置权限的几个步骤,记住您也应该在清单文件中声明相同的权限。

步骤 1. 声明全局变量:

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 方法中调用此方法,

位置权限(); 以及您可以从此处调用的任何权限以及您可以在覆盖方法 onRequestPermissionsResult 中获得的每个结果。

谢谢

希望这对你有帮助(Y)。

请参考这里的例子

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

【讨论】:

你能解释一下你没有得到什么或有什么问题吗? 你说的我都知道了。这不适用,因为应用程序针对 SDK 版本 15,而且问题不在应用程序中。问题在于与作为单独应用程序的小部件容器一起运行的小部件。 你能解释一下如何在小部件中获取这个活动吗?【参考方案2】:

@Docs 说

在运行时请求权限

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

因此,尽管您在清单中声明了权限但仍然获得权限被拒绝,这是有道理的

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

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.

根据您的要求更改权限

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

【讨论】:

看注释2。当targetSDK为 【参考方案3】:

您的清单文件中是否有此权限?

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

【讨论】:

我有 WRITE_EXTERNAL_STORAGE 根据文档授予 READ 一个。但问题不在于应用程序,问题在于操作系统在另一个进程中运行的 WidgetContainer。【参考方案4】:

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

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

`targetSdkVersion=15` 

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

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

【讨论】:

以上是关于在 MarshMallow 的小部件中显示来自 SDCard 的图像的主要内容,如果未能解决你的问题,请参考以下文章

如何禁用来自另一个站点的小部件上的链接?

在低于 Marshmallow 的版本上显示吐司消息

我调用的小部件未显示在颤振列中

处理来自引用未知的小部件的信号

如何在从另一个小部件继承的小部件中设置数据?

显示当前小部件类之外的小部件