这种问题一看就是权限问题,解决办法如下:
1,查看AndroidManifest.xml文件中是否添加静态读写权限。
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
2,6.0以上系统,查看在进行读写操作时是否动态申请读写权限
void getPermission(){ try{ //需要的权限 String[] permArr={ Manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.WRITE_EXTERNAL_STORAGE, Manifest.permission.MOUNT_UNMOUNT_FILESYSTEMS, }; boolean needReq = false; for(int i=0;i<permArr.length;i++){ if(ContextCompat.checkSelfPermission(this, permArr[i])!= PackageManager.PERMISSION_GRANTED){ needReq = true; break; } } if(needReq) ActivityCompat.requestPermissions(this,permArr,1); }catch (Exception e){ Log.w("动态申请权限时,发生异常。",e); }
3,10.0以上系统,在AndroidManifest.xml文件的application节点下添加
android:requestLegacyExternalStorage="true"
4.Android 11+
android:requestLegacyExternalStorage="true" 失效 如果需要使用公共存储,需要系统签名+
android:sharedUserId="android.uid.system"
我们可以通过Context的getExternalFilesDir(null)方法获取APP专属目录,例如:/storage/emulated/0/Android/data/com.example.myapplication/files如果需要把图片保存到系统相册里可以参考下面代码:
val bitmap = BitmapFactory.decodeResource(resources, R.drawable.image_03) val values = ContentValues(); values.put( MediaStore.MediaColumns.RELATIVE_PATH, Environment.DIRECTORY_PICTURES + File.separator + "MyApplication"); //在图库里显示的文件夹名:MyApplication values.put(MediaStore.MediaColumns.DISPLAY_NAME, "test"); values.put(MediaStore.MediaColumns.MIME_TYPE, "image/jpeg"); values.put(MediaStore.MediaColumns.DATE_ADDED, System.currentTimeMillis() / 1000); values.put(MediaStore.MediaColumns.DATE_MODIFIED, System.currentTimeMillis() / 1000); values.put(MediaStore.MediaColumns.IS_PENDING, 1); val resolver = contentResolver; val uri = resolver.insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values); val out = resolver.openOutputStream(uri!!) bitmap.compress(Bitmap.CompressFormat.JPEG, 50, out) values.clear() values.put(MediaStore.MediaColumns.IS_PENDING, 0) values.putNull(MediaStore.MediaColumns.DATE_EXPIRES) resolver.update(uri, values, null, null)
Android 11 获取存储路径错误 android.system.ErrnoException: open failed: EPERM (Operation not permitted),Android11 不能获取sdcard通用空间路径。 private String getSavePath() { String path; if (Build.VERSION.SDK_INT > 29) { path = mContext.getExternalFilesDir(null).getAbsolutePath() + "/log/update/"; } else { path = Environment.getExternalStorageDirectory().getPath() + "/log/update/"; } return path; } 获取的空间路径为 Android/data/XXXX(应用包名)/log
<!-- Allows an application a broad access to external storage in scoped storage. Intended to be used by few apps that need to manage files on behalf of the users. <p>Protection level: signature|appop|preinstalled --> <permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE" android:permissionGroup="android.permission-group.UNDEFINED" android:protectionLevel="signature|appop|preinstalled" />