Android的权限动态申请需要注意的地方

本文探讨了Android 6.0及以后版本中权限动态申请的问题,指出了一些容易忽视的细节。作者尝试封装权限申请过程,虽然最终未达到理想效果,但发现Fragment无需实现OnRequestPermissionsResultCallback接口,只需直接调用requestPermissions()即可。此外,作者提到已有成熟的权限管理框架,并表达了对更好封装方法的探索意愿。最终,作者在基类中实现了简单权限申请的抽象,以适应Activity和Fragment的需求。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

        自从安卓6.0来了之后,权限的动态申请问题就一直让代码不美观,但是因为工作比较忙,一直没有怎么样去对这个权限动态申请的封装。今天心血来潮,准备封装一下,虽然最终还是因为不符合封装预期放弃了,但是还是得到了一些之前没关注的点。

        首先需要动态申请的“危险”权限的列表

        总结如下:android.permission-group是权限组,下面是权限组中的权限

android.permission-group.CALENDAR

android.permission.READ_CALENDAR      //允许程序读取用户日历数据
android.permission.WRITE_CALENDAR     //允许一个程序写入但不读取用户日历数据

android.permission-group.CAMERA
android.permission.CAMERA            //允许访问摄像头进行拍照

android.permission-group.CONTACTS
android.permission.READ_CONTACTS     //允许应用访问联系人通讯录信息
android.permission.WRITE_CONTACTS    //写入联系人,但不可读取
android.permission.GET_ACCOUNTS    //访问一个帐户列表在Accounts Service中

android.permission-group.LOCATION
android.permission.ACCESS_FINE_LOCATION      //允许一个程序访问精良位置(如GPS)
android.permission.ACCESS_COARSE_LOCATION    //通过WiFi或移动基站的方式获取用户错略的经纬度信息,定位精度大概误差在30~1500米

android.permission-group.MICROPHONE
android.permission.RECORD_AUDIO            //录制声音通过手机或耳机的麦克

android.permission-group.PHONE
android.permission.READ_PHONE_STATE             //访问电话状态
android.permission.CALL_PHONE                      //允许一个程序初始化一个电话拨号不需通过拨号用户界面需要用户确认
android.permission.READ_CALL_LOG
android.permission.WRITE_CALL_LOG

com.android.voicemail.permission.ADD_VOICEMAIL
android.permission.USE_SIP                       //允许程序使用SIP视频服务
android.permission.PROCESS_OUTGOING_CALLS          //允许程序监视、修改有关播出电话

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

android.permission-group.SMS
android.permission.SEND_SMS                  //发送短信
android.permission.RECEIVE_SMS              //允许程序监控一个将收到短信息,记录或处理
android.permission.READ_SMS                  //允许程序读取短信息
android.permission.RECEIVE_WAP_PUSH           //允许程序监控将收到WAP PUSH信息
android.permission.RECEIVE_MMS                //允许一个程序监控将收到MMS彩信,记录或处理
android.permission.READ_CELL_BROADCASTS

android.permission-group.STORAGE
android.permission.READ_EXTERNAL_STORAGE           //允许程序读取外部存储
android.permission.WRITE_EXTERNAL_STORAGE         //允许程序写入外部存储,如SD卡上写文件
          有了上面的表之后接下来就是,就是动态申请的代码(这个百度一下非常的多)注意这个是在Activity中申请的

/*
单个的权限申请函数
 */
public void Permission_application_sing(Context context, Activity activity, String permission) {
    if (Build.VERSION.SDK_INT >= 23) {   //判断是否是6.0系统
        int checkCallPhonePermission = ContextCompat.checkSelfPermission(context, permission);
        if (checkCallPhonePermission != PackageManager.PERMISSION_GRANTED) {
            ActivityCompat.requestPermissions(activity, new String[]{permission}, 123);
        } else {
            getPermissiondeal.PermissionAllow_deal();   //权限被允许做的操作
        }
    } else {
        getPermissiondeal.PermissionAllow_deal();       //6.0以下系统直接操作
    }
}   
          回调函数

public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
    switch (requestCode) {
        case 123:
            if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {       //用户点击了允许权限
                Log.e("onRequestPermissionsResult", "PermissionAllow_deal");
                getPermissiondeal.PermissionAllow_deal();
            } else {                                                            //用户点击了拒绝权限
                Log.e("onRequestPermissionsResult", "PermissionRefuse_deal");
                getPermissiondeal.PermissionRefuse_deal();
            }
            break;
    }
}
          权限用户操作之后点击发现回调函数并没有执行,上网百度了一下,发现需要在Activity实现ActivityCompat.OnRequestPermissionsResultCallback接口,如下

public class PermissionsUtil extends Activity implements ActivityCompat.OnRequestPermissionsResultCallback {
          实现了这个接口之后onRequestPermissionsResult在Activity中有效执行,但是在Fragment中,onRequestPermissionsResult回调又再一次失效了。又经过了一番百度

找到了Fragment不需要实现ActivityCompat.OnRequestPermissionsResultCallback接口,只需要将上面的修改为

if (Build.VERSION.SDK_INT >= 23) {
    int checkCallPhonePermission = ContextCompat.checkSelfPermission(context,Manifest.permission.RECORD_AUDIO);
    if(checkCallPhonePermission != PackageManager.PERMISSION_GRANTED){
        requestPermissions(new String[]{Manifest.permission.RECORD_AUDIO},123);
    }else{
        setParam();
        mIat.startListening(mRecoListener);
    }
} else {
    setParam();
    mIat.startListening(mRecoListener);
}

           将ActivityCompat.requestPermissions(activity, new String[]{permission}, 123);修改为  requestPermissions(new String[]{Manifest.permission.RECORD_AUDIO},123);,onRequestPermissionsResult就有效了。有一些朋友已经写了很好的权限封装的框架,自己一直没去看,如果大家有更好的框架,可以推荐给我,本次的封装已失败告终,有时间会寻找更加好的封装权限的方法。


        经过一两天的沉淀,本人最终在基类中使用抽象简单的实现了权限的抽取,使其继承后较简单的使用。针对单一的权限申请,简陋是简陋,暂时对我还够用,后期再优化呗。(需要区分Activity与fragment)

      

package com.haichong.bluetoothtwo;

import android.Manifest;
import android.app.Activity;
import android.app.ProgressDialog;
import android.content.Context;
import android.content.pm.PackageManager;
import android.graphics.Color;
import android.os.Build;
import android.support.v4.app.ActivityCompat;
import android.support.v4.content.ContextCompat;
import android.util.Log;

import Util.SystemBarTintManager;

/**
 * Created by Administrator on 2017/4/11.
 */

public abstract class BaseActivity extends Activity implements ActivityCompat.OnRequestPermissionsResultCallback{
    ProgressDialog progressDialog;

    /*
   设置activity的状态栏的颜色
    */
    public void SetStatusBarClor(String color) {
        // 创建状态栏的管理实例
        SystemBarTintManager tintManager = new SystemBarTintManager(this);
        // 激活状态栏设置
        tintManager.setStatusBarTintEnabled(true);
        // 设置一个颜色给系统栏
        tintManager.setTintColor(Color.parseColor(color));
    }

    /*
初始化开启进度条
 */
    public void initprogressDialog(String message) {
        if (progressDialog == null) {
            progressDialog = new ProgressDialog(this);
            // 设置进度条风格,风格为圆形,旋转的
            progressDialog.setProgressStyle(ProgressDialog.STYLE_SPINNER);
            // 设置ProgressDialog 标题
            // jdtdialog.setTitle("进度对话框");
            // 设置ProgressDialog 提示信息
            progressDialog.setMessage(message);
            // 设置ProgressDialog 标题图标
            // jdtdialog.setIcon(android.R.drawable.ic_dialog_alert);
            // 设置ProgressDialog的最大进度
            progressDialog.setMax(100);
            progressDialog.setCanceledOnTouchOutside(false);
            // 设置ProgressDialog 的一个Button
            // 设置ProgressDialog 是否可以按退回按键取消
            progressDialog.setCancelable(true);
            // 显示
            progressDialog.show();
            // 设置ProgressDialog的当前进度
            progressDialog.setProgress(50);
        }
    }

    /*
结束进度条
 */
    public void endprogressDialog() {
        progressDialog.cancel();
        progressDialog = null;
    }


    /*
    以下是权限申请
    */

        /*
需要用户同意的权限表格  (使用例子   Manifest.permission.RECORD_AUDIO)
android.permission-group.CALENDAR

android.permission.READ_CALENDAR      //允许程序读取用户日历数据
android.permission.WRITE_CALENDAR     //允许一个程序写入但不读取用户日历数据

android.permission-group.CAMERA
android.permission.CAMERA            //允许访问摄像头进行拍照

android.permission-group.CONTACTS
android.permission.READ_CONTACTS     //允许应用访问联系人通讯录信息
android.permission.WRITE_CONTACTS    //写入联系人,但不可读取
android.permission.GET_ACCOUNTS    //访问一个帐户列表在Accounts Service中

android.permission-group.LOCATION
android.permission.ACCESS_FINE_LOCATION      //允许一个程序访问精良位置(如GPS)
android.permission.ACCESS_COARSE_LOCATION    //通过WiFi或移动基站的方式获取用户错略的经纬度信息,定位精度大概误差在30~1500米

android.permission-group.MICROPHONE
android.permission.RECORD_AUDIO            //录制声音通过手机或耳机的麦克

android.permission-group.PHONE
android.permission.READ_PHONE_STATE             //访问电话状态
android.permission.CALL_PHONE                      //允许一个程序初始化一个电话拨号不需通过拨号用户界面需要用户确认
android.permission.READ_CALL_LOG
android.permission.WRITE_CALL_LOG

com.android.voicemail.permission.ADD_VOICEMAIL
android.permission.USE_SIP                       //允许程序使用SIP视频服务
android.permission.PROCESS_OUTGOING_CALLS          //允许程序监视、修改有关播出电话

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

android.permission-group.SMS
android.permission.SEND_SMS                  //发送短信
android.permission.RECEIVE_SMS              //允许程序监控一个将收到短信息,记录或处理
android.permission.READ_SMS                  //允许程序读取短信息
android.permission.RECEIVE_WAP_PUSH           //允许程序监控将收到WAP PUSH信息
android.permission.RECEIVE_MMS                //允许一个程序监控将收到MMS彩信,记录或处理
android.permission.READ_CELL_BROADCASTS

android.permission-group.STORAGE
android.permission.READ_EXTERNAL_STORAGE           //允许程序读取外部存储
android.permission.WRITE_EXTERNAL_STORAGE         //允许程序写入外部存储,如SD卡上写文件
*/

    /*
    单个的权限申请函数
    (permission传输例子   Manifest.permission.RECORD_AUDIO)
     */
    public void Permission_application_sing(Context context, String permission) {
        if (Build.VERSION.SDK_INT >= 23) {
            int checkCallPhonePermission = ContextCompat.checkSelfPermission(context, permission);
            if (checkCallPhonePermission != PackageManager.PERMISSION_GRANTED) {
                requestPermissions(new String[]{Manifest.permission.RECORD_AUDIO}, 123);
            } else {
                Permissions_ok();
            }
        } else {
            Permissions_ok();
        }
    }

    public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
        switch (requestCode) {
            case 123:
                if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                    Log.e("onRequestPermissionsResult", "PermissionAllow_deal");
                    Permissions_ok();
                } else {
                    Log.e("onRequestPermissionsResult", "PermissionRefuse_deal");
                    Permissions_fail();
                }
                break;
        }
    }

    // 子类必须实现的方法(权限必用,后续会加入权限组)
    public abstract void Permissions_ok();
    public abstract void Permissions_fail();
}


          fragment的

package Fragment;

import android.app.Activity;
import android.app.Fragment;
import android.content.Context;
import android.content.pm.PackageManager;
import android.os.Build;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v4.content.ContextCompat;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

/**
 * Created by Administrator on 2017/4/11.
 * 基础的fragment界面
 */

public abstract class BaseFragment extends Fragment{

    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        return initViews();
    }
    // 子类必须实现初始化布局的方法
    public abstract View initViews();

    public Activity mActivity;
    public Context context;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        mActivity = getActivity();
    }


    /*
    以下是权限申请
    */
    /*
需要用户同意的权限表格  (使用例子   Manifest.permission.RECORD_AUDIO)
android.permission-group.CALENDAR

android.permission.READ_CALENDAR      //允许程序读取用户日历数据
android.permission.WRITE_CALENDAR     //允许一个程序写入但不读取用户日历数据

android.permission-group.CAMERA
android.permission.CAMERA            //允许访问摄像头进行拍照

android.permission-group.CONTACTS
android.permission.READ_CONTACTS     //允许应用访问联系人通讯录信息
android.permission.WRITE_CONTACTS    //写入联系人,但不可读取
android.permission.GET_ACCOUNTS    //访问一个帐户列表在Accounts Service中

android.permission-group.LOCATION
android.permission.ACCESS_FINE_LOCATION      //允许一个程序访问精良位置(如GPS)
android.permission.ACCESS_COARSE_LOCATION    //通过WiFi或移动基站的方式获取用户错略的经纬度信息,定位精度大概误差在30~1500米

android.permission-group.MICROPHONE
android.permission.RECORD_AUDIO            //录制声音通过手机或耳机的麦克

android.permission-group.PHONE
android.permission.READ_PHONE_STATE             //访问电话状态
android.permission.CALL_PHONE                      //允许一个程序初始化一个电话拨号不需通过拨号用户界面需要用户确认
android.permission.READ_CALL_LOG
android.permission.WRITE_CALL_LOG

com.android.voicemail.permission.ADD_VOICEMAIL
android.permission.USE_SIP                       //允许程序使用SIP视频服务
android.permission.PROCESS_OUTGOING_CALLS          //允许程序监视、修改有关播出电话

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

android.permission-group.SMS
android.permission.SEND_SMS                  //发送短信
android.permission.RECEIVE_SMS              //允许程序监控一个将收到短信息,记录或处理
android.permission.READ_SMS                  //允许程序读取短信息
android.permission.RECEIVE_WAP_PUSH           //允许程序监控将收到WAP PUSH信息
android.permission.RECEIVE_MMS                //允许一个程序监控将收到MMS彩信,记录或处理
android.permission.READ_CELL_BROADCASTS

android.permission-group.STORAGE
android.permission.READ_EXTERNAL_STORAGE           //允许程序读取外部存储
android.permission.WRITE_EXTERNAL_STORAGE         //允许程序写入外部存储,如SD卡上写文件
*/

    /*
    单个的权限申请函数
    (permission传输例子   Manifest.permission.RECORD_AUDIO)
     */
    public void Permission_application_sing(Context context, String permission) {
        if (Build.VERSION.SDK_INT >= 23) {
            int checkCallPhonePermission = ContextCompat.checkSelfPermission(context,permission);
            if (checkCallPhonePermission != PackageManager.PERMISSION_GRANTED) {
                requestPermissions(new String[]{permission}, 123);
            } else {
                Permissions_ok();
            }
        } else {
            Permissions_ok();
        }
    }

    public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
        switch (requestCode) {
            case 123:
                if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                    Log.e("onRequestPermissionsResult", "PermissionAllow_deal");
                    Permissions_ok();
                } else {
                    Permissions_fail();
                }
                break;
        }
    }

    // 子类必须实现的方法(权限必用,后续会加入权限组)
    public abstract void Permissions_ok();
    public abstract void Permissions_fail();
}
           用得上的话大家就用。哈哈

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值