【问题标题】:Displaying images from SDCard in a Widget from MarshMallow在 MarshMallow 的小部件中显示来自 SDCard 的图像
【发布时间】: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,并且应用程序访问外部存储没有任何问题,问题出在我怀疑没有的小部件容器上权限。

【问题讨论】:

    标签: android android-widget android-6.0-marshmallow


    【解决方案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 处理权限运行时。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2013-08-07
      • 1970-01-01
      • 1970-01-01
      • 2012-01-06
      • 2011-06-29
      • 1970-01-01
      • 2011-06-27
      相关资源
      最近更新 更多