Android中的事件传递机制
16lz
2021-01-25
今天来看一下Android中的事件分发以及动态权限
Android的权限机制从第一个版本开始就已经存在,但之前的Android权限机制在保护用户安全和隐私等方面起到的作用有限,为此,Android开发团队在6.0系统中引用了运行时权限的功能
Android6.0的动态权限
共分为 9 组,每组只要有一个权限申请成功了,就默认整组权限都可以使用了
//获取通讯录权限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
只需要在manifest.xml中添加的权限
android.permission.ACCESS_LOCATION_EXTRA_COMMANDSandroid.permission.ACCESS_NETWORK_STATEandroid.permission.ACCESS_NOTIFICATION_POLICYandroid.permission.ACCESS_WIFI_STATEandroid.permission.ACCESS_WIMAX_STATEandroid.permission.BLUETOOTHandroid.permission.BLUETOOTH_ADMINandroid.permission.BROADCAST_STICKYandroid.permission.CHANGE_NETWORK_STATEandroid.permission.CHANGE_WIFI_MULTICAST_STATEandroid.permission.CHANGE_WIFI_STATEandroid.permission.CHANGE_WIMAX_STATEandroid.permission.DISABLE_KEYGUARDandroid.permission.EXPAND_STATUS_BARandroid.permission.FLASHLIGHTandroid.permission.GET_ACCOUNTSandroid.permission.GET_PACKAGE_SIZEandroid.permission.INTERNETandroid.permission.KILL_BACKGROUND_PROCESSESandroid.permission.MODIFY_AUDIO_SETTINGSandroid.permission.NFCandroid.permission.READ_SYNC_SETTINGSandroid.permission.READ_SYNC_STATSandroid.permission.RECEIVE_BOOT_COMPLETEDandroid.permission.REORDER_TASKSandroid.permission.REQUEST_INSTALL_PACKAGESandroid.permission.SET_TIME_ZONEandroid.permission.SET_WALLPAPERandroid.permission.SET_WALLPAPER_HINTSandroid.permission.SUBSCRIBED_FEEDS_READandroid.permission.TRANSMIT_IRandroid.permission.USE_FINGERPRINTandroid.permission.VIBRATEandroid.permission.WAKE_LOCKandroid.permission.WRITE_SYNC_SETTINGScom.android.alarm.permission.SET_ALARMcom.android.launcher.permission.INSTALL_SHORTCUTcom.android.launcher.permission.UNINSTALL_SHORTCUT
动态权限申请流程
第一步需要检测是否授权
//检测是否有写sd卡的权限 int code = ActivityCompat.checkSelfPermission(this,Manifest.permission.WRITE_EXTERNAL_STORAGE); if(code == PackageManager.PERMISSION_DENIED){ //未授权 }
如果没有授权则申请授权
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, REQUEST_PERMISSION);
最后处理授权结果:在Activity中重写onRequestPermissionsResult
// 授权结果@Overridepublic void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { super.onRequestPermissionsResult(requestCode, permissions, grantResults); if (requestCode == REQUEST_PERMISSION) { if (grantResults[0] == PackageManager.PERMISSION_DENIED) { // 用户拒绝 // 检测是否有必要跟用户说明为什么要申请这个权限,如果拒绝了会有什么结果 if (ActivityCompat.shouldShowRequestPermissionRationale(WelcomeActivity.this, permissions[0])) { // 解释一下 AlertDialog.Builder b = new AlertDialog.Builder(WelcomeActivity.this); b.setTitle(" 警告 ") .setMessage(" 不授权将影响应用的正常使用 , 是否需要重新授权 ?") .setPositiveButton(" 是 ", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { ActivityCompat.requestPermissions(WelcomeActivity.this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, REQUEST_PERMISSION); } }).setNegativeButton(" 否 ", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { finish(); } }); b.show(); } } else { toMainActivity(); } }}
授权 Activity 的封装
1 、封装了授权检测
2 、授权分进入设置 –> 应用详情 –> 权限这种打开方式 以及 直接使用授权申请方法两种
3 、对结果同一处理为 RESULT_OK 就是成功 否则就是授权失败
/*** 申请授权的 Activity ( 1 、可以进入设置打开或者关闭权限, 2 、直接使用授权申请方法来申请)* github PermissionGrant*/public class PermissionActivity extends Activity { private static final int REQUEST_SETTINGS = 1; private static final int REQUEST_PERMISSION = 2; private String[] permissions; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); Intent it = getIntent(); if (it == null || !it.hasExtra("permissions")) { finish(); return; } permissions = it.getStringArrayExtra("permissions"); requestWindowFeature(Window.FEATURE_NO_TITLE); setContentView(R.layout.activity_permission); findViewById(R.id.btn_setting).setOnClickListener(btnClick); findViewById(R.id.btn_grant).setOnClickListener(btnClick); }/*** 启动授权界面** @param context* @param requestCode* @param permissions*/public static void startPermissionActivity(Activity context, int requestCode, String... permissions) { Intent it = new Intent(context, PermissionActivity.class); it.putExtra("permissions", permissions); context.startActivityForResult(it, requestCode); } private View.OnClickListener btnClick = new View.OnClickListener() { @Override public void onClick(View v) { switch (v.getId()) { case R.id.btn_setting: // 进入设置打开权限 Intent it = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS); // 配置跳转要查看的应用的包名 packege:com.xykj.filemanager it.setData(Uri.parse("package:" + getApplication().getPackageName())); startActivityForResult(it, REQUEST_SETTINGS); break; case R.id.btn_grant: // 使用申请授权方法 ActivityCompat.requestPermissions(PermissionActivity.this, permissions, REQUEST_PERMISSION); break; } }};// 授权结果@Override public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { super.onRequestPermissionsResult(requestCode, permissions, grantResults); if (requestCode == REQUEST_PERMISSION) { int deniedIndex = getFirstDeniedIndex(grantResults); if (deniedIndex != -1) { // 用户拒绝 // 检测是否有必要跟用户说明为什么要申请这个权限,如果拒绝了会有什么结果 if(ActivityCompat.shouldShowRequestPermissionRationale(PermissionActivity.this, permissions[deniedIndex])) { // 解释一下 AlertDialog.Builder b = new AlertDialog.Builder(PermissionActivity.this); b.setTitle(" 警告 ") .setMessage(" 不授权将影响应用的正常使用 , 是否需要重新授权 ?") .setPositiveButton(" 是 ", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { ActivityCompat.requestPermissions( PermissionActivity.this, PermissionActivity.this.permissions, REQUEST_PERMISSION); } }).setNegativeButton(" 否 ", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { finish(); } }); b.show(); } } else { setResult(RESULT_OK); finish(); } }}private int getFirstDeniedIndex(int[] grantResults) { int len = grantResults.length; for (int i = 0; i < len; i++) { if (grantResults[i] != PackageManager.PERMISSION_GRANTED) { return i; } } return -1;}/*** 检测是否授权** @param context* @param permissions* @return*/public static boolean isGrantedPermission(Context context, List permissions) { if (Build.VERSION.SDK_INT < 23) { return true; } int size = permissions.size(); for (int i = 0; i < size; i++) { String name = permissions.get(i); // 一个个的检测授权情况,如果发现了其中某一个未授权,返回 false 表示检测授权失败 int code = ActivityCompat.checkSelfPermission(context, name); if (code == PackageManager.PERMISSION_DENIED) { return false; } String op = AppOpsManagerCompat.permissionToOp(name); if (TextUtils.isEmpty(op)) { continue; } code = AppOpsManagerCompat.noteProxyOp(context, op, context.getApplicationContext().getPackageName()); if (code != AppOpsManagerCompat.MODE_ALLOWED) { return false; } } return true;}@Overrideprotected void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); if (requestCode == REQUEST_SETTINGS) { if (isGrantedPermission(PermissionActivity.this, permissions)) { setResult(RESULT_OK); } else { setResult(RESULT_CANCELED); } finish(); } }}
为了方便该授权Activity的运用,可以将其显示为Dialog
使用:
if (!PermissionActivity.isGrantedPermission(this,Manifest.permission.WRITE_EXTERNAL_STORAGE)) { // 未授权,申请授权 PermissionActivity.startPermissionActivity(this,REQUEST_PERMISSION,Manifest.permission.WRITE_EXTERNAL_STORAGE);} else { // 成功 ...}结果处理@Overrideprotected void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); if(resultCode == RESULT_OK){ // 授权成功 }else{ // 授权失败 }}
这里我后续会慢慢改进
更多相关文章
- Android添加用户组及自定义App权限的方法
- Android(安卓)4.2 通过修改FrameWork源码实现动态隐藏导航栏,实现
- Android(安卓)Wear缺少本质上的创新
- 移植ffmpeg库到Android后的简单使用
- android toast乱码
- Android(安卓)扫描二维码(Scan Kit)
- Android实现动态高斯模糊效果示例代码
- Android版本更新(适用于6.0/7.0)
- Android(安卓)使用sharedpreferences、ACache缓存用户名和密码