android studio开发——android11版本以上权限动态申请问题,包括文件读写、图片、相机的调用
用于android手机的升级,现在已经是android13版本了,对于权限问题可能更加敏感了,前段时间开发发现之前的方法已经不再适用于android11以后的版本了
读写权限申请最好是跳转到设置中进行才是最好了,下面我们开始进行
首先是AndroidManifest.xml文件的权限
然后这里讲解一下权限申请的情况,有两种情况
第一种情况是直接在Activity中申请权限
第二种情况是在Fragment中申请权限
第一种情况就比较直接,按照android11之前的权限申请如下
//首先定义请求变量 private static final String[] PERMISSIONS_STORAGE = {Manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.WRITE_EXTERNAL_STORAGE};//请求状态码,请求码的作用是与回调函数进行匹配的,这样就可以对不同权限操作进行不同的提示private static final int REQUEST_EXTERNAL_STORAGE = 1;//使用ActivityCompat.requestPermissions进行动态权限申请ActivityCompat.requestPermissions(MainActivity.this, PERMISSIONS_STORAGE, REQUEST_EXTERNAL_STORAGE);//然后Activity会有一个回调函数,可以在这个回调函数做一些提示//如下重写onRequestPermissionsResult方法@Overridepublic void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { //申请文件读写权限 super.onRequestPermissionsResult(requestCode, permissions, grantResults); switch (requestCode) { case REQUEST_EXTERNAL_STORAGE: if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) { havePermission = true; Toast.makeText(this, "授权成功!", Toast.LENGTH_SHORT).show(); } else { havePermission = false; Toast.makeText(this, "授权被拒绝!", Toast.LENGTH_SHORT).show(); } break; case REQUEST_PERMISSION_CODE_33: Toast.makeText(this, "授权成功!", Toast.LENGTH_SHORT).show(); break; }
完整代码例子如下
public class MainActivity extends AppCompatActivity { private static final String[] PERMISSIONS_STORAGE = {Manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.WRITE_EXTERNAL_STORAGE}; //请求状态码 private static final int REQUEST_EXTERNAL_STORAGE = 1; //创建Activity生命周期 protected void onCreate(Bundle savedInstanceState) { } //获取Activity焦点的生命周期 @Override protected void onResume() { super.onResume(); checkPermission(); } private AlertDialog dialog; private void checkPermission() { //检查权限(NEED_PERMISSION)是否被授权 PackageManager.PERMISSION_GRANTED表示同意授权 //这里是android7以上就需要动态申请权限 if (Build.VERSION.SDK_INT > Build.VERSION_CODES.M) { if (ActivityCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) { //申请权限 if (dialog != null) { dialog.dismiss(); dialog = null; } dialog = new AlertDialog.Builder(this).setTitle("提示")//设置标题.setMessage("请开启文件访问权限,否则无法正常使用应用!").setPositiveButton("确定", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { dialog.dismiss(); ActivityCompat.requestPermissions(MainActivity.this, PERMISSIONS_STORAGE, REQUEST_EXTERNAL_STORAGE); }}).create(); dialog.show(); } else { havePermission = true; } } else { //android6以下不需要动态申请权限 havePermission = true;} }}@Overridepublic void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { //申请文件读写权限 super.onRequestPermissionsResult(requestCode, permissions, grantResults); switch (requestCode) { case REQUEST_EXTERNAL_STORAGE: if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) { havePermission = true; Toast.makeText(this, "授权成功!", Toast.LENGTH_SHORT).show(); } else { havePermission = false; Toast.makeText(this, "授权被拒绝!", Toast.LENGTH_SHORT).show(); } break; case REQUEST_PERMISSION_CODE_33: Toast.makeText(this, "授权成功!", Toast.LENGTH_SHORT).show(); break; }
下面是第二种情况在Fragment中动态申请权限,因为Fragment是相当于依附在Activity中的页面,所以Fragment中没有回调函数处理,因此需要用到它所在的Activity的activity对象,例如Fragment的定义如下
public class PersonFragment extends Fragment { //定义一个Activity对象,用于给MainActivity赋值 public static Activity context; private static final String[] PERMISSIONS_STORAGE = {Manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.WRITE_EXTERNAL_STORAGE,Manifest.permission.CAMERA}; //请求状态码 private static final int REQUEST_EXTERNAL_STORAGE = 1;} @Override public void onStart() { super.onStart(); checkPermission(); } private AlertDialog dialog; private void checkPermission() { //检查权限(NEED_PERMISSION)是否被授权 PackageManager.PERMISSION_GRANTED表示同意授权 //这里是android7以上就需要动态申请权限 if (Build.VERSION.SDK_INT > Build.VERSION_CODES.M) { if (ActivityCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) { //申请权限 if (dialog != null) { dialog.dismiss(); dialog = null; } dialog = new AlertDialog.Builder(this).setTitle("提示")//设置标题.setMessage("请开启文件访问权限,否则无法正常使用应用!").setPositiveButton("确定", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { dialog.dismiss(); ActivityCompat.requestPermissions(context, PERMISSIONS_STORAGE, REQUEST_EXTERNAL_STORAGE); }}).create(); dialog.show(); } else { havePermission = true; } } else { //android6以下不需要动态申请权限 havePermission = true;} }
那么在MainActivity中我们给上面的Fragment赋值activity对象,那么Fragment就可以在申请权限的时候操做MainActivity的回调函数了,MainActivity代码例子如下
public class MainActivity extends AppCompatActivity { //这里的请求码要和Fragment的请求码一致 private static final int REQUEST_EXTERNAL_STORAGE = 1; //创建Activity生命周期 protected void onCreate(Bundle savedInstanceState) { PersonFragment.context = MainActivity.this }@Overridepublic void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { //申请文件读写权限 super.onRequestPermissionsResult(requestCode, permissions, grantResults); switch (requestCode) { case REQUEST_EXTERNAL_STORAGE: if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) { havePermission = true; Toast.makeText(this, "授权成功!", Toast.LENGTH_SHORT).show(); } else { havePermission = false; Toast.makeText(this, "授权被拒绝!", Toast.LENGTH_SHORT).show(); } break; case REQUEST_PERMISSION_CODE_33: Toast.makeText(this, "授权成功!", Toast.LENGTH_SHORT).show(); break; }
以上例子是对于一些到懂不懂的朋友讲解权限申请与回调函数的关系使用,下面就是android7以下及android11以下以及android13以下的动态权限申请情况
文件读写权限直接上代码了
public class MainActivity extends AppCompatActivity { //申请的权限放进数组里 private static final String[] PERMISSIONS_STORAGE = {Manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.WRITE_EXTERNAL_STORAGE}; //请求状态码 private static final int REQUEST_EXTERNAL_STORAGE = 1; //创建Activity生命周期 protected void onCreate(Bundle savedInstanceState) { } //获取Activity焦点的生命周期 @Override protected void onResume() { super.onResume(); checkPermission(); } private AlertDialog dialog; private void checkPermission() { //检查权限(NEED_PERMISSION)是否被授权 PackageManager.PERMISSION_GRANTED表示同意授权 //这里是android11以上的读写权限申请 //需要通过Settings.ACTION_MANAGE_ALL_FILES_ACCESS_PERMISSION跳转到权限设置打开权限 if (Build.VERSION.SDK_INT >= 30) { if (!Environment.isExternalStorageManager()) { if (dialog != null) { dialog.dismiss(); dialog = null; } dialog = new AlertDialog.Builder(this) .setTitle("提示")//设置标题 .setMessage("请开启文件访问权限,否则无法正常使用本应用!") .setNegativeButton("取消", new DialogInterface.OnClickListener() {@Overridepublic void onClick(DialogInterface dialog, int i) { dialog.dismiss();} }) .setPositiveButton("确定", new DialogInterface.OnClickListener() {@Overridepublic void onClick(DialogInterface dialog, int which) { dialog.dismiss(); Intent intent = new Intent(Settings.ACTION_MANAGE_ALL_FILES_ACCESS_PERMISSION); startActivity(intent);} }).create(); dialog.show(); } else { havePermission = true;} } else { //这里就是android7到android11的权限申请 //直接通过ActivityCompat.requestPermissions就可以 if (Build.VERSION.SDK_INT > Build.VERSION_CODES.M) { if (ActivityCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) { //申请权限 if (dialog != null) { dialog.dismiss(); dialog = null; } dialog = new AlertDialog.Builder(this).setTitle("提示")//设置标题.setMessage("请开启文件访问权限,否则无法正常使用应用!").setPositiveButton("确定", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { dialog.dismiss(); ActivityCompat.requestPermissions(MainActivity.this, PERMISSIONS_STORAGE, REQUEST_EXTERNAL_STORAGE); }}).create(); dialog.show(); } else { havePermission = true; } } else { //android7以下的不需要动态申请权限 havePermission = true; } } } //权限申请成功后的回调函数,可以做提示或其他 @Override public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { //申请文件读写权限 super.onRequestPermissionsResult(requestCode, permissions, grantResults); switch (requestCode) { case REQUEST_EXTERNAL_STORAGE: if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) { havePermission = true; Toast.makeText(this, "授权成功!", Toast.LENGTH_SHORT).show(); } else { havePermission = false; Toast.makeText(this, "授权被拒绝!", Toast.LENGTH_SHORT).show(); } break; case REQUEST_PERMISSION_CODE_33: Toast.makeText(this, "授权成功!", Toast.LENGTH_SHORT).show(); break; } }
相册、相机权限申请情况
这里可能就android13比较特殊,因为android13把相册分成了3个权限,分别是图片申请、视频申请、音频申请
private static final String[] PERMISSIONS_STORAGE = {Manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.WRITE_EXTERNAL_STORAGE, Manifest.permission.CAMERA};//请求状态码private static final int REQUEST_EXTERNAL_STORAGE = 1;//android13相册权限申请变量 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};//请求状态码private static final int REQUEST_PERMISSION_CODE_33 = 2;
那么权限数组可能就不一样了,android13以下的申请读写权限就好了,而android13则可能需要动态申请这3个权限,所以代码如下,这里我用Fragment申请权限
@RequiresApi(api = Build.VERSION_CODES.TIRAMISU)@SuppressLint("StaticFieldLeak")public class PersonFragment extends Fragment { //MainActivity的activity对象 public static Activity context; @Override public void onStart() { super.onStart(); ifHaveAlbumPermission(context) } //打开相册 private void openFile() { Intent intentFromGallery = new Intent(); // 设置文件类型 intentFromGallery.setType("image/*");//选择图片 intentFromGallery.setAction(Intent.ACTION_GET_CONTENT); //你需要使用系统提供的startActivityForResult(Intent intent,int requestCode)方法调用MainActivity的回调函数 context.startActivityForResult(intentFromGallery, REQUEST_PICTURE_CODE); } // 判断是否有文件存储权限 private void ifHaveAlbumPermission(Activity activity) { if (ActivityCompat.checkSelfPermission(activity, Manifest.permission.READ_MEDIA_IMAGES) != PackageManager.PERMISSION_GRANTED) { //android13权限申请 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) { ActivityCompat.requestPermissions(activity, PERMISSIONS_STORAGE_33, REQUEST_PERMISSION_CODE_33); openFile(); } else { //android13以下的权限申请 ActivityCompat.requestPermissions(activity, PERMISSIONS_STORAGE, REQUEST_EXTERNAL_STORAGE); } } else { openFile(); } }}
以上就差不多完成了,相机的情况大同小异,可以看其他博主写的
来源地址:https://blog.csdn.net/m0_59799878/article/details/130795891
免责声明:
① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。
② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341