Android:检查是否需要请求运行时权限

3

我希望检查特定的应用程序是否需要在运行时处理Android Marshmallow运行时权限。

以下假设是否正确?

/**
 * Checks whether runtime permissions must be handled or not.
 *
 * @param context Application context.
 * @return Handle runtime permissions or not.
 */
public static boolean shouldCheckRuntimePermissions(Context context) {
    return
            isApplicationWithMarshmallowTargetSdkVersion(context) &&
                    Build.VERSION.SDK_INT >= Build.VERSION_CODES.M;
}

/**
 * Checks whether the app is compiled with targetSdkVersion Marshmallow or above.
 *
 * @param context Application context.
 * @return Application targetSdkVersion above 23 or not.
 */
public static boolean isApplicationWithMarshmallowTargetSdkVersion(Context context) {
    return
            context.getApplicationInfo().targetSdkVersion >= Build.VERSION_CODES.M;
}

这是我精心制作的表格,例如在使用Android Marshmallow运行时权限时需要向用户请求ACCESS_COARSE_LOCATION权限。

====================
target SDK |<23| 23|
====================
       |<23| X | X |
       ------------| 
OS SDK |23 | X | V |
====================   

我知道有Support库辅助工具的存在,但我希望在这种情况下避免使用它们。


1
我认为你只需要检查构建SDK版本,因为目标版本仅表示您在开发时瞄准的SDK。 - Luis Miguel Sierra
@LuisMiguelSierra 我不这么认为,如果你使用targetSDK 23和OS SDK 22运行应用程序,则无需请求运行时权限。至少我已经测试过危险的COARSE_LOCATION。 - GoRoS
你的假设听起来不错。它是否正常工作? - Marcin Koziński
1
@GoRoS 是的,你说得对。这里解释了目标SDK、构建SDK和运行时权限之间的关系。https://developer.android.com/training/permissions/requesting.html - Luis Miguel Sierra
@LuisMiguelSierra 你说得对,我已经添加了一个答案来帮助其他有同样问题/疑问的人。谢谢! - GoRoS
1
如果你考虑到Android支持那些没有实现运行时权限的旧应用,这对我来说是有道理的。我只是没有想到。点赞,很好,我们现在清楚了。 - Luis Miguel Sierra
3个回答

3
@LuisMiguelSierra是对的,我在我的问题结尾处贴的链接中已经有了答案,但我完全没有意识到。以下是解答我的问题并确认我的做法和方法正确的引用:在所有Android版本上,您的应用程序都需要在其应用程序清单中声明需要的普通和危险权限,如“声明权限”中所述。然而,该声明的效果取决于系统版本和您的应用程序的目标SDK级别:
如果设备运行Android 5.1或更低版本,或者您的应用程序的目标SDK为22或更低版本:如果您在清单中列出一个危险权限,则用户必须在安装应用程序时授予权限;如果他们不授予权限,则系统根本不会安装应用程序。
如果设备运行Android 6.0或更高版本,并且您的应用程序的目标SDK为23或更高版本:应用程序必须在清单中列出权限,并且在应用程序运行时必须请求每个危险权限。用户可以授予或拒绝每个权限请求,即使用户拒绝权限请求,应用程序也可以继续以有限的能力运行。
因此,关于何时请求权限的这种假设得到了确认。
====================
target SDK |<23| 23|
====================
       |<23| X | X |
       ------------| 
OS SDK |23 | X | V |
====================

1

如果您的活动检查到API版本>= 23且权限被拒绝,则请求该权限。

if (android.os.Build.VERSION.SDK_INT >= 23 && ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) == PackageManager.PERMISSION_DENIED) {
        requestPermissions(new String[]{Manifest.permission.ACCESS_COARSE_LOCATION}, REQUEST_LOCATION_PERMISSION);
}

而要从用户那里获取结果,只需覆盖即可

 @Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
    switch (requestCode) {
        case REQUEST_LOCATION_PERMISSION:
             if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                    Log.d(TAG,"Premission granted");
             }else {
                    Log.d(TAG,"Premission denied");
             }
             break;
    }
}

嗨,Abanoub,1)我不想知道如何请求运行时权限,因为我已经发布了2)请阅读我最后一句话,我说我不想使用支持库。 - GoRoS

0
你可以尝试使用来自Google Samples的EasyPermissions库。它处理与权限相关的检查,您无需担心版本检查。

嗨jaibatrik,谢谢回答。我已经知道这个示例,但我只是想理解“何时询问”的逻辑,而不是“如何询问”,以及我的假设是否正确。 - GoRoS
如果SDK版本低于M,您无需检查权限,只需在清单中声明即可。如果它等于或大于M,请使用Context#checkPermission检查权限。如果没有权限,请请求权限。 - jaibatrik

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接