With the recent release of Android Q Beta, getExternalStoragePublicDirectory()
became deprecated. Now if someone wants to create a folder he has to either use getExternalFilesDir()
or use MediaStore. But I am developing an app where the user clicks to download his profile picture and I download it using Firebase Storage. Now, the download process works flawlessly, the real problem is storing it in a file. Now I don't want to store in my private data folder like:
File file = new File(getExternalFilesDir(), "file.jpg");
I want it to download in the Downloads folder, so I need to use the deprecated method. Is there a new way to store files in a folder like the Downloads, or Music for Android Q and later? What should I do?
Note: I had asked this question yesterday in a different manner, but the answers did not satisfy me. So I decided to ask this question with more specific details.
Edit: I did check the documentation here: https://developer.android.com/preview/privacy/scoped-storage . In fact, I've been researching for the previous three days, but I don't know how to implement it in my app. An example would be appreciated.
Also, I'm using Java , and not Kotlin.
First,download the image and save to your private folder like so: File file = new File(getExternalFilesDir(), "file.jpg");
Next, grab the content:// uri of the just downloaded image file like so: Uri sourceUri = resolver.insert( imageCollections, values);
Then, grab the content:// uri of the destination file in the Download folder of external storage like so: Uri destinationUri = data.getData();
Create InputStream from the sourceUri like so: FileInputStream fis = ( FileInputStream ) this.getContentResolver().openInputStream( sourceUri);
Create OutputStream from the destinationUri like so: FileOutputStream fos = ( FileOutputStream ) this.getContentResolver().openOutputStream( destination );
copy file from source to destination .
All together: //after image file is successfully downloaded...
String path = fullPathToRecentlyDownloadedImage;
path should be like:/storage/emulated/0/Android/data/yourAppPackageName/files/ImageFolder/imageName.png
Dont hard code it.
Uri imageCollections = MediaStore.Image.Media.getContentUri( "external" );
ContentValues values = new ContentValues();
values.put( MediaStore.Image.Media.DISPLAY_NAME, nameOfImage );
values.put( MediaStore.Image.Media.MIME_TYPE, imageMimeType );
values.put( MediaStore.Image.Media.DATE_ADDED, dateAdded );
values.put( MediaStore.Image.Media.DATA, path );
Uri sourceUri= resolver.insert( imageCollections , values);
Then, grab the content:// uri of the destination file in the Download folder of external storage
Intent i = new Intent();
if ( Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT ) {
i.setAction( Intent.ACTION_CREATE_DOCUMENT );
i.addCategory( Intent.CATEGORY_OPENABLE );
i.setType( imageMimeType );
i.putExtra( Intent.EXTRA_TITLE, nameOfImage );
startActivityForResult( i, 1000 );
}
The content:// uri will be pushed to onActivityResult() function of MainActivity.Override this function like so:
@Override
public void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
Super.onActivityResult(requestCode, resultCode, data);
if ( requestCode == 1000 && data != null ){
destinationUri = data.getData();
We now have the destination and source content:// uris, initializing Input and Output streams from these uris as well as copying bytes from source to destination is up to you.
Note:The intent code above will open a save as activity, navigate to the Download folder and click save.
Hope will help
Did you check this documentation here: https://developer.android.com/preview/privacy/scoped-storage
In order to access any other file that another app has created, including files in a "downloads" directory, your app must use the Storage Access Framework, which allows the user to select a specific file.
Maybe this will help you also: https://developer.android.com/guide/topics/providers/document-provider
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.