这篇博客的代码是看了郭神的视频后,整合知识点得出的。
郭神视频录播地址:http://edu.csdn.net/course/detail/3539
关于运行时权限的特点:
- APP从低于6.0的版本升级上来时,原来拥有的权限默认允许。也就是说不用重新申请权限。
- APP的targetSdkVersion版本低于6.0时,也不用获取运行时权限。
话不多说,马上来封装起来。
1.先建一个接口,用于监听用户是否允许我们所申请的权限
/**
* 运行时权限接口
*/
public interface RuntimePermissionListener {
/**
* 允许所请求的全部权限
*/
void onRuntimePermissionGranted();
/**
* 拒绝所请求的部分或全部权限
*/
void onRuntimePermissionDenied(List<String> deniedPermission);
}
2.建一个ActivityCollector类。因为在申请权限的时候需要一个Activity对象,利用ActivityCollector类,每次获取栈顶的Activity传参进去,这样,即使不在Activity里面也可以调用申请对象的方法。这样还有应该好处就是,栈顶的Activity的优先级最高,不容易被系统回收。
/**
* Activity 栈
*/
public class ActivityCollector {
private static List<Activity> activityList = new ArrayList<>();
public static void addActivity(Activity activity){
activityList.add(activity);
}
public static void removeActivity(Activity activity){
activityList.remove(activity);
}
public static Activity getTopActivity(){
if(activityList.isEmpty()){
return null;
}else {
return activityList.get(activityList.size() - 1);
}
}
}
3.建一个BaseActivity。让BaseActivity继承Activity,这样的好处是对项目的扩展性较高。
public class BaseActivity extends AppCompatActivity {
private static final int RUNTIME_PERMISSION_REQUEST_CODE = 1;
private static RuntimePermissionListener mRuntimePermissionListener;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_base);
ActivityCollector.addActivity(this);//进栈
}
@Override
protected void onDestroy() {
super.onDestroy();
ActivityCollector.removeActivity(this);//出栈
}
public static void requestPermission(String[] permissions, RuntimePermissionListener listener){
Activity topActivity = ActivityCollector.getTopActivity();
if(topActivity == null){//如果连栈顶Activity都没有,也就没必要申请权限了
return;
}
mRuntimePermissionListener = listener;
List<String> deniedPermissionList = new ArrayList<>();
for (String permission : permissions){
if(ContextCompat.checkSelfPermission(topActivity,permission) != PackageManager.PERMISSION_GRANTED){
deniedPermissionList.add(permission);
}
}
if(deniedPermissionList.isEmpty()){
//权限全部允许
mRuntimePermissionListener.onRuntimePermissionGranted();
}else {
//权限没有被全部允许
String[] deniedPermissionArray = deniedPermissionList.toArray(new String[deniedPermissionList.size()]);
//请求未被允许的权限
ActivityCompat.requestPermissions(topActivity,deniedPermissionArray,RUNTIME_PERMISSION_REQUEST_CODE);
}
}
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
switch (requestCode){
case RUNTIME_PERMISSION_REQUEST_CODE:
if(grantResults.length > 0){
List<String> deniedPermissions = new ArrayList<>();
for (int i = 0; i < grantResults.length; i++){
int grantResult = grantResults[i];
String permission = permissions[i];
if(grantResult != PackageManager.PERMISSION_GRANTED){
deniedPermissions.add(permission);
}
}
if(deniedPermissions.isEmpty()){
//允许所请求的全部权限
mRuntimePermissionListener.onRuntimePermissionGranted();
}else {
//拒绝所请求的部分或全部权限
mRuntimePermissionListener.onRuntimePermissionDenied(deniedPermissions);
}
}
break;
default:
break;
}
}
}
4.测试一下。无论是否在Activity里面,都可以申请权限。
public void test_click(View v){
BaseActivity.requestPermission(new String[]{Manifest.permission.CALL_PHONE,Manifest.permission.CAMERA}, new RuntimePermissionListener() {
@Override
public void onRuntimePermissionGranted() {
Toast.makeText(MainActivity.this,"都允许了",Toast.LENGTH_SHORT).show();
}
@Override
public void onRuntimePermissionDenied(List<String> deniedPermission) {
for(String permission :deniedPermission){
Toast.makeText(MainActivity.this,"被拒绝了" + permission,Toast.LENGTH_SHORT).show();
}
}
});
}
如此一来,便大功告成。