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

ehxuflar  于 2023-04-18  发布在  Android
关注(0)|答案(2)|浏览(177)

嘿,我正在做一个新项目,需要你从我的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

i7uaboj4

i7uaboj41#

您正在声明DownloadFile对象,但没有初始化它。

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

别忘了初始化它。

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

编辑:

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

j2datikz

j2datikz2#

Kotlin中,这个函数可能很有用,这里的try/catch避免崩溃和handle send吐司给用户。
之后可能需要解压此文件,所以请查看此链接https://stackoverflow.com/a/76032406/12272687

fun downloadZip() {

        val url = URL("http://www.Any.com/sub/name.zip")

        Thread {
            try {
                val con: HttpURLConnection = url.openConnection() as HttpURLConnection
                con.doInput = true
                con.connectTimeout = 1200
                con.connect()
                val responseCode = con.responseCode
               

                if (responseCode == HttpURLConnection.HTTP_OK) {
                    val m = con.inputStream
                    val inStream = BufferedInputStream(m, 1024 * 5)
                    val myFilename = "newFile"
                    val myExtensionVar = ".zip"
                    val file = File(
                        context.getDir("Music", AppCompatActivity.MODE_PRIVATE),
                        "/$myFilename$myExtensionVar"
                    )
                    
                    Log.i("well", "Downloaded file: $file")
                    if (file.exists()) {
                       file.delete()
                       
                    }else{
                    val buff = ByteArray(5 * 1024)
                    // Create File (Copy)
                    file.createNewFile()
                    val outStream = FileOutputStream(file)
                    var len:Int
                    while (inStream.read(buff).also { len = it } >= 0) {

                        outStream.write(buff, 0, len)

                    }

                    outStream.flush()
                    outStream.close()
                    inStream.close()
                    Log.i("well", "Done file: $file")

                    handler.post {
                        Toast.makeText(
                            context,
                            context.getString(R.string.mes_end_file), Toast.LENGTH_SHORT
                        ).show()
                      

                      
                    }
                    }
                }
            } catch (ex: Exception) {
                ex.printStackTrace()
                handler.sendMessage(handler.obtainMessage(22, "OK"))
            } catch (ex: IllegalThreadStateException){
                println( ex.printStackTrace())
                handler.sendMessage(handler.obtainMessage(22, "OK"))
            }

        }.start()

相关问题