簡體   English   中英

如何將應用程序生成的文件存儲在 Android 的“下載”文件夾中?

[英]How to store files generated from app in "Downloads" folder of Android?

我正在我的應用程序中生成一個 excelsheet,生成時應自動保存在任何 android 設備的“下載”文件夾中,通常保存所有下載。

我有以下內容將文件保存在“我的文件”文件夾下 -

File file = new File(context.getExternalFilesDir(null), fileName);

導致 -

W/FileUtils﹕ Writing file/storage/emulated/0/Android/data/com.mobileapp/files/temp.xls

我寧願在生成 Excel 表時將生成的文件自動保存在“下載”文件夾中。

更新#1:請在此處查看快照。 我想要的是紅色圈出的那個,如果有意義的話,您建議的內容存儲在藍色圈出的那個 (/storage/emulated/0/download) 中。 請告知我如何將文件保存在紅色圓圈中,即“下載”文件夾,該文件夾不同於“MyFiles”下的 /storage/emulated/0/Download

快照

使用它來獲取目錄:

Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS);

並且不要忘記在您的 manifest.xml 中設置此權限:

<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>

現在從你的問題編輯我認為更好地理解你想要什么。 下載菜單中顯示在紅色圓圈中的文件是實際通過DownloadManager ,盡管我給您的先前步驟會將文件保存在您的下載文件夾中,但它們不會顯示在此菜單中,因為它們沒有被下載. 但是,要完成此操作,您必須啟動文件下載,以便在此處顯示。

以下是如何開始下載的示例:

 DownloadManager.Request request = new DownloadManager.Request(uri);
request.setDestinationInExternalPublicDir(Environment.DIRECTORY_DOWNLOADS, "fileName");
request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED); // to notify when download is complete
request.allowScanningByMediaScanner();// if you want to be available from media players
DownloadManager manager = (DownloadManager) getSystemService(DOWNLOAD_SERVICE);
manager.enqueue(request);

此方法用於從 Uri 下載,我沒有將它與本地文件一起使用。

如果您的文件不是來自互聯網,您可以嘗試保存一個臨時副本並獲取該文件的 Uri 值。

只需使用 DownloadManager 下載生成的文件,如下所示:

File dir = new File("//sdcard//Download//");

File file = new File(dir, fileName);

DownloadManager downloadManager = (DownloadManager) context.getSystemService(DOWNLOAD_SERVICE);

downloadManager.addCompletedDownload(file.getName(), file.getName(), true, "text/plain",file.getAbsolutePath(),file.length(),true);

"text/plain"是您傳遞的 mime 類型,因此它會知道哪些應用程序可以運行下載的文件。 那是為我做的。

我使用以下代碼使其在我的 Xamarin Droid 項目中使用 C# 工作:

// Suppose this is your local file
var file = new byte[] { 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20 };
var fileName = "myFile.pdf";

// Determine where to save your file
var downloadDirectory = Path.Combine(Android.OS.Environment.ExternalStorageDirectory.AbsolutePath, Android.OS.Environment.DirectoryDownloads);
var filePath = Path.Combine(downloadDirectory, fileName);

// Create and save your file to the Android device
var streamWriter = File.Create(filePath);
streamWriter.Close();
File.WriteAllBytes(filePath, file);

// Notify the user about the completed "download"
var downloadManager = DownloadManager.FromContext(Android.App.Application.Context);
downloadManager.AddCompletedDownload(fileName, "myDescription", true, "application/pdf", filePath, File.ReadAllBytes(filePath).Length, true);

現在,您的本地文件已“下載”到您的 Android 設備,用戶會收到通知,並且正在將對該文件的引用添加到下載文件夾中。 但是,請確保在寫入文件系統之前詢問用戶的權限,否則將引發“拒絕訪問”異常。

對於 API 29 及以上

根據文檔,需要將Storage Access Framework用於Other types of shareable content, including downloaded files

應使用系統文件選擇器將文件保存到外部存儲目錄。

將文件復制到外部存儲示例:

// use system file picker Intent to select destination directory
private fun selectExternalStorageFolder(fileName: String) {
    val intent = Intent(Intent.ACTION_CREATE_DOCUMENT).apply {
        addCategory(Intent.CATEGORY_OPENABLE)
        type = "*/*"
        putExtra(Intent.EXTRA_TITLE, name)
    }
    startActivityForResult(intent, FILE_PICKER_REQUEST)
}

// receive Uri for selected directory
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
    super.onActivityResult(requestCode, resultCode, data)
    when (requestCode) {
        FILE_PICKER_REQUEST -> data?.data?.let { destinationUri ->
            copyFileToExternalStorage(destinationUri)
        }
    }
}

// use ContentResolver to write file by Uri
private fun copyFileToExternalStorage(destination: Uri) {
    val yourFile: File = ...

    try {
        val outputStream = contentResolver.openOutputStream(destination) ?: return
        outputStream.write(yourFile.readBytes())
        outputStream.close()
    } catch (e: IOException) {
        e.printStackTrace()
    }
}

處理 API 29 和 30

獲取目錄:

Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS);

在您的 AndroidManifest.xml 中設置此權限:

<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />

將 requestLegacyExternalStorage 添加到 AndroidManifest.xml 中的應用程序標記(適用於 API 29):

<application
    ...
    android:requestLegacyExternalStorage="true">

由於Oluwatumbi已正確回答了這個問題,但首先您需要通過以下代碼檢查是否授予WRITE_EXTERNAL_STORAGE權限:

int MY_PERMISSIONS_REQUEST_WRITE_EXTERNAL_STORAGE = 1;

if (ContextCompat.checkSelfPermission(context, Manifest.permission.WRITE_EXTERNAL_STORAGE)
            != PackageManager.PERMISSION_GRANTED) {
        // Permission is not granted
        // Request for permission
        ActivityCompat.requestPermissions(thisActivity,
                new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE},
                MY_PERMISSIONS_REQUEST_WRITE_EXTERNAL_STORAGE);

    }else{
        Uri uri = Uri.parse(yourUrl);
        DownloadManager.Request request = new DownloadManager.Request(uri);
        request.setDestinationInExternalPublicDir(Environment.DIRECTORY_DOWNLOADS, "fileName");
        request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED); // to notify when download is complete
        request.allowScanningByMediaScanner();// if you want to be available from media players
        DownloadManager manager = (DownloadManager) getSystemService(DOWNLOAD_SERVICE);
        manager.enqueue(request);
    }

這是使用 DownloadManager for Xamarin android api version 29 運行代碼下載文件

public bool DownloadFileByDownloadManager(string imageURL)
        {
            try
            {
                string file_ext = Path.GetExtension(imageURL);
                string file_name = "MyschoolAttachment_" + DateTime.Now.ToString("yyyy MM dd hh mm ss").Replace(" ", "") + file_ext;
                var path = global::Android.OS.Environment.DirectoryDownloads;

                Android.Net.Uri uri = Android.Net.Uri.Parse(imageURL);
                DownloadManager.Request request = new DownloadManager.Request(uri);
                request.SetDestinationInExternalPublicDir(path, file_name);
                request.SetTitle(file_name);
                request.SetNotificationVisibility(DownloadVisibility.VisibleNotifyCompleted); // to notify when download is complete

                // Notify the user about the completed "download"
                var downloadManager = DownloadManager.FromContext(Android.App.Application.Context);

                var d_id = downloadManager.Enqueue(request);
                return true;
            }
            catch (Exception ex)
            {
                UserDialogs.Instance.Alert("Error in download attachment.", "Error", "OK");
                System.Diagnostics.Debug.WriteLine("Error !" + ex.ToString());
                return false;
            }
        }

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM