自从安卓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(); }用得上的话大家就用。哈哈