Android动态权限获取(懒人自用)

  • Android动态权限
    • 动态预览
    • 使用权限情景:
    • 代码部分
    • 使用
    • 问题
    • 源码

Android动态权限

动态权限基本每个项目都用得到,懒得每次都写整理一下自己用,尽量少点copy(╯0╰)
不想漫天飞舞的引入别人的依赖,简单的事情尽量不要搞复杂,除非真的有必要。

动态预览

使用权限情景:

  1. App初始化时申请所有权限
  2. 部分涉及权限操作的地方,要检查权限是否可用

代码部分

1.工具类(PermissionManager.java)

package com.huan.squirrel.appermission.util;import android.Manifest;import android.annotation.TargetApi;import android.app.Activity;import android.app.AlertDialog;import android.app.ProgressDialog;import android.content.Context;import android.content.DialogInterface;import android.content.Intent;import android.content.pm.PackageManager;import android.net.Uri;import android.os.Build;import android.os.Handler;import android.provider.Settings;import android.support.annotation.RequiresApi;import android.support.v4.app.ActivityCompat;import android.support.v4.content.ContextCompat;import android.widget.Toast;import com.huan.squirrel.appermission.R;import static android.provider.Settings.ACTION_MANAGE_OVERLAY_PERMISSION;/** * 系统权限管理 * Created by huan on 2017/11/14. */public class PermissionManager {    private static int REQUEST_PERMISS_CODE = 3248;    //请求悬浮    public static int SYSTEM_ALERT_WINDOW_CODE = 11004;    private Activity context;    private static PermissionManager instance;    AlertDialog.Builder builder;    AlertDialog dialog;    public static PermissionManager getInstance(Activity context) {        if (instance == null) {            instance = new PermissionManager(context);        }        return instance;    }    public PermissionManager(Activity context) {        this.context = context;    }    //普通权限    private static String[] PERMISSIONS_ALL = {            Manifest.permission.READ_EXTERNAL_STORAGE,            Manifest.permission.WRITE_EXTERNAL_STORAGE};    //需要的特殊权限,需要进入设置页面才能授权的    private static String[] PERMISSIONS_SPE = {Manifest.permission.SYSTEM_ALERT_WINDOW, Manifest.permission.INSTALL_PACKAGES};    //初始化app所需的权限    public void initPermission() {        if (builder != null && dialog != null) {            dialog.dismiss();        }        if (getPermissionStatus2(context, PERMISSIONS_SPE)) {//初始化特殊权限            if (!getPermissionStatus(context, PERMISSIONS_ALL)) {//初始化普通权限                chekPermission(context, PERMISSIONS_ALL, new PermissionManager.OnCheckPermissionListener() {                    @Override                    public void onPassed() {                        //必须授权所有权限才能使用则,否则嵌套循环                        initPermission();                    }                    @Override                    public void onNoPassed() {                        //必须授权所有权限才能使用则,否则嵌套循环                        initPermission();                    }                });            }        }    }    //特殊权限弹窗后进入设置页面处理    public void showPermissionSettingDialog(final Context context, String permission) {        switch (permission) {            case Manifest.permission.INSTALL_PACKAGES:                //弹框提示用户手动打开                showAlert(context, "安装权限", "需要打开允许来自此来源,请去设置中开启此权限", new DialogInterface.OnClickListener() {                    @RequiresApi(api = Build.VERSION_CODES.O)                    @Override                    public void onClick(DialogInterface dialog, int which) {                        //此方法需要API>=26才能使用                        startInstallPermissionSettingActivity((Activity) context);                    }                });                break;            case Manifest.permission.SYSTEM_ALERT_WINDOW:                //弹框提示用户手动打开                showAlert(context, "悬浮窗权限", "需要打开在其他应用中显示", new DialogInterface.OnClickListener() {                    @RequiresApi(api = Build.VERSION_CODES.O)                    @Override                    public void onClick(DialogInterface dialog, int which) {                        //此方法需要API>=26才能使用                        getOverlayPermission((Activity) context);                    }                });                break;        }    }    //跳转到设置-请求悬浮窗权限    @TargetApi(Build.VERSION_CODES.M)    public void getOverlayPermission(Activity context) {        Intent intent = new Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION);        intent.setData(Uri.parse("package:" + context.getPackageName()));        //intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);        context.startActivityForResult(intent, SYSTEM_ALERT_WINDOW_CODE);    }    // 跳转到设置-允许安装未知来源-页面    @TargetApi(Build.VERSION_CODES.O)    public static void startInstallPermissionSettingActivity(final Activity context) {        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {            Uri packageURI = Uri.parse("package:" + context.getPackageName());            //注意这个是8.0新API            Intent intent = new Intent(Settings.ACTION_MANAGE_UNKNOWN_APP_SOURCES, packageURI);            //intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);            context.startActivity(intent);        }    }    //检查安装app权限是否可用    public static boolean getPermissionStatusByName(Context context, String permissionName) {        //兼容8.0        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {            switch (permissionName) {                case Manifest.permission.INSTALL_PACKAGES:                    return context.getPackageManager().canRequestPackageInstalls();                case Manifest.permission.SYSTEM_ALERT_WINDOW:                    return Settings.canDrawOverlays(context);            }        }        return true;    }    //获取普通权限是否可用    @TargetApi(Build.VERSION_CODES.M)    public static boolean getPermissionStatus(Context context, String permissionName) {        // 版本判断。当手机系统大于 23 时,才有必要去判断权限是否获取        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {            int i = ContextCompat.checkSelfPermission(context, permissionName);            // 权限是否已经 授权 GRANTED---授权  DINIED---拒绝            return (i == PackageManager.PERMISSION_GRANTED);        }        return true;    }    //特殊权限    public boolean getPermissionStatus2(Context context, String[] permissions) {        // 版本判断。当手机系统大于 23 时,才有必要去判断权限是否获取        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {            // 检查该权限是否已经获取            for (String str : permissions) {                if (!getPermissionStatusByName(context, str)) {                    showPermissionSettingDialog(context, str);                    return false;                }            }        }        return true;    }    //普通权限    public static boolean getPermissionStatus(Context context, String[] permissions) {        // 版本判断。当手机系统大于 23 时,才有必要去判断权限是否获取        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {            // 检查该权限是否已经获取            for (String str : permissions) {                if (!getPermissionStatus(context, str)) {                    return false;                }            }        }        return true;    }    public static  void chekPermission(Context context, String[] permissions, OnCheckPermissionListener listener) {        // 版本判断。当手机系统大于 23 时,才有必要去判断权限是否获取        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {            // 检查该权限是否已经获取            boolean useful = getPermissionStatus(context, permissions);            if (!useful) {                // 如果没有授予该权限,就去提示用户请求                showDialogTipUserRequestPermission(context, permissions);            } else {                listener.onPassed();            }        } else {            listener.onPassed();        }    }    // 提示用户该请求权限的弹出框    private static void showDialogTipUserRequestPermission(final Context context, final String[] permission) {        new AlertDialog.Builder(context)                .setTitle("权限不可用")                .setMessage("请开启权限后,再继续操作")                .setPositiveButton("立即开启", new DialogInterface.OnClickListener() {                    @Override                    public void onClick(DialogInterface dialog, int which) {                        startRequestPermission(context, permission);                    }                })                .setNegativeButton("取消", new DialogInterface.OnClickListener() {                    @Override                    public void onClick(DialogInterface dialog, int which) {                        Toast.makeText(context, "请开启权限后再操作", Toast.LENGTH_LONG).show();                        instance.initPermission();                    }                }).setCancelable(false).show();    }    // 开始提交请求权限    private static void startRequestPermission(final Context context, String[] permissions) {        ActivityCompat.requestPermissions((Activity) context, permissions, REQUEST_PERMISS_CODE);    }    //部分权限需要延时后生效    public void showProcess() {        Handler handler = new Handler();        handler.postDelayed(new Runnable() {            @Override            public void run() {                //重新检查所有权限是否可用                initPermission();            }        }, 1000);    }    /**     * 监听器,监听权限是否通过     */    public interface OnCheckPermissionListener {        void onPassed();//通过        void onNoPassed();//不通过    }    /**     * alert 消息提示框显示     *     * @param context  上下文     * @param title    标题     * @param message  消息     * @param listener 监听器     */    public void showAlert(Context context, String title, String message, DialogInterface.OnClickListener listener) {        builder = new AlertDialog.Builder(context);        builder.setTitle(title);        builder.setMessage(message);        builder.setPositiveButton("确定", listener);        builder.setCancelable(false);        builder.setIcon(R.mipmap.ic_launcher);        dialog = builder.create();        dialog.show();    }}

2.使用部分(MainActivity.java)

package com.huan.squirrel.appermission;import android.Manifest;import android.content.Context;import android.content.Intent;import android.support.annotation.NonNull;import android.support.v7.app.AppCompatActivity;import android.os.Bundle;import android.view.View;import android.widget.Button;import android.widget.TextView;import android.widget.Toast;import com.huan.squirrel.appermission.util.PermissionManager;import static com.huan.squirrel.appermission.util.PermissionManager.SYSTEM_ALERT_WINDOW_CODE;public class MainActivity extends AppCompatActivity {    private Context context;    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        /*********************     需要权限的功能要再次检查权限是否可用    start     ******************************************/        context = this;        final Button btn_permission = findViewById(R.id.btn_permission);        final String[] PERMISSIONS_ALL = {                Manifest.permission.READ_EXTERNAL_STORAGE,                Manifest.permission.WRITE_EXTERNAL_STORAGE,                Manifest.permission.CAMERA};        btn_permission.setOnClickListener(new View.OnClickListener() {            @Override            public void onClick(View view) {                PermissionManager.chekPermission(context, PERMISSIONS_ALL, new PermissionManager.OnCheckPermissionListener() {                    @Override                    public void onPassed() {                        Toast.makeText(context,"权限已经全部开启",Toast.LENGTH_LONG).show();                    }                    @Override                    public void onNoPassed() {                        Toast.makeText(context,"部分权限未开启",Toast.LENGTH_LONG).show();                    }                });            }        });        /*************************   需要权限的功能要再次检查权限是否可用  end      **************************************/    }    /************************  app第一次打开页面设置app运行必要的权限    start     ***************************************/    @Override    protected void onResume() {        super.onResume();        PermissionManager.getInstance(this).initPermission();    }    @Override    protected void onActivityResult(int requestCode, int resultCode, Intent data) {        super.onActivityResult(requestCode, resultCode, data);        if(SYSTEM_ALERT_WINDOW_CODE==requestCode){            PermissionManager.getInstance(this).showProcess();        }else{            PermissionManager.getInstance(this).initPermission();        }    }    //处理权限申请回调(写在Activity中)    @Override    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {        PermissionManager.getInstance(this).initPermission();    }    /**********************     app第一次打开页面设置app运行必要的权限    start   ***************************************/}

使用

1.activity中声明全部的权限
复制三个方法 onResume, onActivityResult, onRequestPermissionsResult

2.某些需要权限才能操作的时候需要检查
使用 PermissionManager.chekPermission()方法处理

问题

1.有些地方还存在问题没有好的解决。如 获取悬浮窗权限的时候,跳转到设置页面手动开启权限后,返回MainActivity并通过Settings.canDrawOverlays方法没有及时返回true,要延迟一会儿。
2.没有对onActivityResult方法做过多的判断,全都在resume方法中重新检查并初始化权限(容易让人诟病)。
3.特殊权限需要的时候自己添加处理。

源码

https://github.com/squirrelhuan/APPermission

更多相关文章

  1. android Matrix处理图片原理及方法整理
  2. Android的安全与权限(1)
  3. android studio打开旧项目遇到build.gradle相关的问题解决方法
  4. Android的读写文件权限
  5. 将retrofit2和rxjava的初始化配置到application
  6. android判断模拟器的三种方法

随机推荐

  1. 各种IT职业的英文翻译
  2. 写了一个字符串的二维表: TSta
  3. UI 自动化测试在有赞的实践
  4. 覆盖、再覆盖
  5. rsync daemon模式实战
  6. AEnM:兴利除弊—实现高性能织物基柔性电化
  7. 记一次失败的Perl + Nginx + FastCGI 配
  8. 执行 Application.Terminate 后, OnDestr
  9. Perl Dancer 学习(一)
  10. 关于字符串, 之前没这样用过