使用Android下载管理器下载文件并保存到应用程序文件夹中

6

如何在我的Android应用程序中从Web服务器下载一些文件并将它们存储在根位置的应用程序文件夹或内部/外部存储器中的私有文件夹中。

我可以下载文件,但是我无法将它们存储在私有文件夹中。

我已经编写了我的下载管理器,但是在其中显示通知(如下载百分比)时遇到了一些问题。


请参考此链接:https://dev59.com/l3A75IYBdhLWcg3w7tx6#3028660。你所说的“private folder”是指什么? - Nilesh Deokar
4个回答

3

我不确定你想用“私人文件夹”做什么...但是这是我如何使用进度回调下载文件的方法:

public class Downloader extends Thread implements Runnable{
    private String url;
    private String path;
    private DownloaderCallback listener=null;

    public Downloader(String path, String url){
        this.path=path;
        this.url=url;
    }

    public void run(){
        try {
            URL url = new URL(this.url);
            URLConnection urlConnection = url.openConnection();
            urlConnection.connect();

            String filename = urlConnection.getHeaderField("Content-Disposition");
            // your filename should be in this header... adapt the next line for your case
            filename = filename.substring(filename.indexOf("filename")+10, filename.length()-2);

            int total = urlConnection.getContentLength();
            int count;

            InputStream input = new BufferedInputStream(url.openStream());
            OutputStream output = new FileOutputStream(path+"/"+filename);

            byte data[] = new byte[4096];
            long current = 0;

            while ((count = input.read(data)) != -1) {
                current += count;
                if(listener!=null){
                    listener.onProgress((int) ((current*100)/total));
                }
                output.write(data, 0, count);
            }

            output.flush();

            output.close();
            input.close();

            if(listener!=null){
                listener.onFinish();
            }
        } catch (Exception e) {
            if(listener!=null)
                listener.onError(e.getMessage());
        }
    }

    public void setDownloaderCallback(DownloaderCallback listener){
        this.listener=listener;
    }

    public interface DownloaderCallback{
        void onProgress(int progress);
        void onFinish();
        void onError(String message);
    }
}

如何使用:

Downloader dl = new Downloader("/path/to/save/file", "http://server.com/download");
dl.setDownloaderCallback(new DownloaderCallback{
    @Override
    void onProgress(int progress){

    }

    @Override
    void onFinish(){

    }

    @Override
    void onError(String message){

    }
});
dl.start();

谢谢您的回答,如何在通知中显示下载进度?当我尝试显示它时,下拉通知栏会有很大的延迟。 - FarshidABZ
这样的结构化答案可以被用作一个公共模块。非常感谢,兄弟! - BharathRao

1

使用DownloadManager下载文件并将其保存到应用程序的私有存储目录中,您可以在setDestinationInExternalFilesDir方法中将目录参数设置为null。这将确保文件被下载到您的应用程序的私有文件存储中,其他应用程序或用户无法访问。

示例

val request = DownloadManager.Request(Uri.parse(fileUrl))
    .setDestinationInExternalFilesDir(context, null, fileName)

完整示例
这是一个完整的函数示例,它可以将文件下载到您的应用程序的私有文件夹中。只需将上下文、文件 URL、文件名和文件描述传递给它,您就可以根据自己的需求进行修改:

private fun downloadFile(
        context: Context,
        fileUrl: String,
        fileName: String,
        fileDescription: String
    ) {
        val request = DownloadManager.Request(Uri.parse(fileUrl))
            .setTitle(fileName)
            .setDescription(fileDescription)
            .setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED)
            .setDestinationInExternalFilesDir(context, null, "$fileName.${getFileExtension(fileUrl)}")

        val downloadManager = context.getSystemService(Context.DOWNLOAD_SERVICE) as? DownloadManager
        downloadManager?.enqueue(request)
    }

这个函数用于获取文件扩展名,以使其无问题地工作:

private fun getFileExtension(fileUrl: String): String {
    return MimeTypeMap.getFileExtensionFromUrl(fileUrl)
}

您可以通过以下方式获取私有应用程序文件的引用:

val privateDir = context.getExternalFilesDir(null)

私人文件夹路径将是:

val path = "/storage/emulated/0/Android/data/com.your.package/files/"

请确保将“com.your.package”更改为您的应用程序包名称。

或者您可以直接从文件引用中获取:

val path = privateDir?.absolutePath

示例
如果您下载了一个名为“image.png”的文件,则该图像的路径将是:

val imagePath = "/storage/emulated/0/Android/data/com.your.package/files/image.png"

0

对于您的私人模式,您需要加密文件并将其存储在SD卡/内部存储器上。请参考this


0
如果你想将下载的文件存储到外部存储器中,你可以使用以下代码。
String storagePath = Environment.getExternalStorageDirectory().getPath()+ "/Directory_name/";
//Log.d("Strorgae in view",""+storagePath);
File f = new File(storagePath);
if (!f.exists()) {
    f.mkdirs();
}
//storagePath.mkdirs();
String pathname = f.toString();
if (!f.exists()) {
    f.mkdirs();
}
//Log.d("Storage ",""+pathname);
dm = (DownloadManager) getSystemService(DOWNLOAD_SERVICE);
Uri uri = Uri.parse(image);
checkImage(uri.getLastPathSegment());
if (!downloaded) {
    DownloadManager.Request request = new DownloadManager.Request(uri);
    request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED);
    request.setDestinationInExternalPublicDir("/Directory_name", uri.getLastPathSegment());
    Long referese = dm.enqueue(request);
    Toast.makeText(getApplicationContext(), "Downloading...", Toast.LENGTH_SHORT).show();
}

谢谢,运行得非常完美。然而,我们不需要“String pathname = f.toString();”,并且下载完成后应将“downloaded”设置为true。 - Amir Dora.

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接