File operations in android Q beta

时光毁灭记忆、已成空白 提交于 2019-12-04 15:10:41

In Android API 29 and above you can use the below code to store files, images and videos to external storage.

//First, if your picking your file using "android.media.action.IMAGE_CAPTURE" then store that file in applications private Path(getExternalFilesDir()) as below.

File destination = new File(context.getExternalFilesDir(Environment.DIRECTORY_PICTURES), fileName);

//Then use content provider to get access to Media-store as below.

 ContentValues values = new ContentValues(); 
 values.put(MediaStore.Images.Media.TITLE, fileName); 
 values.put(MediaStore.Images.Media.DISPLAY_NAME, fileName);

//if you want specific mime type, specify your mime type here. otherwise leave it blank, it will take default file mime type

values.put(MediaStore.Images.Media.MIME_TYPE, "MimeType"); 
values.put(MediaStore.Images.Media.DATE_ADDED, System.currentTimeMillis() / 1000); 
values.put(MediaStore.Images.Media.DATE_TAKEN, System.currentTimeMillis()); 
values.put(MediaStore.Images.Media.RELATIVE_PATH, "Pictures/" + "path"); // specify 
 storage path

// insert to media-store using content provider, it will return URI.

Uri uri = cxt.getContentResolver().insert(MediaStore.Files.getContentUri("external"), values); 

//Use that URI to open the file.

ParcelFileDescriptor descriptor = context.getContentResolver().openFileDescriptor(uri,"w"); //"w" specify's write mode
FileDescriptor fileDescriptor = descriptor.getFileDescriptor();

// read file from private path.

InputStream dataInputStream = cxt.openFileInput(privatePath_file_path);

//write file into out file-stream.

 OutputStream output = new FileOutputStream(fileDescriptor);
 byte[] buf = new byte[1024];
 int bytesRead;
 while ((bytesRead = dataInputStream.read(buf)) > 0) 
 {
  output.write(buf, 0, bytesRead);
 }
 datanputStream.close();
 output.close();
}

In Android Q direct File access is disabled by default for the apps outside their private folders. Here few strategies you can use:

  1. Use the manifest option requestLegacyStorage to have the old behavior but it won't work anymore with Android R, so it's really a short term solution;
  2. Save your files using getExternalFilesDir() method. It's your private folder, other apps could access these files only if they have READ_EXTERNAL_STORAGE permission. In this case it would be good to use FileProvider to grant access to other apps to your files.
  3. Use MediaStore API to insert your media directly. This approach is good for videos, music and photos.
  4. Use the method getPrimaryStorageVolume().createOpenDocumentTreeIntent() of class StorageManager to ask for access to the extenal primary volume. In this case you need user consent and you won't be able to use File api directly anyway, but using DocumentFile class you have a very similar interface, so this is the solution closer to the old behavior. It works if you need to perform operations in foreground and background, i.e. without user interaction with the exception the first interaction to request the permission.
  5. Use ACTION_CREATE_DOCUMENT to create a file using SAF. This option is valid if you do this operation in foreground because you will need the folder selection by the user.

I link Flipper library for point 4, it helps to manage files like in older android versions.

Add android:requestLegacyStorage="true" in <application> tag in Android Manifest, which will allow you to use All File APIs, for now.

1)Use Document-provider https://developer.android.com/guide/topics/providers/document-provider#create

2)User will be asked to save(total number of files) and get stored in documents folder. https://gist.github.com/neonankiti/05922cf0a44108a2e2732671ed9ef386

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!