Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/196.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
android中的下载代码下载不完整的文件_Android_Android Asynctask_Download_Assets - Fatal编程技术网

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

android中的下载代码下载不完整的文件,android,android-asynctask,download,assets,Android,Android Asynctask,Download,Assets,我遵循了一些在线教程,创建了这段代码来下载我在dropbox中托管的文件 我正在使用异步任务来完成此任务 // AsyncTask to download a file private class DownloadTask extends AsyncTask<String, Integer, String> { private Context context; public DownloadTask(Context context) {

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

我正在使用异步任务来完成此任务

// 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;
        }
代码工作正常,但有时outputstream不写入完整文件并退出。一切看起来都很好。文件已下载,但已损坏

getContentLength()还返回-1,因此我无法检查是否使用内容长度下载了整个文件。该文件是一个脱机矢量贴图,我需要它来显示脱机贴图。损坏的文件在尝试访问时导致运行时异常。是否有办法确保文件已正确下载


此外,我想提供应用程序本身的数据。我可以把它放在我的应用程序的资产文件夹中吗。运行时访问assets文件夹中文件的最佳方式是什么。

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

我认为使用DownloadManager将是一个很好的主意,可以实现您想要的目标。请参考:

简短的解决办法

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");

这是一个好主意,但我不想让用户在下载时执行任何任务。您找到解决方案了吗?
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");