安卓10 Android Q 权限申请遇到的坑——更严格的动态权限申请和存储权限
- 问题描述
- 原因介绍
- 新建文件的方法
- 动态权限的申请
问题描述
本人刚入安卓app开发的大门,安卓10的权限问题就把我拒之门外。
我使用了File类的makedir()和createnewfile()方法,还有短信收发权限。首先我在Manifest里申请了权限(这可以肯定),在我的安卓6.0上完美运行,创建了log文件和所需文件夹,还有短信的收发。然而到了安卓10测试机上却费了一番周折,操作总是失败。
主要原因是新版本的安卓在权限管理上更加严格,开发者无法在安卓其他目录拥有较多的权限,所以一般的开发时都将文件放在外置存储的cache下。也就是手机内置存储中占用极大的Android/data文件夹。
原因介绍
Android Q 中删除了READ_EXTERNAL_STORAGE和WRITE_EXTERNAL_STORAGE两项危险权限,限制 App 只能使用自己的应用空间存放文件。
当 App 需要保存一些不能随卸载删除的文件时,需要根据存放位置动态申请新增的权限:READ_MEDIA_IMAGES,READ_MEDIA_VIDEO 或 READ_MEDIA_AUDIO(分别对应系统的媒体文件夹)。 比较特殊的是 Downloads 文件夹:写入和读取自身写入的数据不需要申请权限,但想获取其他 App 存进去的文件时,必须使用系统的文件选择器,由用户选择。
新建文件的方法
当然,在这之前还需要在manifest里加入读写权限并动态申请啦!不过据说在自己应用的缓存文件夹下的读写不需要外加权限。
// 这里获取了安卓cache文件夹下分配给该app的目录绝对路径
logger = new Logger(getBaseContext().getExternalCacheDir().toString());
//这里对文件进行了操作
public Logger(String syspath){
path=syspath+"/filedirname";
File appDir = new File(path);
if (!appDir.exists()) {
appDir.mkdir();
//Log.i("msg",String.valueOf(appDir.exists()));
}
file= new File(appDir, filename);
try{
//Log.i("msg",file.getAbsolutePath()+file.isFile()+file.isDirectory());
file.createNewFile();
outputStream = new FileOutputStream(file);
}catch (IOException e){
e.printStackTrace();
}
}
动态权限的申请
Android Q的动态权限为每一个Activity都分配了权限,每个Activity必须为其单独申请权限,否则无法运行。不过也有可能是因为miui的每次申请时“询问”设置导致的。总之我的两台小米在onCreate下都申请了权限,但是在点击按钮后仍然提示权限未申请,在点击按钮的方法下重新ActivityCompat.requestPermissions()就能完美运行了。
@Override
public void onRequestPermissionsResult(int permsRequestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
if (permsRequestCode==reqcode) {
if (permissions.equals(permissions_net)&&
grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
SmsManager smsManager=SmsManager.getDefault();
smsManager.sendTextMessage(SXSM.sendto,null,SXSM.content,null,null);
} else {
//logger.writelog(permissions[0]+"request failed");
}
return;
}
}
void getPer(Activity a,String[] pers){
ActivityCompat.requestPermissions(a,pers,reqcode);
}
public void getSXMM(View view){
//发送短信
if(this.checkSelfPermission(Manifest.permission.SEND_SMS)== PackageManager.PERMISSION_GRANTED) {
SmsManager smsManager=SmsManager.getDefault();
smsManager.sendTextMessage(SXSM.sendto,null,SXSM.content,null,null);
logger.writelog("The message was sent.");
}else{
logger.writelog("permission denied");
getPer(this,permissions_sms);
}
}