安卓不同版本运行时权限(Runtime Permission )表现可能会不同,
为了安全,目前大部分安卓版本某些敏感权限比如:录音,摄像头,发送短信等都,APP调用前都需要先申请对应权限,用户选择“同意”则可正常使用否则对应功能将不能使用。
CTA认证要求低版本的如Android5的apk必须要支持运行时权限,但是其功能是Android6才引入的,需要对Runtime Permission不同版本的表现有个初步认识,好方便针对CTA要求进行修改。

Android5及以下版本

无运行时权限功能,无需在代码中申请权限就可调用,应用安装后会自动获得权限。

安卓5(Lollipop, 21)及以下没有此功能
其可以直接代码中打开摄像头, 创建一个叫TestM的工程,用于测试,
第一步需要声明要求的摄像头权限
AndroidManifest.xml

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

这个不管哪个版本都需要加,不然无法获取到权限。

第二步app build.gradle中对应如下
targetSdk 21
对应是要求代码运行在android5上。

    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        textView = (TextView) findViewById(R.id.result);
         startCamera(); // 可直接打开摄像头

可在 设置—应用和通知—TestM—权限中查看是否获得权限
android5应用安装后,自动获得权限。
如图1
在这里插入图片描述

安卓6.0引入的运行时权限(runtime permission)功能

敏感权限需要代码申请,如未申请到则无法使用
比如摄像头示例
第一步需要声明要求的摄像头权限
AndroidManifest.xml

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

注意如果xml中不添加这行代码,则代码requestPermissions
请求权限时不会弹出权限授权选择框。如果不请求权限直接尝试打开摄像头会失败,错误打印:cannot open camera “1” without camera permission’。

第二步
app的build.gradle需要配置好sdk版本号,其中
targetSdk需要大于等于23, 23对应Android6.0,表示要运行在6.0系统中,则代码会以6.0版本的sdk进行编译生成apk
compileSdk目前的android studio2021只能设置最小值为28,若设置为23会各种编译不过,因为找不到对应的 appcompat版本,比如
28对应的能下载到
implementation ‘com.android.support:appcompat-v7:28.0.0’
而23对应的会下载不到
implementation ‘com.android.support:appcompat-v7:23.0.0’

android {
    compileSdk 28
    defaultConfig {
        minSdk 19
        targetSdk 23

第三步代码中申请摄像头权限,之前申请成功或者此次申请成功则可打开摄像头
主要是先 checkSelfPermission,如果之前未授权过则调用requestPermissions请求授权。
若不请求权限直接打开摄像头则会失败。

public class MainActivity extends AppCompatActivity {
    private static final String TAG = "MainActivity";
    private static final int FRONT_CAMERA = 1;
    private static final int MY_PERMISSIONS_REQUEST = 1000;
    Camera mCamera = null;
    TextView textView;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        textView = (TextView) findViewById(R.id.result);
      getPermissionInfo(); // 如果是6以上版本执行此句
      //startCamera(); // 5及以下版本执行此句
    @Override
    protected void onDestroy() {
        super.onDestroy();
        if (mCamera != null)
            mCamera.release();
    private void getPermissionInfo() {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { // M为23,  表示版本6.0及以上
            if (ContextCompat.checkSelfPermission(this, Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) {
                //版本大于等于6.0的版本,未授权则动态请求授权
                ActivityCompat.requestPermissions(this, new String[] {Manifest.permission.CAMERA }, MY_PERMISSIONS_REQUEST);
                return;
            } else {
                // PERMISSION_GRANTED  表示已经授权并可以使用
                startCamera();
        } else {//Android6.0以前的版本,可以直接使用
            Log.d("",  "6.0以前的版本");
            startCamera();
    private void startCamera() {
        try {
            mCamera = Camera.open(FRONT_CAMERA);
            Log.d(TAG, "open success");
            textView.setText("open camera success");
        } catch (RuntimeException e) {
            Log.e(TAG, "fail to open camera");
            e.printStackTrace();
            mCamera = null;
            textView.setText("open camera failed");
    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
       // 通过回调,监听用户是否授权
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        switch (requestCode) {
            case MY_PERMISSIONS_REQUEST: {
                if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                    // 授权成功
                    startCamera();
                } else {
                    // 授权失败!
                    Toast.makeText(this, "授权失败", Toast.LENGTH_SHORT);
                break;
            default:
                break;

Android6及以上版本,代码中请求权限时,会弹出一个是否允许的选择框,
在这里插入图片描述
选中“允许”则获得权限,并可打开摄像头,设置中权限情况如图1;
选中“拒绝”,则无法获得权限,摄像头无法正常打开,
如图3
在这里插入图片描述
CTA部分需要针对Android SDK进行修改,使其对Android5的apk也能支持运行时权限,此处不详述。
作者:帅得不敢出门 谢绝转载

    之前的文章中,我们分析了Android的AppOps权限管理机制。( http://blog.csdn.net/hyhyl1990/article/details/46842915 )     可以说,该机制一直都在(应该是从4.2就开始存在了),但一直没有被真正使用过… 每次Android更新OS版本,都一直是隐藏它的( 一些OEM厂商可能会在某些版本上打开)。
android权限问题一直被用户所诟病,终于google在android M上加入了运行时权限RuntimePermission)。对我们的应用有什么影响呢android M以下(api level<23)仍然是在安装时申请权限,也就是没影响,之前的应用仍然按照之前的逻辑在android M上运行。 android M以上(api level>=23),就需要声请权限啦,开发应用的时候就需要注意啦
shell@zenltevzw:/ $ pm list permissions -d -g Dangerous Permissions: group:android.permission-group.LGT_C 《Android学习笔记总结+最新移动架构视频+大厂安卓面试真题+项目实战源码讲义》 【docs.qq.com/doc/DSkNLaERkbnFoS0ZF】 完整内容开源分享 ONTENT group:com.sec.enterprise.permi
Android RuntimePermissions Sample This sample shows runtime permissions available in Android M and above. It shows how to check and request permissions at runtime, handle backwards compatibility using the support library and how to declare optional permissions for M-devices only. Introduction Android M introduced runtime permissions. Applications targeting M and above need to request their permissions at runtime. All permissions still need to be declared in the AndroidManifest. However, when acc
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.example.criminalintent"> <uses-permissi...  targetSdkVersion 23 开始 使用运行时权限,就像iphone谈框,不能简单的和以前一样 在配置文件写明权限,需要用代码判断。所以为了防止此问题发生 请不要设置targetSdkVersion 23,应该比他小,不然需要代码判断。 目前不属于运行时权限的有 android.permission.ACCESS_LOCATION_EXTRA_COMMANDS androi... 在Android 6.0 之前权限管理存在一些弊端: 权限系统只会在安装的时候询问一次,用户可以选择性的授予应用相关权限。但是一旦安装了,应用软件会在用户毫不知情的情况下访问权限内的所有东西。 在Android 6.0 之前权限都称为install time permission,应用软件在安装以后用户不能修改permission 的授权情况,也不允许对permission 进行单独...