动态获取权限的封装

普通权限(直接在XML布局添加就可以了)

对于用户的隐私是没有危险的,只需要在AndroidManifest.xml中申请即可以授权

Normal Permissions如下:

ACCESS_LOCATION_EXTRA_COMMANDS
ACCESS_NETWORK_STATE
ACCESS_NOTIFICATION_POLICY
ACCESS_WIFI_STATE
BLUETOOTH
BLUETOOTH_ADMIN
BROADCAST_STICKY
CHANGE_NETWORK_STATE
CHANGE_WIFI_MULTICAST_STATE
CHANGE_WIFI_STATE
DISABLE_KEYGUARD
EXPAND_STATUS_BAR
GET_PACKAGE_SIZE
INSTALL_SHORTCUT
INTERNET
KILL_BACKGROUND_PROCESSES
MODIFY_AUDIO_SETTINGS
NFC
READ_SYNC_SETTINGS
READ_SYNC_STATS
RECEIVE_BOOT_COMPLETED
REORDER_TASKS
REQUEST_INSTALL_PACKAGES
SET_ALARM
SET_TIME_ZONE
SET_WALLPAPER
SET_WALLPAPER_HINTS
TRANSMIT_IR
UNINSTALL_SHORTCUT
USE_FINGERPRINT
VIBRATE
WAKE_LOCK
WRITE_SYNC_SETTINGS

危险权限(XML添加还需要动态申请)

需要访问用户的隐私信息等的权限

Dangerous Permissions:

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

主要的方法: 

//检查是否拥有这个权限
ContextCompat.checkSelfPermission
//请求权限 设置申请的权限和请求码
ActivityCompat.requestPermissions
//被拒绝之后:是否要向用户解释权限的行为
ActivityCompat.shouldShowRequestPermissionRationale()

//请求权限返回的结果在
onRequestPermissionsResult 中根据请求码得到result

PackageManager.PERMISSION_GRANTED //常量0 权限被授予
PackageManager.PERMISSION_DENIED //常量-1 权限被拒绝

简单案例:

   private void initPermission() {
        //检查程序是否拥有这个权限
//        ContextCompat.checkSelfPermission()
        //请求权限
//        ActivityCompat.requestPermissions();
        //是否要像用户解释请求权限的行为
//        ActivityCompat.shouldShowRequestPermissionRationale()

        //1.获取程序是否具备该项权限
        //如果是6.0一下的手机,该方法的返回值会始终为PERMISSION_GRANTED
        //因此你并不需要动态申请权限,直接做你想做的
        //如果是6.0以上的手机,情况就分为两种
        //如果是noramal权限,该方法的返回值会始终为PERMISSION_GRANTED
        //如果是dangerous权限,动态请求
        int permission = ContextCompat.checkSelfPermission(this, Manifest.permission.RECORD_AUDIO);
        Log.e("TAG","是否具备这项权限:" + permission);
//        PackageManager.PERMISSION_GRANTED       //权限被授予
//        PackageManager.PERMISSION_DENIED    //权限被拒绝
        //2.判断,如果不具备权限,则申请权限
        if(permission != PackageManager.PERMISSION_GRANTED ) {
            //第一次运行时返回值为false
            boolean should = ActivityCompat.
                    shouldShowRequestPermissionRationale(this,Manifest.permission.RECORD_AUDIO);
            Log.e("TAG","是否需要向用户解释:" + should);
            if(should){
                explainDialog();
                return;
            }
            //参数1:activity对象
            //参数2:需要被授权的权限
            //参数3:请求吗
            ActivityCompat.requestPermissions(this,new String[]{Manifest.permission.RECORD_AUDIO},1);
        }
    }

/**
当权限被拒绝之后要向用户解释为什么需要这个权限 ..
**/
    private void explainDialog() {
        AlertDialog.Builder builder = new AlertDialog.Builder(this)
                .setMessage("录音操作必须要录制音频的权限,是否授权?")
                .setPositiveButton("确定", new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialogInterface, int i) {
                        //请求权限
                        ActivityCompat.requestPermissions(MainActivity.this,new String[]{Manifest.permission.RECORD_AUDIO},1);
                    }
                })
                .setNegativeButton("取消",null);
                builder.show();
    }

    private int granted;    //用于保存权限是否被授予的凭证
    /**
     * 请求权限后的回调方法
     * @param requestCode 是指在requestPermissions()传递的请求码
     * @param permissions  是指在requestPermissions()传递的需要请求的权限
     * @param grantResults  是指申请权限后返回的结果
     */
    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        if(requestCode == 1) {
            granted = grantResults[0];
        }
    }
}

一. PermissionUtil 申请权限工具类(直接Copy)

没有处理的问题:

1.将请求码和Callback放到Map中,不会被覆盖

2.没有处理用户点击权限不再询问时,做出相应的提示

import android.app.Activity;
import android.content.pm.PackageManager;
import android.os.Build;
import android.support.annotation.NonNull;
import android.support.annotation.RequiresApi;
import android.util.Log;
import android.widget.Toast;

import java.util.ArrayList;
import java.util.List;

public class PermissionUtil {

    private Activity mActivity;
    private int mReqCode;//请求码
    private CallBack mCallBack;

    public static interface CallBack {
        void grandAll();//所有必要权限已经申请了,可以跳到主界面

        void denied();//存在没有获取的权限,则直接退出程序
    }

    public PermissionUtil(Activity activity) {
        mActivity = activity;
    }

    /**
     * 申请权限的方法
     *
     * @param needPermissions
     * @param reqCode
     * @param callBack
     */
    @RequiresApi(api = Build.VERSION_CODES.M)
    public void request(List<String> needPermissions, int reqCode, CallBack callBack) {
        if (mActivity == null) {
            throw new IllegalArgumentException("activity is null");
        }

        //如果机器sdk小于23不需要动态获取权限
        if (Build.VERSION.SDK_INT < 23) {
            callBack.grandAll();//默认全部权限已经授予
            return;
        }

        mReqCode = reqCode;
        mCallBack = callBack;

        //存放仍需要获取的权限
        List<String> reqPermissions = new ArrayList<>();
        for (String permission : needPermissions) {
            Log.e("TAG", needPermissions + "0");

            if (mActivity.checkSelfPermission(permission) != PackageManager.PERMISSION_GRANTED) {
                //如果权限还没被获取,则添加进来
                reqPermissions.add(permission);
                Log.d("TAG", reqPermissions + "1");
            }

        }
        //如果存放仍需要获取的权限为空,则意味着所有权限都被授予了
        if (reqPermissions.isEmpty()) {
            callBack.grandAll();
            Log.d("TAG", reqPermissions + "2");
            return;
        }

        //如果不为空,要将这个需要请求的权限,提示授予
        mActivity.requestPermissions(reqPermissions.toArray(new String[]{}), reqCode);

    }

    /**
     * 处理权限后返回的回调
     * 1.当用户执行完获取权限的操作后的回调
     * 提示它还有哪些权限没有被获取
     */
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        if (requestCode == mReqCode) {
            boolean grantAll = true;
            for (int i = 0; i < grantResults.length; i++) {
                if (grantResults[i] != PackageManager.PERMISSION_GRANTED) {
                    grantAll = false;
                    Toast.makeText(mActivity, permissions[i] + "未授权", Toast.LENGTH_SHORT).show();
                    break;
                }
            }

            if (grantAll) {//如果全部都授权了
                mCallBack.grandAll();
            } else {
                mCallBack.denied();
            }


        }
    }
}

二、闪屏页的权限判断,授予了所有必要权限才会跳转到主界面

SplashActivity.java

import android.Manifest;
import android.content.Intent;
import android.os.Build;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.annotation.RequiresApi;
import android.support.v7.app.AppCompatActivity;

import java.util.ArrayList;
import java.util.List;

/**
 * 动态申请权限的界面
 * 1.放在第一个启动的界面(在AndroidManifest.xml中配置)
 */
public class SplashActivity extends AppCompatActivity {
    //定义所有需要申请的权限
    public static List<String> sNeedReqPermissions = new ArrayList<>();
    private PermissionUtil mPermissionUtil;

    static {
        //静态代码块中添加权限
        sNeedReqPermissions.add(Manifest.permission.READ_PHONE_STATE);
        sNeedReqPermissions.add(Manifest.permission.ACCESS_FINE_LOCATION);
        sNeedReqPermissions.add(Manifest.permission.ACCESS_COARSE_LOCATION);
        sNeedReqPermissions.add(Manifest.permission.WRITE_EXTERNAL_STORAGE);
        sNeedReqPermissions.add(Manifest.permission.ACCESS_WIFI_STATE);
        sNeedReqPermissions.add(Manifest.permission.READ_PHONE_STATE);
        sNeedReqPermissions.add(Manifest.permission.ACCESS_NETWORK_STATE);
    }


    @RequiresApi(api = Build.VERSION_CODES.M)
    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        mPermissionUtil = new PermissionUtil(this);
        mPermissionUtil.request(sNeedReqPermissions, 100, new PermissionUtil.CallBack() {
            @Override
            public void grandAll() {
                toMainActivity();
                finish();
            }

            @Override
            public void denied() {
                finish();//直接finish
            }
        });

    }

    //跳转到第二个节目
    private void toMainActivity() {
        startActivity(new Intent(this, MainActivity.class));

    }

    /**
     * 用来返回给申请工具类来做具体回调
     * @param requestCode
     * @param permissions
     * @param grantResults
     */
    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);

        mPermissionUtil.onRequestPermissionsResult(requestCode, permissions, grantResults);
    }
}

注意:在AndroidManifest.xml中将FlashActivity设置第一个启动的界面.

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值