Android 6.0 动态权限申请简单简洁优雅的处理方式

Android M 或以上的设备,在使用涉及隐私的安全权限时,需要动态申请,虽然不难,但写下来代码工作量也不少,而且几乎每个应用都需要用到。所以一直在探索一个要足够简单简洁优雅的处理方式,强迫症的精神指导我要拒绝一切繁琐。至于完不完美那就仁者见仁了。

一、思路:

如果在每个用到权限的地方去申请,有点繁琐,所以做法是直接在每个Activity界面显示前就把该界面所需的权限全部申请允许了,再进入正常的流程。如果有权限未被允许,开发者可以在接口中自己处理,可以直接提示并退出,或者提示权限的作用后重新发起权限申请。

二、危险权限列表:Dangerous Permissions

在Android M 或以上,以下权限需要动态申请的意思。

group:android.permission-group.CONTACTS
  permission:android.permission.WRITE_CONTACTS
  permission:android.permission.GET_ACCOUNTS
  permission:android.permission.READ_CONTACTS

group:android.permission-group.PHONE
  permission:android.permission.READ_CALL_LOG
  permission:android.permission.READ_PHONE_STATE
  permission:android.permission.CALL_PHONE
  permission:android.permission.WRITE_CALL_LOG
  permission:android.permission.USE_SIP
  permission:android.permission.PROCESS_OUTGOING_CALLS
  permission:com.android.voicemail.permission.ADD_VOICEMAIL

group:android.permission-group.CALENDAR
  permission:android.permission.READ_CALENDAR
  permission:android.permission.WRITE_CALENDAR

group:android.permission-group.CAMERA
  permission:android.permission.CAMERA

group:android.permission-group.SENSORS
  permission:android.permission.BODY_SENSORS

group:android.permission-group.LOCATION
  permission:android.permission.ACCESS_FINE_LOCATION
  permission:android.permission.ACCESS_COARSE_LOCATION

group:android.permission-group.STORAGE
  permission:android.permission.READ_EXTERNAL_STORAGE
  permission:android.permission.WRITE_EXTERNAL_STORAGE

group:android.permission-group.MICROPHONE
  permission:android.permission.RECORD_AUDIO

group:android.permission-group.SMS
  permission:android.permission.READ_SMS
  permission:android.permission.RECEIVE_WAP_PUSH
  permission:android.permission.RECEIVE_MMS
  permission:android.permission.RECEIVE_SMS
  permission:android.permission.SEND_SMS
  permission:android.permission.READ_CELL_BROADCASTS

三、使用方式:

先从Activity的使用开始。

public class MainActivity extends AppCompatActivity implements PermissionInterface {

    private PermissionHelper mPermissionHelper;

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

		//初始化并发起权限申请
        mPermissionHelper = new PermissionHelper(this, this);
        mPermissionHelper.requestPermissions();
    }

    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        if(mPermissionHelper.requestPermissionsResult(requestCode, permissions, grantResults)){
			//权限请求结果,并已经处理了该回调
            return;
        }
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
    }

    @Override
    public int getPermissionsRequestCode() {
		//设置权限请求requestCode,只有不跟onRequestPermissionsResult方法中的其他请求码冲突即可。
        return 10000;
    }

    @Override
    public String[] getPermissions() {
		//设置该界面所需的全部权限
        return new String[]{
                Manifest.permission.WRITE_EXTERNAL_STORAGE,
                Manifest.permission.READ_PHONE_STATE
        };
    }

    @Override
    public void requestPermissionsSuccess() {
		//权限请求用户已经全部允许
        initViews();
    }

    @Override
    public void requestPermissionsFail() {
        //权限请求不被用户允许。可以提示并退出或者提示权限的用途并重新发起权限申请。
        finish();
    }
    
    private void initViews(){
        //已经拥有所需权限,可以放心操作任何东西了
		
    }

}

四、其中使用到的两个类和一个接口实现:

1、Activity需要实现的接口PermissionInterface.java

/**
 * 权限请求接口
 * Created by dway on 2018/1/10.
 */
public interface PermissionInterface {

    /**
     * 可设置请求权限请求码
     */
    int getPermissionsRequestCode();

    /**
     * 设置需要请求的权限
     */
    String[] getPermissions();

    /**
     * 请求权限成功回调
     */
    void requestPermissionsSuccess();

    /**
     * 请求权限失败回调
     */
    void requestPermissionsFail();

}

2、工具类PermissionUtil.java

/**
 * 动态权限工具类
 * Created by dway on 2017/1/13.
 */
public class PermissionUtil {

    /**
     * 判断是否有某个权限
     * @param context
     * @param permission
     * @return
     */
    public static boolean hasPermission(Context context, String permission){
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            if(context.checkSelfPermission(permission)  != PackageManager.PERMISSION_GRANTED){
                return false;
            }
        }
        return true;
    }

    /**
     * 弹出对话框请求权限
     * @param activity
     * @param permissions
     * @param requestCode
     */
    public static void requestPermissions(Activity activity, String[] permissions, int requestCode){
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            activity.requestPermissions(permissions, requestCode);
        }
    }

    /**
     * 返回缺失的权限
     * @param context
     * @param permissions
     * @return 返回缺少的权限,null 意味着没有缺少权限
     */
    public static String[] getDeniedPermissions(Context context, String[] permissions){
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            ArrayList<String> deniedPermissionList = new ArrayList<>();
            for(String permission : permissions){
                if(context.checkSelfPermission(permission) != PackageManager.PERMISSION_GRANTED){
                    deniedPermissionList.add(permission);
                }
            }
            int size = deniedPermissionList.size();
            if(size > 0){
                return deniedPermissionList.toArray(new String[deniedPermissionList.size()]);
            }
        }
        return null;
    }

}

3、权限操作帮助类PermissionHelper.java

package com.dway.permission;

import android.app.Activity;
import android.content.pm.PackageManager;
import android.support.annotation.NonNull;

/**
 * 动态权限帮助类
 * Created by dway on 2018/1/10.
 */
public class PermissionHelper {

    private Activity mActivity;
    private PermissionInterface mPermissionInterface;

    public PermissionHelper(@NonNull Activity activity, @NonNull PermissionInterface permissionInterface) {
        mActivity = activity;
        mPermissionInterface = permissionInterface;
    }

    /**
     * 开始请求权限。
     * 方法内部已经对Android M 或以上版本进行了判断,外部使用不再需要重复判断。
     * 如果设备还不是M或以上版本,则也会回调到requestPermissionsSuccess方法。
     */
    public void requestPermissions(){
        String[] deniedPermissions = PermissionUtil.getDeniedPermissions(mActivity, mPermissionInterface.getPermissions());
        if(deniedPermissions != null && deniedPermissions.length > 0){
            PermissionUtil.requestPermissions(mActivity, deniedPermissions, mPermissionInterface.getPermissionsRequestCode());
        }else{
            mPermissionInterface.requestPermissionsSuccess();
        }
    }

    /**
     * 在Activity中的onRequestPermissionsResult中调用
     * @param requestCode
     * @param permissions
     * @param grantResults
     * @return true 代表对该requestCode感兴趣,并已经处理掉了。false 对该requestCode不感兴趣,不处理。
     */
    public boolean requestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults){
        if(requestCode == mPermissionInterface.getPermissionsRequestCode()){
            boolean isAllGranted = true;//是否全部权限已授权
            for(int result : grantResults){
                if(result == PackageManager.PERMISSION_DENIED){
                    isAllGranted = false;
                    break;
                }
            }
            if(isAllGranted){
                //已全部授权
                mPermissionInterface.requestPermissionsSuccess();
            }else{
                //权限有缺失
                mPermissionInterface.requestPermissionsFail();
            }
            return true;
        }
        return false;
    }
    
}

OK,完成。哪个Activity需要权限就实现接口,其他用帮助类就全部搞定。

另外,悬浮窗权限的处理特殊一点,需要跳转设置界面开启。

<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && !Settings.canDrawOverlays(this)) {
            //没有悬浮窗权限,跳转申请
            val intent = Intent(
                Settings.ACTION_MANAGE_OVERLAY_PERMISSION,
                Uri.parse("package:$packageName")
            )
            startActivity(intent)
        }

转载请注明来源:http://blog.csdn.net/lin_dianwei/article/details/79025324

  • 21
    点赞
  • 94
    收藏
    觉得还不错? 一键收藏
  • 38
    评论
### 回答1: OPPO R9的Android 6.版本是一款非常流畅的操作系统,具有更好的性能和更多的功能。它提供了更好的多任务处理能力,更好的电池寿命和更好的安全性能。此外,它还提供了更好的用户体验,使用户可以更轻松地使用手机。总的来说,OPPO R9的Android 6.版本是一款非常出色的操作系统,值得用户使用。 ### 回答2: OPPO R9是一款搭载Android 6.0(Marshmallow)操作系统的手机,该系统带来了诸多新功能,使手机更加易用、稳定和安全。 Android 6.0的最大特点是Doze模式,能够在手机处于静止状态时减少耗电和网络流量。当你将手机放置一段时间后,这种模式就会被启动,手机会进入深度休眠状态,而只在接收到紧急通知时才会唤醒。另外,6.0还引入了应用权限的精细化控制,让用户能够更好地管理和控制自己的手机。 此外,6.0还带来了更灵活的通知管理,在锁屏和主屏幕上都可以查看通知,而且用户还可以自定义通知的优先级和提示方式。另外,6.0还优化了文件管理器和存储空间的管理,更方便用户管理和清理垃圾文件。 总之,OPPO R9搭载的Android 6.0系统功能更加全面,优化了电池续航表现和通知管理,提升了用户体验和安全性,是一款十分优秀的手机系统。 ### 回答3: oppo r9是OPPO手机品牌推出的一款手机,其所搭载的操作系统是Android6.0版本。Android 6.0版本是Android系统中重要的一个版本,它发行于2015年,代号为“Marshmallow”,这个版本有着很多的新增特性和改进的地方,其中最重要的一点是在安全方面做了大量的优化,保证了手机用户的数据隐私和手机安全,同时优化了电池续航能力,优化了声音效果和触摸体验等,提高了系统的稳定性和流畅度。 在OPPO R9中搭载Android 6.0版本后,它不仅保留了Android系统本身的优势,还结合了OPPO自身手机的特点进行了优化。例如OPPO R9搭载了自家的ColorOS 3.0系统,其UI界面设计简洁美观,搭载了丰富实用的智能功能和个性化定制设置,让用户拥有更加个性化的手机体验。 此外,OPPO R9作为一款音乐手机,其在音乐体验上也进行了优化,在系统层面对音质进行了优化,让人们在听歌时拥有更加流畅舒适的体验。 总之,OPPO R9搭载了Android 6.0版本的操作系统,该版本不仅优化了手机的安全性和电池续航能力,并且还融合了OPPO R9手机的特点进行了优化,从而提供了更好的用户体验。
评论 38
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值