Android权限常识(来源于Google官方文档)
如果设备运行的是 Android 6.0(API 级别 23)或更高版本,并且应用的 targetSdkVersion 是 23 或更高版本,则应用在运行时向用户请求权限。用户可随时调用权限,因此应用在每次运行时均需检查自身是否具备所需的权限。
如果设备运行的是 Android 5.1(API 级别 22)或更低版本,并且应用的 targetSdkVersion 是 22 或更低版本,则系统会在用户安装应用时要求用户授予权限。如果将新权限添加到更新的应用版本,系统会在用户更新应用时要求授予该权限。用户一旦安装应用,他们撤销权限的唯一方式是卸载应用。
对于启动页对于权限的处理。主要是采用 github 开源框架----->>>> permissionsdispatcher (star ---->>> 8K+)
框架应用于android权限方面,使用方法如下:
框架支持的注释,在项目需要引入的,如下:
@RuntimePermission : 注册Activity 或Fragment(此框架两者都支持)来处理权限
@NeedPermission : 注释执行需要一个或者多个权限的操作的方法
@OnShowRationale : 注释一个解释为什么需要权限的方法,它传入一个PermissionRequest对象,
该对象可用于在用户输入时继续或中止当前的权限请求;
@OnPermissionDenied : 注释如果用户未授予权限则调用的方法 ;
@OnNeverAskAgain : 如果用户选择让设备“永不再询问”权限,则注释一个被调用的方法
1) gradle引入框架,AndroidMainfest增加要申请的权限
AndroidManifest增加权限---->> build.gradle(app):
implementation("com.github.hotchemi:permissionsdispatcher:3.1.0") {
//if you don't use android.app.Fragment you can exclude support for them
exclude module: "support-v13"
}
annotationProcessor "com.github.hotchemi:permissionsdispatcher-processor:3.1.0"
2) 选择处理权限的载体
大部分情况下,我们会使用Activity来处理权限的问题,例如当前项目,在启动页Activity进行权限处理;
代码如下:
@RuntimePermissions (加入此注释)
public class MainActivity extends AppCompatActivity{
@NeedsPermission(Manifest.permission.CAMERA) (假如当前需要申请相机权限,程序需要请求什么权限都在此添加)
void showCamera() {
三秒后跳转
}
@OnShowRationale(Manifest.permission.CAMERA)
void showRationaleForCamera(final PermissionRequest request) {
new AlertDialog.Builder(this)
.setMessage(R.string.permission_camera_msg)
.setPositiveButton(R.string.button_allow, (dialog, button) ->
request.proceed())
.setNegativeButton(R.string.button_deny, (dialog, button) ->
request.cancel())
.show();
}
@OnPermissionDenied(Manifest.permission.CAMERA) (用户未授予权限,则此时再次申请权限)
void showDeniedForCamera() {
用户未授予权限,则此时再次申请权限
}
@OnNeverAskAgain(Manifest.permission.CAMERA) (上次选择禁止并勾选:下次不在询问)
void showNeverAskForCamera() {
弹出对话框,取消则退出程序(APP),确定则跳转到 权限设置页面,进行权限设置
}
}
链接:跳转到指定app权限设置页面,代码如下(可以将其封装到工具类中,使用的时候直接调用):
public static void gotoAppSettingPage(Context context) {
Intent localIntent = new Intent();
localIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
localIntent.setAction("android.settings.APPLICATION_DETAILS_SETTINGS");
localIntent.setData(Uri.fromParts("package", context.getPackageName(), null));
context.startActivity(localIntent);
}
3) 在onCreate()方法中,委派权限处理以生成的方法showCameraWithPermissionCheck
onCreate中假如以下代码:
启动页为MainActivity时,
MainActivityPermissionsDispatcher.showCameraWithPermissionCheck(this);
启动页为StartupActivity时,
StartupActivityPermissionsDispatcher.showMainViewWithPermissionCheck(this);
4)重写 onRequestPermissionsResult()方法
在MainActivity(或者StartupActivity)中重写 onRequestPermissionsResult()方法;并在super方法之后调用,以下代码:
(处理Activity为MainActivity时)
MainActivityPermissionsDispatcher.onRequestPermissionsResult(this,requestCode,grantResults);
(处理Activity为StartupActivity时)
StartupActivityPermissionsDispatcher.onRequestPermissionsResult(this, requestCode, grantResults);
2.对于启动MainActivity时使用一下模式的解答
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_NEW_TASK)
上述行代码主要用于 解决界面重复创建问题 。
Intent.FLAG_ACTIVITY_CLEAR_TOP:如果在栈中发现存在Activity实例,则清空这个实例之上的Activity,使其处于栈顶
Intent.FLAG_ACTIVITY_NEW_TASK:根据Activity Affinity判断是否需要创建新的Task,然后再创建新的Activit实例放进去。
如果小伙伴发现书写中出现错误,或者有更好的办法解决此问题,欢迎留言和私信。
作者:小小小小枫叶