Android 安卓:下载大文件

Android 安卓:下载大文件,android,asynchronous,download,android-asynctask,Android,Asynchronous,Download,Android Asynctask,我正在尝试从Internet下载大文件(>20Mb) 下载7-15%后,progressbar对话框关闭,我在日志中看到“finish!”。为什么?您应该看看如何实现HTTP范围。这将允许您在下载失败时重新启动下载 至于它为什么会停止,一些运营商实施了下载限制,在一段时间或下载量之后会断开连接。我在一家英国航空公司亲眼目睹了这一点,其他航空公司也告诉了我这一点。通过Androids浏览器下载文件通常很容易验证限制,如果您看到文件暂停或停止,您知道这很可能是运营商的问题(是的,下载可以在不引发异常

我正在尝试从Internet下载大文件(>20Mb)


下载7-15%后,progressbar对话框关闭,我在日志中看到“finish!”。为什么?

您应该看看如何实现HTTP范围。这将允许您在下载失败时重新启动下载

至于它为什么会停止,一些运营商实施了下载限制,在一段时间或下载量之后会断开连接。我在一家英国航空公司亲眼目睹了这一点,其他航空公司也告诉了我这一点。通过Androids浏览器下载文件通常很容易验证限制,如果您看到文件暂停或停止,您知道这很可能是运营商的问题(是的,下载可以在不引发异常的情况下终止)


Http范围实现将允许您从停止的位置继续下载,因此您的doInBackground方法将使用延迟和恢复算法,以便每次连接中断时,您都会等待一段时间,然后尝试从停止下载的位置恢复(当然,还要实施重试限制,这样当手机确实无法下载文件时,就不会出现无限循环)。

有一个非常好的库,它可以处理所有这些问题,并且在网络因未知原因脱机时具有恢复功能。 android库称为PRDownloader,可在Github上找到:

首先,您需要将其添加到gradle文件中,如下所示(当前版本的os 0.6.0)

之后,你可以在我为我开发的应用程序实现的一个类中使用它,如下所示。它使用一个进度对话框,显示下载的百分比,如上所述,在网络离线或用户退出应用程序的情况下,它能够在稍后接收下载。 可根据具体需要进行调整,代码如下:

public class DownloadManager {
private MainActivity activity;
private ProgressDialog progressDialog;

private int downloadStatus;
private String filename="";

private static String dirPath;
private String URL = "https://someurl.com/dummyfile.pdf";

public DownloadManager(MainActivity _activity){
    this.activity=_activity;
    dirPath = Utils.getRootDirPath(activity);
    downloadStatus=0;
}

public void setDownloadUrl(String url){
    this.URL=url;
}

public String getFileNameDirPath(){
    return dirPath+"/"+filename;
};

public void setFilename(String filename){
    this.filename=filename;
}
public String getFilename(){
    return this.filename;
}
public String getDirectoryPath(){
    return this.filename;
}

public void startFileDownload(){
    if (Status.RUNNING == PRDownloader.getStatus(downloadStatus)) {
        PRDownloader.pause(downloadStatus);
        return;
    }

    this.progressDialog = new ProgressDialog(this.activity);
    this.progressDialog.setIndeterminate(true);
    this.progressDialog.setTitle("Title");
    this.progressDialog.setMessage("Downloading file...");
    this.progressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
    this.progressDialog.setCancelable(false);
    this.progressDialog.setMax(100);
    this.progressDialog.show();

    if (Status.PAUSED == PRDownloader.getStatus(downloadStatus)) {
        PRDownloader.resume(downloadStatus);
        return;
    }

    downloadStatus = PRDownloader.download(URL, dirPath, this.filename)
            .build()
            .setOnStartOrResumeListener(new OnStartOrResumeListener() {
                @Override
                public void onStartOrResume() {
                    progressDialog.setIndeterminate(false);
                }
            })
            .setOnPauseListener(new OnPauseListener() {
                @Override
                public void onPause() {
                }
            })
            .setOnCancelListener(new OnCancelListener() {
                @Override
                public void onCancel() {
                    progressDialog.setProgress(0);
                    downloadStatus = 0;
                    progressDialog.setIndeterminate(false);
                    progressDialog.dismiss();
                }
            })
            .setOnProgressListener(new OnProgressListener() {
                @Override
                public void onProgress(Progress progress) {
                    long progressPercent = progress.currentBytes * 100 / progress.totalBytes;
                    progressDialog.setProgress((int) progressPercent);
                    progressDialog.setIndeterminate(false);
                }
            })
            .start(new OnDownloadListener() {
                @Override
                public void onDownloadComplete() {
                    progressDialog.dismiss();
                    activity.fragmentManagement.setCurrentFragment("MapFragment");
                }

                @Override
                public void onError(Error error) {

                    Toast.makeText(activity, "Error downloading file", Toast.LENGTH_SHORT).show();
                    progressDialog.setProgress(0);
                    downloadStatus = 0;
                    progressDialog.setIndeterminate(false);
                    progressDialog.dismiss();
                }
            });
}

public static final class Utils {

    private Utils() {
        // no instance
    }

    public static String getRootDirPath(Context context) {
        if (Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState())) {
            File file = ContextCompat.getExternalFilesDirs(context.getApplicationContext(),
                    null)[0];
            return file.getAbsolutePath();
        } else {
            return context.getApplicationContext().getFilesDir().getAbsolutePath();
        }
    }

    public  static String getProgressDisplayLine(long currentBytes, long totalBytes) {
        return getBytesToMBString(currentBytes) + "/" + getBytesToMBString(totalBytes);
    }

    private static String getBytesToMBString(long bytes){
        return String.format(Locale.ENGLISH, "%.2fMb", bytes / (1024.00 * 1024.00));
    }

}

}

您是在设备或模拟器中尝试过它吗?如果您在模拟器中尝试过它,则它无法正常工作。因为您需要使用high system configuration.emulator。好的,我将在设备上尝试
//output.write(data, 0, count);
    implementation 'com.mindorks.android:prdownloader:0.6.0'
public class DownloadManager {
private MainActivity activity;
private ProgressDialog progressDialog;

private int downloadStatus;
private String filename="";

private static String dirPath;
private String URL = "https://someurl.com/dummyfile.pdf";

public DownloadManager(MainActivity _activity){
    this.activity=_activity;
    dirPath = Utils.getRootDirPath(activity);
    downloadStatus=0;
}

public void setDownloadUrl(String url){
    this.URL=url;
}

public String getFileNameDirPath(){
    return dirPath+"/"+filename;
};

public void setFilename(String filename){
    this.filename=filename;
}
public String getFilename(){
    return this.filename;
}
public String getDirectoryPath(){
    return this.filename;
}

public void startFileDownload(){
    if (Status.RUNNING == PRDownloader.getStatus(downloadStatus)) {
        PRDownloader.pause(downloadStatus);
        return;
    }

    this.progressDialog = new ProgressDialog(this.activity);
    this.progressDialog.setIndeterminate(true);
    this.progressDialog.setTitle("Title");
    this.progressDialog.setMessage("Downloading file...");
    this.progressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
    this.progressDialog.setCancelable(false);
    this.progressDialog.setMax(100);
    this.progressDialog.show();

    if (Status.PAUSED == PRDownloader.getStatus(downloadStatus)) {
        PRDownloader.resume(downloadStatus);
        return;
    }

    downloadStatus = PRDownloader.download(URL, dirPath, this.filename)
            .build()
            .setOnStartOrResumeListener(new OnStartOrResumeListener() {
                @Override
                public void onStartOrResume() {
                    progressDialog.setIndeterminate(false);
                }
            })
            .setOnPauseListener(new OnPauseListener() {
                @Override
                public void onPause() {
                }
            })
            .setOnCancelListener(new OnCancelListener() {
                @Override
                public void onCancel() {
                    progressDialog.setProgress(0);
                    downloadStatus = 0;
                    progressDialog.setIndeterminate(false);
                    progressDialog.dismiss();
                }
            })
            .setOnProgressListener(new OnProgressListener() {
                @Override
                public void onProgress(Progress progress) {
                    long progressPercent = progress.currentBytes * 100 / progress.totalBytes;
                    progressDialog.setProgress((int) progressPercent);
                    progressDialog.setIndeterminate(false);
                }
            })
            .start(new OnDownloadListener() {
                @Override
                public void onDownloadComplete() {
                    progressDialog.dismiss();
                    activity.fragmentManagement.setCurrentFragment("MapFragment");
                }

                @Override
                public void onError(Error error) {

                    Toast.makeText(activity, "Error downloading file", Toast.LENGTH_SHORT).show();
                    progressDialog.setProgress(0);
                    downloadStatus = 0;
                    progressDialog.setIndeterminate(false);
                    progressDialog.dismiss();
                }
            });
}

public static final class Utils {

    private Utils() {
        // no instance
    }

    public static String getRootDirPath(Context context) {
        if (Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState())) {
            File file = ContextCompat.getExternalFilesDirs(context.getApplicationContext(),
                    null)[0];
            return file.getAbsolutePath();
        } else {
            return context.getApplicationContext().getFilesDir().getAbsolutePath();
        }
    }

    public  static String getProgressDisplayLine(long currentBytes, long totalBytes) {
        return getBytesToMBString(currentBytes) + "/" + getBytesToMBString(totalBytes);
    }

    private static String getBytesToMBString(long bytes){
        return String.format(Locale.ENGLISH, "%.2fMb", bytes / (1024.00 * 1024.00));
    }

}