Android权限请求

之前,我们队需要的请求,都不过是在manifest里声明。后来有了运行时权限请求,本来就对权限不太熟,很多都是自顾自的加上去,让程序能跑就好,但有时候,看见国外的程序,那些个简洁的权限列表,就又觉得自己太随意了。之前也有过权限的请求经历,但是都是search->copy->debug,为什么都没有搞得很清楚,反正最终目的不就是run起来么。不过,现在我希望,稍微清楚一些,而不是稀里糊涂的了。

划时代:

在Android 5.1.1(API22)及以前,都是install_time permission request,但是,在Android 6.0(API23)以以后版本,都会是runtime permission request,意味着需要某个危险权限时需要在代码里去检查是否已经granted了。

区别permission和hardware features:

首先,他们都是定义在manifest里,和<application>同级

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
          package="com.example.snazzyapp">

    <uses-permission android:name="android.permission.CAMERA"/>
    <uses-feature android:name="android.hardware.camera" android:required="false" />

    <application ...>
        ...
    </application>
</manifest>

根据官方文档,是如果没有uses-feature,则默认认为应用必须需要有这个功能,如果没有,则Google Play不会安装该应用到手机上。否则,像代码里在uses-feature的android:required="false"则可以认为这个功能不必须,则可以安装。当然,对应的在代码里就要检查了。

权限分类:

权限官方分为3+1类:普通,签名,危险 和 特殊权限。普通->系统可以自动授权,危险->需要询问用户。签名->系统应用(具有系统签名)才可以获取得到。不过官方也说了,这不会影响APP的安装,但是实际上你就是获取不到。特殊权限主要是SYSTEM_ALTER_WINDOW和WRITE_SETTINGS,需要去请求。

还有就是,自API-23 后,有了权限组的概念,但是个人认为,既然官方说了分组可能会变,不要依赖这种机制,所以,我觉得他的存在只是让我们能够理解这种行为而已,于开发者而言似乎没有什么用。

国内情况:

由于我国的rom大多是深度定制,很多都有自己的权限管理机制。所以,个人觉得不要太相信申请权限后返回的结果,还是要自己去检查是否有这个权限。

请求权限:

当要适配API level 23 及以上时,需要在代码中处理权限的动态申请。根据官方文档,如果有适配低版本的要求,使用support库就很方便了。

流程:

  1. 检查权限
  2. 是否需要解释,是->解释
  3. 申请权限
  4. 结果回调处理
// Here, thisActivity is the current activity
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_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_READ_CONTACTS: {
            // 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
    }
}
上面两段都是直接copy官网上的例子,足够清晰明了的了。 官网链接

题外话:

相信很多时候我们处理业务都没有在activity里,但是这个权限请求又非得在activity里,而且结果的回调得让activity来重写处理。这让很多人在拥有架构的时候有点烦。对于在fragment里,activity可以直接getActivity(),但是结果还是没办法获取得到。其实这种情况很多时候都有遇到。我基本上是通过interface,listener这样的方式来将业务代码传进activity里,也没想到什么好的解决办法,看网上的例子,不如自己写写。

小结:

在Android6.0(API level 23)及以后,使用危险权限要动态申请。在之前版本,权限在安装时则已经全部granted了。

其实,在国内的rom,早就有权限控制了,不过是在系统级别的控制,至于它是如何与应用交互的,个人觉得是欺骗,事实就是用不了,又不告诉你用不了,哈哈哈哈。


猜你喜欢

转载自blog.csdn.net/zyssky465/article/details/79973017