Android Java - 如何从 URL 下载 zip 文件?

Posted

技术标签:

【中文标题】Android Java - 如何从 URL 下载 zip 文件?【英文标题】:Android Java - How to download zip file from URL? 【发布时间】:2014-05-28 05:15:08 【问题描述】:

嘿,我正在制作一个新项目,需要您从我的 Dropbox 下载一些文件。我添加了一个名为 DownloadFile 的新类,其中包含下载文件的代码。由于某种原因,当我单击下载时应用程序崩溃。谢谢。

这是下载文件:

    package com.Matt7262.download.app;

    import android.support.v7.app.ActionBarActivity;
    import android.os.Bundle;
    import android.view.Menu;
    import android.view.MenuItem;
    //Chat bot library
    import org.alicebot.ab.Chat;
    import org.alicebot.ab.Bot;

    import android.view.View;
    import android.widget.Button;
    import android.os.Environment;
    import android.widget.TextView;
    import android.widget.Toast;

    import java.io.InputStream;
    import java.net.URL;
    import java.io.DataInputStream;
    import java.io.DataOutputStream;
    import java.io.File;
    import java.io.FileNotFoundException;
    import java.io.FileOutputStream;
    import java.io.IOException;
    import java.net.HttpURLConnection;
    import java.net.MalformedURLException;
    import android.widget.ProgressBar;
    import java.net.URL;
    import java.net.URLConnection;
    import android.app.Activity;
    import android.app.ProgressDialog;
    import android.os.Environment;
    import android.view.View.OnClickListener;

    public class DownloadFile extends ActionBarActivity

    public void updateProgress(int currentSize, int totalSize)
    
        Toast.makeText(getApplicationContext(), "Loading Files...",
                Toast.LENGTH_SHORT).show();
    

    public void Download()
    
        try 
            //set the download URL, a url that points to a file on the internet
            //this is the file to be downloaded
            URL url = new URL("https://dl.dropboxusercontent.com/shz/9cyfz0b45mj6szr/7pBuupNz3N/xecta?token_hash=AAEs9cDFswt98D1IhLnab4dHwhwh5z2Lmhq_N6H-2M0LWg&top_level_offset=6");

            //create the new connection
            HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();

            //set up some things on the connection
            urlConnection.setRequestMethod("GET");
            urlConnection.setDoOutput(true);

            //and connect!
            urlConnection.connect();

            //set the path where we want to save the file
            //in this case, going to save it on the root directory of the
            //sd card.
            File SDCardRoot = Environment.getExternalStorageDirectory();
            //create a new file, specifying the path, and the filename
            //which we want to save the file as.
            File file = new File(SDCardRoot,"hello.zip");

            //this will be used to write the downloaded data into the file we created
            FileOutputStream fileOutput = new FileOutputStream(file);

            //this will be used in reading the data from the internet
            InputStream inputStream = urlConnection.getInputStream();

            //this is the total size of the file
            int totalSize = urlConnection.getContentLength();
            //variable to store total downloaded bytes
            int downloadedSize = 0;

            //create a buffer...
            byte[] buffer = new byte[1024];
            int bufferLength = 0; //used to store a temporary size of the buffer

            //now, read through the input buffer and write the contents to the file
            while ( (bufferLength = inputStream.read(buffer)) > 0 ) 
                //add the data in the buffer to the file in the file output stream (the file on the sd card
                fileOutput.write(buffer, 0, bufferLength);
                //add up the size so we know how much is downloaded
                downloadedSize += bufferLength;
                //this is where you would do something to report the prgress, like this maybe
                updateProgress(downloadedSize, totalSize);

            
            //close the output stream when done
            fileOutput.close();

            //catch some possible errors...
         catch (MalformedURLException e) 
            e.printStackTrace();
         catch (IOException e) 
            e.printStackTrace();
        
    
    

主活动:

package com.Matt7262.download.app;

import android.support.v7.app.ActionBarActivity;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
//Chat bot library
import org.alicebot.ab.Chat;
import org.alicebot.ab.Bot;

import android.view.View;
import android.widget.Button;
import android.os.Environment;
import android.widget.TextView;
import android.widget.Toast;

import android.os.AsyncTask;

public class MainActivity extends ActionBarActivity 

    TextView input;
    String dPath = Environment.getExternalStorageDirectory().getAbsolutePath() + "/Download";
    private DownloadFile df;

    @Override
    protected void onCreate(Bundle savedInstanceState) 
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    

    //EditText mEdit = (EditText)findViewById(R.id.editText1);

    public void buttonOnClick(View v)
    
        input = (TextView) findViewById(R.id.editText1);

        String dbPath = Environment.getExternalStorageDirectory().getAbsolutePath() + "/Download/Ab";

        Button button=(Button) v;

        //Creating bot
        String botname="xecta";
        String path= dbPath;
        Bot xecta = new Bot(botname, path);

        Chat chatSession = new Chat(xecta);

        String request = input.getText().toString();
        String response = chatSession.multisentenceRespond(request);
        ((Button) v).setText(response);
    

    public void onClickDownload(View view)
    
        df.Download();
    

    @Override
    public boolean onCreateOptionsMenu(Menu menu) 

        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.main, menu);
        return true;
    

    @Override
    public boolean onOptionsItemSelected(MenuItem item) 
        // Handle action bar item clicks here. The action bar will
        // automatically handle clicks on the Home/Up button, so long
        // as you specify a parent activity in AndroidManifest.xml.
        int id = item.getItemId();
        if (id == R.id.action_settings) 
            return true;
        
        return super.onOptionsItemSelected(item);
    

    /*public void updateProgress(int currentSize, int totalSize)
    
        Toast.makeText(getApplicationContext(), "Retrieving Files...",
                Toast.LENGTH_SHORT).show();
    /*

    /*public void Download()
    
        try 
            //set the download URL, a url that points to a file on the internet
            //this is the file to be downloaded
            URL url = new URL("https://dl.dropboxusercontent.com/shz/9cyfz0b45mj6szr/7pBuupNz3N/xecta?token_hash=AAEs9cDFswt98D1IhLnab4dHwhwh5z2Lmhq_N6H-2M0LWg&top_level_offset=6");

            //create the new connection
            HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();

            //set up some things on the connection
            urlConnection.setRequestMethod("GET");
            urlConnection.setDoOutput(true);

            //and connect!
            urlConnection.connect();

            //set the path where we want to save the file
            //in this case, going to save it on the root directory of the
            //sd card.
            File SDCardRoot = Environment.getExternalStorageDirectory();
            //create a new file, specifying the path, and the filename
            //which we want to save the file as.
            File file = new File(SDCardRoot,"hello.zip");

            //this will be used to write the downloaded data into the file we created
            FileOutputStream fileOutput = new FileOutputStream(file);

            //this will be used in reading the data from the internet
            InputStream inputStream = urlConnection.getInputStream();

            //this is the total size of the file
            int totalSize = urlConnection.getContentLength();
            //variable to store total downloaded bytes
            int downloadedSize = 0;

            //create a buffer...
            byte[] buffer = new byte[1024];
            int bufferLength = 0; //used to store a temporary size of the buffer

            //now, read through the input buffer and write the contents to the file
            while ( (bufferLength = inputStream.read(buffer)) > 0 ) 
                //add the data in the buffer to the file in the file output stream (the file on the sd card
                fileOutput.write(buffer, 0, bufferLength);
                //add up the size so we know how much is downloaded
                downloadedSize += bufferLength;
                //this is where you would do something to report the prgress, like this maybe
                updateProgress(downloadedSize, totalSize);

            
            //close the output stream when done
            fileOutput.close();

         //catch some possible errors...
         catch (MalformedURLException e) 
            e.printStackTrace();
         catch (IOException e) 
            e.printStackTrace();
        
    */



我想这就是我从 logcat 中得到的全部内容:

logcat

【问题讨论】:

应用程序可能崩溃,因为您尝试在 uithread 上下载。尝试构建一个新的异步任务来为您下载文件:) 我该怎么做@Pphoenix?谢谢:) @Pphoenix asynctask 在与 UI 有交互(更新)时使用! @SELMANON 啊,是的,我只是假设他使用了 UI 更新 :) 【参考方案1】:

您正在声明 DownloadFile 对象,但未对其进行初始化。

private DownloadFile df;
df.Download(); // Throws NPE

别忘了初始化它。

private DownloadFile df = new DownloadFile();
df.Download();

编辑:

现在你初始化了对象并避免了 NPE,但这次你得到了一个NetworkOnMainThreadException。 Honeycomb 版本之后,Android 不允许在主线程上进行网络操作。您可以使用AsyncTask 来解决这个问题。

【讨论】:

谢谢@Tim,但我把私有的 DownloadFile df;在“公共类 MainActivity 扩展 ActionBarActivity”下并放置 df = new DownloadFile(); df.Download();但它仍然不起作用。 通过初始化它,你解决了 NPE 问题。现在可能是另一个问题。看看logcat。 我会在帖子中添加新的 logcat。 @蒂姆 我添加了新的 logcat @Tim 谢谢@Tim,这有帮助

以上是关于Android Java - 如何从 URL 下载 zip 文件?的主要内容,如果未能解决你的问题,请参考以下文章

如何从包含 Android 上自动下载图片的 url 中读取图片?

如何从java中的url下载图像?

如何从 Java 中的给定 URL 下载 PDF? [复制]

从url下载pdf,在flutter中保存到android中的手机本地存储

如何从android中的url解析xml?

coverflow android:如何从coverflow中的url获取图像