【问题标题】:Android 6 revoked permissions checked as grantedAndroid 6 撤销的权限检查为已授予
【发布时间】:2016-01-19 13:49:18
【问题描述】:

遇到问题了,我不确定是否是错误。

如果用户授予权限,然后随后撤消该权限,则 checkSelfPermission 似乎对已撤消的权限返回 GRANTED。

例如看来撤销permission.CAMERA后:

true == ActivityCompat.checkSelfPermission(context, permission.CAMERA)
                            == PackageManager.PERMISSION_GRANTED

我似乎发现相机被撤销的唯一方法是例外:

10-20 14:25:54.330: E/AndroidRuntime(13954): java.lang.SecurityException: Permission Denial: starting Intent { act=android.media.action.IMAGE_CAPTURE flg=0x3 cmp=com.google.android.GoogleCamera/com.android.camera.CaptureActivity clip={text/uri-list U:file:///storage/emulated/0/Pictures/JPEG_20151020_142554_399504353.jpg} (has extras) } from ProcessRecord{adc5d77 13954:com.conx2share.conx2share.staging/u0a144} (pid=13954, uid=10144) with revoked permission android.permission.CAMERA
10-20 14:25:54.330: E/AndroidRuntime(13954):    at android.os.Parcel.readException(Parcel.java:1599)
10-20 14:25:54.330: E/AndroidRuntime(13954):    at android.os.Parcel.readException(Parcel.java:1552)
10-20 14:25:54.330: E/AndroidRuntime(13954):    at android.app.ActivityManagerProxy.startActivity(ActivityManagerNative.java:2658)
10-20 14:25:54.330: E/AndroidRuntime(13954):    at android.app.Instrumentation.execStartActivity(Instrumentation.java:1507)
10-20 14:25:54.330: E/AndroidRuntime(13954):    at android.app.Activity.startActivityForResult(Activity.java:3917)
10-20 14:25:54.330: E/AndroidRuntime(13954):    at android.app.Activity.startActivityForResult(Activity.java:3877)
10-20 14:25:54.330: E/AndroidRuntime(13954):    at android.support.v4.app.FragmentActivity.startActivityFromFragment(FragmentActivity.java:855)
10-20 14:25:54.330: E/AndroidRuntime(13954):    at android.support.v4.app.FragmentActivity$HostCallbacks.onStartActivityFromFragment(FragmentActivity.java:907)
10-20 14:25:54.330: E/AndroidRuntime(13954):    at android.support.v4.app.Fragment.startActivityForResult(Fragment.java:930)

有谁知道这是用户错误还是新权限系统中的错误?

【问题讨论】:

  • 我无法使用this sample app 重现您的问题。我运行该应用程序,它会在首次运行时请求权限。我授予它们,然后转到设置并撤销它们。我回到示例应用程序并单击“拍照”按钮。该应用程序正确检测到我没有权限并为此显示黄色横幅。我再次点击“拍照”,系统提示我撤销的权限。刚刚在运行 6.0 的 Nexus 5 上进行了测试。
  • 很高兴知道,那可能是用户错误,我会继续挖掘。
  • 美好的一天。我也有同样的问题。关键是我的应用程序的目标 SDK 不是 23(Marshmallow)而是 22(Lolipop)。我在带有 android 6.0 的 Nexus 5 上运行我的应用程序。我去设置,我禁用我的应用程序的一些权限。当我返回我的应用程序并调用 ContextCompat.checkSelfPermission() 以获得我的许可时,结果是 PERMISSION_GRANTED。问题是如果应用程序以 android 5.1 lolipop api 为目标,如何检测到 android 6.0 设备上的应用程序的权限被撤销
  • 你不应该这样做,因为你的应用在 22 中,应用权限是默认授予的。

标签: android permissions android-6.0-marshmallow


【解决方案1】:

我参加聚会有点晚了,但我只是遇到了这个问题,并认为将来应该对其他人有用。

根据谷歌链接https://developers.google.com/android/guides/permissions#prerequisites

除了新的平台功能外,Android 6.0 Marshmallow 还具有新的 简化应用安装和自动更新的权限模型 过程。现在在运行时而不是之前请求权限 应用安装。

因此,如果您将应用定位到 SDK 级别 23 或更高级别,则在 AndroidManifest.xml 中声明的权限是不够的(尽管有必要)。确保您使用的是 V4 支持库并按如下所示进行检查:

@Override
    public void onClick(View view) {

        // Check permission for CAMERA
        if (ActivityCompat.checkSelfPermission(context, Manifest.permission.CAMERA)
                != PackageManager.PERMISSION_GRANTED) {
            // Check Permissions Now
            // Callback onRequestPermissionsResult interceptado na Activity MainActivity
            ActivityCompat.requestPermissions(getActivity(),
                                              new String[]{Manifest.permission.CAMERA},
                                              MainActivity.REQUEST_CAMERA);
        } else {
            // permission has been granted, continue as usual

            Intent captureIntent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
            startActivityForResult(captureIntent, 0);
        }

就我而言,我在Fragment 上进行了检查,但可以在Activity 上进行检查,这取决于您的需求。

用户可以通过进入设置>应用>你的应用授予应用权限,然后授予权限。在这种情况下,逻辑通过else 并调用意图。 另一方面,生活并不那么容易,用户不会那样做。因此我们必须调用 ActivityCompat.requestPermissions:

ActivityCompat.requestPermissions(getActivity(),
                                              new String[]{Manifest.permission.CAMERA},
                                              MainActivity.REQUEST_CAMERA);

在第一个参数中我传递了getActivity(),因为我使用的是Fragment。如果您使用Activity,请传递this。第二个参数是要检查的权限,第三个参数是应用程序定义的int常量,用作回调方法的标识符,我将在后面解释。

public static final int REQUEST_CAMERA = 1;

ActivityCompat.requestPermissions 将打开一个对话框,要求用户授予或拒绝权限。这就是为什么我们必须使用onRequestPermissionsResult的方法:

@Override
    public void onRequestPermissionsResult(int requestCode,
                                           String permissions[], int[] grantResults) {
        switch (requestCode) {
            case REQUEST_CAMERA: {
                // 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.
                    Toast.makeText(getApplicationContext(), "Permission granted", Toast.LENGTH_SHORT).show();
                } else {

                    // permission denied, boo! Disable the
                    // functionality that depends on this permission.
                    Toast.makeText(getApplicationContext(), "Permission denied", Toast.LENGTH_SHORT).show();
                }
                return;
            }

            // other 'case' lines to check for other
            // permissions this app might request
        }
    }

如果你像我一样使用Fragment,这个回调方法必须在包含Fragment的Activity中。

【讨论】:

  • 我在Manifest.permission.CAMERA 中的CAMERA 上收到红色文字
【解决方案2】:

事实证明这是逻辑中的程序员错误。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-10-07
    • 2015-01-13
    • 1970-01-01
    • 2012-01-23
    • 2013-02-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多