Android运行时权限

2018-03-26  本文已影响0人  francis_fanfan

android 6.0运行时权限

Android 中的权限在6.0(API23)之前一直是在安装应用的时候一次性授予的,要不不安装此软件,要么接受此软件申请的所有权限。6.0之后,Google更改了权限的授予方式,用户在安装时可以选择授予或者不授予应用申请的权限,到需要使用此权限的时候再去向用户申请。

权限的两种类型

[图片上传失败...(image-3b9dab-1522052782236)]

接下来我们来说说怎么申请运行时权限

1. 先说说几个系统api

  1. checkSelfPermission

    检查是否授予了某一项权限,
    如果权限已经授予,返回0,否则返回-1
    Determine whether you have been granted a particular permission.

  2. shouldShowRequestPermissionRationale

    当你没有某个权限的时候,你最好显示一个UI组件,告诉用户这个应用为什么需要这个权限,告诉用户如果授予该权限会有带来什么好处,
    如果您的权限请求已经被拒绝过一次,返回true,否则返回false
    Gets whether you should show UI with rationale for requesting a permission. You should do this only if you do not have the permission and the context in which the permission is requested does not clearly communicate to the user what would be the benefit from granting this permission.

  3. requestPermissions

    当检查到用户没有授予某项你需要的危险权限的时候,向用户申请该权限
    Requests permissions to be granted to this application. These permissions must be requested in your manifest

  4. onRequestPermissionsResult

    这是 requestPermissions 方法的回调,每次调用requestPermissions都会有一次回调
    Callback for the result from requesting permissions. This method is invoked for every call on requestPermissions(String[], int).

2. 再说说怎么用

这里面有一个坑很多文章都没有讲明白,我也是在项目中遇到了才把这个问题给搞清楚了的。大多数文章的示例都是以Activity为背景讲的,像我这种刚接触运行时权限的菜鸟而言,当然就是copy下别人的用法喽,一不小心就掉进了坑里。
这个坑就是onRequestPermissionsResult方法根本没被调用。帅哥们看这里!

敲黑板划重点:

上面我们说的四个系统api中的后面三个方法其实是有两套的,Activity使用一套, Fragment要使用另外一套!在Activity中使用ActivityCompat.requestPermissions,在Fragment中使用requestPermissions

3. Talk is simple , show u the code!

我们来看示例代码:

看看Fragment怎么用

1.检查权限

if (ContextCompat.checkSelfPermission(mContext, Manifest.permission.CALL_PHONE)
         == PackageManager.PERMISSION_GRANTED) {
    //已经授权,
}else{
    //没有权限
}

2.显示原因

if(shouldShowRequestPermissionRationale(Manifest.permission.CALL_PHONE){
    //如果需要显示请求权限的原因 在这里写        
} else {
    //请求权限                  
}

3.请求权限

requestPermissions(new String[]{Manifest.permission.CALL_PHONE},1);

4.处理回调

@Override
public void onRequestPermissionsResult(int requestCode,String permissions[], int[] grantResults) {
    super.onRequestPermissionsResult(requestCode, permissions, grantResults);
}

一个完整的Fragment:

package com.example.francis.demo.simpletest;

import android.Manifest;
import android.content.pm.PackageManager;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.support.v4.content.ContextCompat;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

import com.example.francis.demo.R;

public class RuntimePermissionFragment extends Fragment {
    private final int REQUEST_CODE_CALL_PHONE = 1;

    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        super.onCreateView(inflater, container, savedInstanceState);
        View view = inflater.inflate(R.layout.fragment_runtime_permission, container, false);
        view.findViewById(R.id.call_button).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (ContextCompat.checkSelfPermission(getActivity(), Manifest.permission.CALL_PHONE) == PackageManager.PERMISSION_GRANTED) {
                    //打电话逻辑在哪里写
                } else {
                    if (shouldShowRequestPermissionRationale(Manifest.permission.CALL_PHONE)) {
                        //展示你给用户的解释,这不是必须的,如果你觉得不需要或者你不想解释,那就不要解释了 
                    } else {
                        requestPermissions(new String[]{Manifest.permission.CALL_PHONE}, REQUEST_CODE_CALL_PHONE);
                    }
                }
            }
        });
        return view;
    }

    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        if (requestCode == REQUEST_CODE_CALL_PHONE) {
            if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                //打电话权限被授予
                //打电话逻辑写这里
            } else {
                //用户拒绝了你的打电话权限
            }
        }
    }
}

看看Activity怎么用

1.检查权限

if (ContextCompat.checkSelfPermission(mContext, Manifest.permission.CALL_PHONE)
         == PackageManager.PERMISSION_GRANTED) {
    //已经授权,
}else{
    //没有权限
}

2.显示原因

if(ActivityCompat.shouldShowRequestPermissionRationale(Manifest.permission.CALL_PHONE){
    //如果需要显示请求权限的原因 在这里写        
} else {
    //请求权限                  
}

3.请求权限

ActivityCompat.requestPermissions(new String[]{Manifest.permission.CALL_PHONE},1);

4.处理回调

@Override
public void onRequestPermissionsResult(int requestCode,String permissions[], int[] grantResults) {
    super.onRequestPermissionsResult(requestCode, permissions, grantResults);
}

一个简单Activity示例

package com.example.francis.demo.simpletest;

import android.Manifest;
import android.content.Context;
import android.content.pm.PackageManager;
import android.support.annotation.NonNull;
import android.support.v4.app.ActivityCompat;
import android.support.v4.content.ContextCompat;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;

import com.example.francis.demo.R;

public class RuntimePermissionActivity extends AppCompatActivity {
    private final int REQUEST_CODE_CALL_PHONE = 1;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_runtime_permission);

        findViewById(R.id.call_button).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (ContextCompat.checkSelfPermission(RuntimePermissionActivity.this, Manifest.permission.CALL_PHONE) == PackageManager.PERMISSION_GRANTED) {
                    //打电话逻辑在哪里写
                } else {
                    if (ActivityCompat.shouldShowRequestPermissionRationale(RuntimePermissionActivity.this,Manifest.permission.CALL_PHONE)) {
                        //展示你给用户的解释,这不是必须的,如果你觉得不需要或者你不想解释,那就不要解释了
                    } else {
                        //请求权限
                        ActivityCompat.requestPermissions(RuntimePermissionActivity.this,new String[]{Manifest.permission.CALL_PHONE}, REQUEST_CODE_CALL_PHONE);
                    }
                }
            }
        });
    }
    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        if (requestCode == REQUEST_CODE_CALL_PHONE) {
            if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                //打电话权限被授予
                //打电话逻辑写这里
            } else {
                //用户拒绝了你的打电话权限
            }
        }
    }
}

小结

到了这里,运行时权限的申请流程和细节大家应该已经非常清楚了,接下来你需要做的就是自己写写看,看看源码介绍。虽然也有很多别人写好的很多库可以直接来调用,但是万变不离其宗,知道本质再去使用第三方库吧。
对了,别忘了在清单文件中声明这些危险权限哦😁...

上一篇 下一篇

猜你喜欢

热点阅读