android - android下载代码下载不完整的文件

标签 android android-asynctask download assets

我遵循了一些在线教程并创建了这段代码来下载我在保管箱中托管的文件

我正在使用异步任务来执行此操作

// AsyncTask to download a file
    private class DownloadTask extends AsyncTask<String, Integer, String> {

        private Context context;

        public DownloadTask(Context context) {
            this.context = context;
        }

        @Override
        protected String doInBackground(String... sUrl) {
            // take CPU lock to prevent CPU from going off if the user
            // presses the power button during download
            PowerManager pm = (PowerManager) context
                    .getSystemService(Context.POWER_SERVICE);
            PowerManager.WakeLock wl = pm.newWakeLock(
                    PowerManager.PARTIAL_WAKE_LOCK, getClass().getName());
            wl.acquire();

            try {
                InputStream input = null;
                OutputStream output = null;
                HttpURLConnection connection = null;
                try {
                    URL url = new URL(sUrl[0]);
                    connection = (HttpURLConnection) url.openConnection();
                    connection.connect();

                    // expect HTTP 200 OK, so we don't mistakenly save error
                    // report
                    // instead of the file
                    if (connection.getResponseCode() != HttpURLConnection.HTTP_OK)
                        return "Server returned HTTP "
                                + connection.getResponseCode() + " "
                                + connection.getResponseMessage();

                    // TODO

                    File file = new File(Environment
                            .getExternalStorageDirectory().getPath()
                            + "/kathmandu.map");

                    if (file.exists()) {
                        Log.i("File Exists", "Code Gets here, file exists");
                        return "exists";
                        // if (connection.getResponseCode() ==
                        // HttpURLConnection.HTTP_NOT_MODIFIED) {
                        //
                        // return null;
                        // }
                    }

                    // this will be useful to display download percentage
                    // might be -1: server did not report the length
                    int fileLength = connection.getContentLength();
                    Log.i("Length", String.valueOf(fileLength));

                    // download the file
                    input = connection.getInputStream();
                    output = new FileOutputStream(Environment
                            .getExternalStorageDirectory().getPath()
                            + "/kathmandu.map");

                    byte data[] = new byte[4096];
                    long total = 0;
                    int count;
                    while ((count = input.read(data)) != -1) {
                        // allow canceling with back button
                        if (isCancelled())
                            return null;
                        total += count;
                        // publishing the progress....
                        if (fileLength > 0) // only if total length is known
                            publishProgress((int) (total * 100 / fileLength));
                        output.write(data, 0, count);
                    }
                } catch (Exception e) {
                    return e.toString();
                } finally {
                    try {
                        if (output != null)
                            output.close();
                        if (input != null)
                            input.close();
                    } catch (IOException ignored) {
                    }

                    if (connection != null)
                        connection.disconnect();
                }
            } finally {
                wl.release();
            }
            return null;
        }

我在点击下载选项菜单时调用下载代码。

final DownloadTask downloadTask = new DownloadTask(MapActivity.this);
            downloadTask
                    .execute("https://dl.dropboxusercontent.com/u/95497883/kathmandu-2013-8-12.map");


        mProgressDialog
                .setOnCancelListener(new DialogInterface.OnCancelListener() {
                    @Override
                    public void onCancel(DialogInterface dialog) {
                        downloadTask.cancel(true);
                    }
                });

代码工作正常,但有时输出流没有写入完整文件并退出。一切看起来都很好。文件已下载,但已损坏。

getContentLength() 也返回 -1,因此我无法使用内容长度检查整个文件是否已下载。该文件是离线矢量 map ,我需要它来显示离线 map 。损坏的文件在尝试访问它时会导致运行时异常。有什么方法可以确保文件已正确下载。

我还想通过应用程序本身提供数据。我可以把它放在我的应用程序的 Assets 文件夹中吗?在运行时访问 Assets 文件夹中文件的最佳方式是什么。

最佳答案

您的 Assets 文件夹不可写,因为它是 apk 的一部分。您当然可以像在代码中所做的那样使用应用程序的沙箱存储(使用 Environment.getDir() )或外部存储(使用 Environment.getExternalStorageDirectory() )。

我认为使用 DownloadManager 是一个很好的主意,可以实现您想要的效果,请引用:http://developer.android.com/reference/android/app/DownloadManager.html

一个简短的解决方案

DownloadManager.Request req=new DownloadManager.Request(url);

req.setAllowedNetworkTypes(DownloadManager.Request.NETWORK_WIFI
                               | DownloadManager.Request.NETWORK_MOBILE)
   .setTitle("Downloading")
   .setDescription("Map is Being Downloaded")
   .setDestinationInExternalPublicDir(Environment.getExternalStorageDirectory,
                                      "+/maps_app/something.map");

关于android - android下载代码下载不完整的文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19805342/

相关文章:

Android 即时应用程序 : Strategy for splitting up single activity apps

java - 如何正确地从 Fragment 返回一个变量?

android - 禁止使用 AsyncTask,使用自定义 AsyncTask

android - 在没有下载管理器或第三方库的情况下在连接不良时加载文件

linux - 在Linux中定期从FTP下载文件

android - 兼容 :showAsAction ="always" does not work

android - 使用原生 Android 摄像头时如何限制视频时长?

android - 从 AsyncTask 调用自定义对话框

android - 如何有效地使用 Asynctask

linux - 检查下载/上传是否正在进行