简体   繁体   English

如何将文件下载到下载文件夹等

[英]How to download files to downloads folder, etc

With the recent release of Android Q Beta, getExternalStoragePublicDirectory() became deprecated.随着最近发布的 Android Q Beta, getExternalStoragePublicDirectory()已被弃用。 Now if someone wants to create a folder he has to either use getExternalFilesDir() or use MediaStore.现在,如果有人想创建一个文件夹,他必须使用getExternalFilesDir()或使用 MediaStore。 But I am developing an app where the user clicks to download his profile picture and I download it using Firebase Storage.但我正在开发一个应用程序,用户点击下载他的个人资料图片,然后我使用 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.我希望它下载到 Downloads 文件夹中,所以我需要使用已弃用的方法。 Is there a new way to store files in a folder like the Downloads, or Music for Android Q and later?是否有一种新方法可以将文件存储在下载或适用于 Android Q 及更高版本的音乐等文件夹中? 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 .编辑:我确实在这里检查了文档: 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.另外,我使用的是Java ,而不是 Kotlin 。

  1. First,download the image and save to your private folder like so: File file = new File(getExternalFilesDir(), "file.jpg");首先,下载图像并保存到您的私人文件夹,如下所示: File file = new File(getExternalFilesDir(), "file.jpg");

  2. Next, grab the content:// uri of the just downloaded image file like so: Uri sourceUri = resolver.insert( imageCollections, values);接下来,像这样获取刚刚下载的图像文件的 content:// uri: Uri sourceUri = resolver.insert( imageCollections, values);

  3. Then, grab the content:// uri of the destination file in the Download folder of external storage like so: Uri destinationUri = data.getData();然后,像这样在外部存储的下载文件夹中获取目标文件的 content:// uri: Uri destinationUri = data.getData();

  4. Create InputStream from the sourceUri like so: FileInputStream fis = ( FileInputStream ) this.getContentResolver().openInputStream( sourceUri);像这样从 sourceUri 创建 InputStream: FileInputStream fis = ( FileInputStream ) this.getContentResolver().openInputStream( sourceUri);

  5. Create OutputStream from the destinationUri like so: FileOutputStream fos = ( FileOutputStream ) this.getContentResolver().openOutputStream( destination );像这样从 destinationUri 创建 OutputStream: FileOutputStream fos = ( FileOutputStream ) this.getContentResolver().openOutputStream( destination );

  6. 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路径应该是:/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然后,在外部存储的Download文件夹中获取目标文件的content://uri

   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: content:// uri 将被推送到 MainActivity.Override 这个函数的 onActivityResult() 函数,如下所示:

@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.我们现在有了目标和源 content:// uri,从这些 uri 初始化输入和输出流以及将字节从源复制到目标取决于您。

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您是否在此处查看此文档: 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也许这也会对您有所帮助: https : //developer.android.com/guide/topics/providers/document-provider

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM