大家好,欢迎来到IT知识分享网。
(1)targetSdkVersion
想要了解权限,最好还是要对Android系统版本和API等级有一定的了解,才能知道Android在哪个系统版本对权限有所变化。
具体可参考如下文章Android 系统版本和 API 等级对应关系表。
(2)Android权限分类
- 普通权限:只需要在清单文件中注册即可
- 危险权限:需要在代码中动态申请,以弹系统 Dialog 的形式进行请求
- 特殊权限:需要在代码中动态申请,以跳系统 Activity 的形式进行请求
而我们今天要讲的主题,是关于存储权限,在 Android 6.0 之后就变成了危险权限,而到了 Android 11 上面变成了特殊权限,而最明显的区别是一个是通过 Dialog 展示给用户看,另外一个是通过 Activity 展现给用户看。
(A)6.0之后的危险权限界面
(B)Android 11®之后的特殊权限界面
(4)Android 10.0 以下存储权限适配
(A)升级 targetSdkVersion
android
defaultConfig {
targetSdkVersion 23
}
}
(B)添加清单权限
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
(C)代码动态申请
public final class PermissionActivity extends AppCompatActivity {
private static final int REQUEST_CODE = 1024;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestPermission();
}
private void requestPermission() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
// 先判断有没有权限
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.READ_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED &&
ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED) {
writeFile();
} else {
ActivityCompat.requestPermissions(this, new String[]{
Manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.WRITE_EXTERNAL_STORAGE}, REQUEST_CODE);
}
} else {
writeFile();
}
}
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
if (requestCode == REQUEST_CODE) {
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.READ_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED &&
ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED) {
writeFile();
} else {
ToastUtils.show("存储权限获取失败");
}
}
}
/** * 模拟文件写入 */
private void writeFile() {
ToastUtils.show("写入文件成功");
}
}
(D)需要注意的是,如果 targetSdkVersion >= 29 上,还需要在清单文件中加上
<application android:requestLegacyExternalStorage="true">
否则就算申请了存储权限,在安卓 10.0 的设备上将无法正常读写外部存储上的文件。
(4)Android 11 申请存储权限
(A)升级 targetSdkVersion
android
defaultConfig {
targetSdkVersion 30
}
}
(B)添加清单权限
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE" />
(C)代码动态申请
public final class PermissionActivity extends AppCompatActivity {
private static final int REQUEST_CODE = 1024;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestPermission();
}
private void requestPermission() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
// 先判断有没有权限
if (Environment.isExternalStorageManager()) {
writeFile();
} else {
Intent intent = new Intent(Settings.ACTION_MANAGE_APP_ALL_FILES_ACCESS_PERMISSION);
intent.setData(Uri.parse("package:" + context.getPackageName()));
startActivityForResult(intent, REQUEST_CODE);
}
} else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
// 先判断有没有权限
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.READ_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED &&
ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED) {
writeFile();
} else {
ActivityCompat.requestPermissions(this, new String[]{
Manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.WRITE_EXTERNAL_STORAGE}, REQUEST_CODE);
}
} else {
writeFile();
}
}
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
if (requestCode == REQUEST_CODE) {
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.READ_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED &&
ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED) {
writeFile();
} else {
ToastUtils.show("存储权限获取失败");
}
}
}
@Override
protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == REQUEST_CODE && Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
if (Environment.isExternalStorageManager()) {
writeFile();
} else {
ToastUtils.show("存储权限获取失败");
}
}
}
/** * 模拟文件写入 */
private void writeFile() {
ToastUtils.show("写入文件成功");
}
}
(5)使用三方Jar来简单申请权限
XXPermissions.with(this)
// 不适配 Android 11 可以这样写
//.permission(Permission.Group.STORAGE)
// 适配 Android 11 需要这样写,这里无需再写 Permission.Group.STORAGE
.permission(Permission.MANAGE_EXTERNAL_STORAGE)
.request(new OnPermissionCallback() {
@Override
public void onGranted(List<String> permissions, boolean all) {
if (all) {
toast("获取存储权限成功");
}
}
@Override
public void onDenied(List<String> permissions, boolean never) {
if (never) {
toast("被永久拒绝授权,请手动授予存储权限");
// 如果是被永久拒绝就跳转到应用权限系统设置页面
XXPermissions.startPermissionActivity(MainActivity.this, permissions);
} else {
toast("获取存储权限失败");
}
}
});
(6)Android 13 申请存储权限
从Android 13开始,如果你的应用targetSdk指定到了33或以上,那么READ_EXTERNAL_STORAGE权限就完全失去了作用,申请它将不会产生任何的效果。
与此同时Google新增了READ_MEDIA_IMAGES、READ_MEDIA_VIDEO和READ_MEDIA_AUDIO这3个运行时权限,分别用于管理手机的照片、视频和音频文件。
(A)升级 targetSdkVersion
android
defaultConfig {
targetSdkVersion 33
}
}
(B)添加清单权限
<!-- 一般来说,允许用户自定义头像的app都需要这个权限 -->
<uses-permission android:name="android.permission.READ_MEDIA_IMAGES" android:minSdkVersion = "33"/>
<!-- 如果你想开发音乐播放器之类需要获取音频的app,加上这个权限 -->
<uses-permission android:name="android.permission.READ_MEDIA_AUDIO" android:minSdkVersion = "33"/>
<!-- 如果你想开发视频编辑器之类需要获取视频的app,加上这个权限 -->
<uses-permission android:name="android.permission.READ_MEDIA_VIDEO" android:minSdkVersion = "33"/>
<!-- 向前兼容 -->
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" android:maxSdkVersion="32" />
(C)代码动态申请
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
ActivityCompat.requestPermissions( activity,new String[]{
READ_MEDIA_IMAGES,
READ_MEDIA_AUDIO,
READ_MEDIA_VIDEO
},MEDIA_READ_REQUEST_CODE);
}else{
ActivityCompat.requestPermissions( activity,new String[]{
READ_EXTERNAL_STORAGE
},MEDIA_READ_REQUEST_CODE);
}
(D)Android 13自带的文件选择器
Android 13除了修改对媒体文件访问权限外,还为用户提供了一种全新的媒体文件选择器,让其无需向应用授予对整个媒体库的访问权限,也解决了以往的版本不支持多选的问题。
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU){
// 打开Android 13自带的媒体文件选择器(默认单选)
Intent intent = new Intent(MediaStore.ACTION_PICK_IMAGES);
// 如果想多选,就加上这行代码,其中MediaStore.getPickImagesMaxLimit()代表设备的Provider最大支持的多选数量
intent.putExtra(MediaStore.EXTRA_PICK_IMAGES_MAX, Math.min(10,MediaStore.getPickImagesMaxLimit()));
// 如果只能选择视频,加上这行代码
intent.setType("video/*");
// 如果想只选择图片,加上这行代码
intent.setType("image/*");
// 如果想限定某种格式的图片或视频,可以把上边的*改成gif或者mp4
intent.setType("image/gif");
startActivityForResult(intent, PHOTO_PICKER_MULTI_SELECT_REQUEST_CODE);
}
免责声明:本站所有文章内容,图片,视频等均是来源于用户投稿和互联网及文摘转载整编而成,不代表本站观点,不承担相关法律责任。其著作权各归其原作者或其出版社所有。如发现本站有涉嫌抄袭侵权/违法违规的内容,侵犯到您的权益,请在线联系站长,一经查实,本站将立刻删除。 本文来自网络,若有侵权,请联系删除,如若转载,请注明出处:https://yundeesoft.com/20580.html