当前位置:   article > 正文

android studio开发——android11版本以上权限动态申请问题,包括文件读写、图片、相机的调用_android.permission.read_media_images

android.permission.read_media_images

用于android手机的升级,现在已经是android13版本了,对于权限问题可能更加敏感了,前段时间开发发现之前的方法已经不再适用于android11以后的版本了

读写权限申请最好是跳转到设置中进行才是最好了,下面我们开始进行

首先是AndroidManifest.xml文件的权限

  1. <!-- android13的图片、音频、视频的权限-->
  2. <uses-permission android:name="android.permission.READ_MEDIA_IMAGES" />
  3. <uses-permission android:name="android.permission.READ_MEDIA_AUDIO" />
  4. <uses-permission android:name="android.permission.READ_MEDIA_VIDEO" />
  5. <!--存储权限-->
  6. <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
  7. <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
  8. <uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE"
  9. tools:ignore="ScopedStorage" />
  10. <!-- 打开相机权限-->
  11. <uses-permission android:name="android.permission.CAMERA" />
  12. <uses-feature android:name="android.hardware.camera" />
  13. <!-- 网络权限-->
  14. <uses-permission android:name="android.permission.INTERNET" />

然后这里讲解一下权限申请的情况,有两种情况

第一种情况是直接在Activity中申请权限

第二种情况是在Fragment中申请权限

第一种情况就比较直接,按照android11之前的权限申请如下

  1. //首先定义请求变量
  2. private static final String[] PERMISSIONS_STORAGE = {Manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.WRITE_EXTERNAL_STORAGE};
  3. //请求状态码,请求码的作用是与回调函数进行匹配的,这样就可以对不同权限操作进行不同的提示
  4. private static final int REQUEST_EXTERNAL_STORAGE = 1;
  5. //使用ActivityCompat.requestPermissions进行动态权限申请
  6. ActivityCompat.requestPermissions(MainActivity.this, PERMISSIONS_STORAGE, REQUEST_EXTERNAL_STORAGE);
  7. //然后Activity会有一个回调函数,可以在这个回调函数做一些提示
  8. //如下重写onRequestPermissionsResult方法
  9. @Override
  10. public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { //申请文件读写权限
  11. super.onRequestPermissionsResult(requestCode, permissions, grantResults);
  12. switch (requestCode) {
  13. case REQUEST_EXTERNAL_STORAGE:
  14. if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
  15. havePermission = true;
  16. Toast.makeText(this, "授权成功!", Toast.LENGTH_SHORT).show();
  17. } else {
  18. havePermission = false;
  19. Toast.makeText(this, "授权被拒绝!", Toast.LENGTH_SHORT).show();
  20. }
  21. break;
  22. case REQUEST_PERMISSION_CODE_33:
  23. Toast.makeText(this, "授权成功!", Toast.LENGTH_SHORT).show();
  24. break;
  25. }

 完整代码例子如下

  1. public class MainActivity extends AppCompatActivity {
  2. private static final String[] PERMISSIONS_STORAGE = {Manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.WRITE_EXTERNAL_STORAGE};
  3. //请求状态码
  4. private static final int REQUEST_EXTERNAL_STORAGE = 1;
  5. //创建Activity生命周期
  6. protected void onCreate(Bundle savedInstanceState) {
  7. }
  8. //获取Activity焦点的生命周期
  9. @Override
  10. protected void onResume() {
  11. super.onResume();
  12. checkPermission();
  13. }
  14. private AlertDialog dialog;
  15. private void checkPermission() {
  16. //检查权限(NEED_PERMISSION)是否被授权 PackageManager.PERMISSION_GRANTED表示同意授权
  17. //这里是android7以上就需要动态申请权限
  18. if (Build.VERSION.SDK_INT > Build.VERSION_CODES.M) {
  19. if (ActivityCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
  20. //申请权限
  21. if (dialog != null) {
  22. dialog.dismiss();
  23. dialog = null;
  24. }
  25. dialog = new AlertDialog.Builder(this)
  26. .setTitle("提示")//设置标题
  27. .setMessage("请开启文件访问权限,否则无法正常使用应用!")
  28. .setPositiveButton("确定", new DialogInterface.OnClickListener() {
  29. @Override
  30. public void onClick(DialogInterface dialog, int which) {
  31. dialog.dismiss();
  32. ActivityCompat.requestPermissions(MainActivity.this, PERMISSIONS_STORAGE, REQUEST_EXTERNAL_STORAGE);
  33. }
  34. }).create();
  35. dialog.show();
  36. } else {
  37. havePermission = true;
  38. }
  39. } else {
  40. //android6以下不需要动态申请权限
  41. havePermission = true;
  42. }
  43. }
  44. }
  45. @Override
  46. public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { //申请文件读写权限
  47. super.onRequestPermissionsResult(requestCode, permissions, grantResults);
  48. switch (requestCode) {
  49. case REQUEST_EXTERNAL_STORAGE:
  50. if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
  51. havePermission = true;
  52. Toast.makeText(this, "授权成功!", Toast.LENGTH_SHORT).show();
  53. } else {
  54. havePermission = false;
  55. Toast.makeText(this, "授权被拒绝!", Toast.LENGTH_SHORT).show();
  56. }
  57. break;
  58. case REQUEST_PERMISSION_CODE_33:
  59. Toast.makeText(this, "授权成功!", Toast.LENGTH_SHORT).show();
  60. break;
  61. }

 下面是第二种情况在Fragment中动态申请权限,因为Fragment是相当于依附在Activity中的页面,所以Fragment中没有回调函数处理,因此需要用到它所在的Activity的activity对象,例如Fragment的定义如下

  1. public class PersonFragment extends Fragment {
  2. //定义一个Activity对象,用于给MainActivity赋值
  3. public static Activity context;
  4. private static final String[] PERMISSIONS_STORAGE = {Manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.WRITE_EXTERNAL_STORAGE,Manifest.permission.CAMERA};
  5. //请求状态码
  6. private static final int REQUEST_EXTERNAL_STORAGE = 1;
  7. }
  8. @Override
  9. public void onStart() {
  10. super.onStart();
  11. checkPermission();
  12. }
  13. private AlertDialog dialog;
  14. private void checkPermission() {
  15. //检查权限(NEED_PERMISSION)是否被授权 PackageManager.PERMISSION_GRANTED表示同意授权
  16. //这里是android7以上就需要动态申请权限
  17. if (Build.VERSION.SDK_INT > Build.VERSION_CODES.M) {
  18. if (ActivityCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
  19. //申请权限
  20. if (dialog != null) {
  21. dialog.dismiss();
  22. dialog = null;
  23. }
  24. dialog = new AlertDialog.Builder(this)
  25. .setTitle("提示")//设置标题
  26. .setMessage("请开启文件访问权限,否则无法正常使用应用!")
  27. .setPositiveButton("确定", new DialogInterface.OnClickListener() {
  28. @Override
  29. public void onClick(DialogInterface dialog, int which) {
  30. dialog.dismiss();
  31. ActivityCompat.requestPermissions(context, PERMISSIONS_STORAGE, REQUEST_EXTERNAL_STORAGE);
  32. }
  33. }).create();
  34. dialog.show();
  35. } else {
  36. havePermission = true;
  37. }
  38. } else {
  39. //android6以下不需要动态申请权限
  40. havePermission = true;
  41. }
  42. }

那么在MainActivity中我们给上面的Fragment赋值activity对象,那么Fragment就可以在申请权限的时候操做MainActivity的回调函数了,MainActivity代码例子如下

  1. public class MainActivity extends AppCompatActivity {
  2. //这里的请求码要和Fragment的请求码一致
  3. private static final int REQUEST_EXTERNAL_STORAGE = 1;
  4. //创建Activity生命周期
  5. protected void onCreate(Bundle savedInstanceState) {
  6. PersonFragment.context = MainActivity.this
  7. }
  8. @Override
  9. public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { //申请文件读写权限
  10. super.onRequestPermissionsResult(requestCode, permissions, grantResults);
  11. switch (requestCode) {
  12. case REQUEST_EXTERNAL_STORAGE:
  13. if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
  14. havePermission = true;
  15. Toast.makeText(this, "授权成功!", Toast.LENGTH_SHORT).show();
  16. } else {
  17. havePermission = false;
  18. Toast.makeText(this, "授权被拒绝!", Toast.LENGTH_SHORT).show();
  19. }
  20. break;
  21. case REQUEST_PERMISSION_CODE_33:
  22. Toast.makeText(this, "授权成功!", Toast.LENGTH_SHORT).show();
  23. break;
  24. }

以上例子是对于一些到懂不懂的朋友讲解权限申请与回调函数的关系使用,下面就是android7以下及android11以下以及android13以下的动态权限申请情况

1.文件读写权限直接上代码了

  1. public class MainActivity extends AppCompatActivity {
  2. //申请的权限放进数组里
  3. private static final String[] PERMISSIONS_STORAGE = {Manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.WRITE_EXTERNAL_STORAGE};
  4. //请求状态码
  5. private static final int REQUEST_EXTERNAL_STORAGE = 1;
  6. //创建Activity生命周期
  7. protected void onCreate(Bundle savedInstanceState) {
  8. }
  9. //获取Activity焦点的生命周期
  10. @Override
  11. protected void onResume() {
  12. super.onResume();
  13. checkPermission();
  14. }
  15. private AlertDialog dialog;
  16. private void checkPermission() {
  17. //检查权限(NEED_PERMISSION)是否被授权 PackageManager.PERMISSION_GRANTED表示同意授权
  18. //这里是android11以上的读写权限申请
  19. //需要通过Settings.ACTION_MANAGE_ALL_FILES_ACCESS_PERMISSION跳转到权限设置打开权限
  20. if (Build.VERSION.SDK_INT >= 30) {
  21. if (!Environment.isExternalStorageManager()) {
  22. if (dialog != null) {
  23. dialog.dismiss();
  24. dialog = null;
  25. }
  26. dialog = new AlertDialog.Builder(this)
  27. .setTitle("提示")//设置标题
  28. .setMessage("请开启文件访问权限,否则无法正常使用本应用!")
  29. .setNegativeButton("取消", new DialogInterface.OnClickListener() {
  30. @Override
  31. public void onClick(DialogInterface dialog, int i) {
  32. dialog.dismiss();
  33. }
  34. })
  35. .setPositiveButton("确定", new DialogInterface.OnClickListener() {
  36. @Override
  37. public void onClick(DialogInterface dialog, int which) {
  38. dialog.dismiss();
  39. Intent intent = new Intent(Settings.ACTION_MANAGE_ALL_FILES_ACCESS_PERMISSION);
  40. startActivity(intent);
  41. }
  42. }).create();
  43. dialog.show();
  44. } else {
  45. havePermission = true;
  46. }
  47. } else {
  48. //这里就是android7到android11的权限申请
  49. //直接通过ActivityCompat.requestPermissions就可以
  50. if (Build.VERSION.SDK_INT > Build.VERSION_CODES.M) {
  51. if (ActivityCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
  52. //申请权限
  53. if (dialog != null) {
  54. dialog.dismiss();
  55. dialog = null;
  56. }
  57. dialog = new AlertDialog.Builder(this)
  58. .setTitle("提示")//设置标题
  59. .setMessage("请开启文件访问权限,否则无法正常使用应用!")
  60. .setPositiveButton("确定", new DialogInterface.OnClickListener() {
  61. @Override
  62. public void onClick(DialogInterface dialog, int which) {
  63. dialog.dismiss();
  64. ActivityCompat.requestPermissions(MainActivity.this, PERMISSIONS_STORAGE, REQUEST_EXTERNAL_STORAGE);
  65. }
  66. }).create();
  67. dialog.show();
  68. } else {
  69. havePermission = true;
  70. }
  71. } else {
  72. //android7以下的不需要动态申请权限
  73. havePermission = true;
  74. }
  75. }
  76. }
  77. //权限申请成功后的回调函数,可以做提示或其他
  78. @Override
  79. public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { //申请文件读写权限
  80. super.onRequestPermissionsResult(requestCode, permissions, grantResults);
  81. switch (requestCode) {
  82. case REQUEST_EXTERNAL_STORAGE:
  83. if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
  84. havePermission = true;
  85. Toast.makeText(this, "授权成功!", Toast.LENGTH_SHORT).show();
  86. } else {
  87. havePermission = false;
  88. Toast.makeText(this, "授权被拒绝!", Toast.LENGTH_SHORT).show();
  89. }
  90. break;
  91. case REQUEST_PERMISSION_CODE_33:
  92. Toast.makeText(this, "授权成功!", Toast.LENGTH_SHORT).show();
  93. break;
  94. }
  95. }

2.相册、相机权限申请情况

这里可能就android13比较特殊,因为android13把相册分成了3个权限,分别是图片申请、视频申请、音频申请

  1. private static final String[] PERMISSIONS_STORAGE = {Manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.WRITE_EXTERNAL_STORAGE, Manifest.permission.CAMERA};
  2. //请求状态码
  3. private static final int REQUEST_EXTERNAL_STORAGE = 1;
  4. //android13相册权限申请变量
  5. private static final String[] PERMISSIONS_STORAGE_33 = {Manifest.permission.READ_MEDIA_IMAGES, Manifest.permission.READ_MEDIA_AUDIO, Manifest.permission.READ_MEDIA_VIDEO, Manifest.permission.CAMERA};
  6. //请求状态码
  7. private static final int REQUEST_PERMISSION_CODE_33 = 2;

那么权限数组可能就不一样了,android13以下的申请读写权限就好了,而android13则可能需要动态申请这3个权限,所以代码如下,这里我用Fragment申请权限

  1. @RequiresApi(api = Build.VERSION_CODES.TIRAMISU)
  2. @SuppressLint("StaticFieldLeak")
  3. public class PersonFragment extends Fragment {
  4. //MainActivity的activity对象
  5. public static Activity context;
  6. @Override
  7. public void onStart() {
  8. super.onStart();
  9. ifHaveAlbumPermission(context)
  10. }
  11. //打开相册
  12. private void openFile() {
  13. Intent intentFromGallery = new Intent();
  14. // 设置文件类型
  15. intentFromGallery.setType("image/*");//选择图片
  16. intentFromGallery.setAction(Intent.ACTION_GET_CONTENT);
  17. //你需要使用系统提供的startActivityForResult(Intent intent,int requestCode)方法调用MainActivity的回调函数
  18. context.startActivityForResult(intentFromGallery, REQUEST_PICTURE_CODE);
  19. }
  20. // 判断是否有文件存储权限
  21. private void ifHaveAlbumPermission(Activity activity) {
  22. if (ActivityCompat.checkSelfPermission(activity, Manifest.permission.READ_MEDIA_IMAGES) != PackageManager.PERMISSION_GRANTED) {
  23. //android13权限申请
  24. if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
  25. ActivityCompat.requestPermissions(activity, PERMISSIONS_STORAGE_33, REQUEST_PERMISSION_CODE_33);
  26. openFile();
  27. } else {
  28. //android13以下的权限申请
  29. ActivityCompat.requestPermissions(activity, PERMISSIONS_STORAGE, REQUEST_EXTERNAL_STORAGE);
  30. }
  31. } else {
  32. openFile();
  33. }
  34. }
  35. }

以上就差不多完成了,相机的情况大同小异,可以看其他博主写的

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/我家自动化/article/detail/438123
推荐阅读
相关标签
  

闽ICP备14008679号