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

24 浏览
0 Comments

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

嘿,我正在做一个新项目,需要你从我的Dropbox下载一些文件。我添加了一个名为DownloadFile的新类,其中包含下载文件的代码。不知何故,当我点击下载时,应用程序崩溃了。谢谢。

这里是DownloadFile的代码:

package com.Matt7262.download.app;
import android.support.v7.app.ActionBarActivity;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
//聊天机器人库
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(), "正在加载文件...",
                Toast.LENGTH_SHORT).show();
    }
    public void Download() {
        try {
            URL url = new URL("https://dl.dropboxusercontent.com/shz/9cyfz0b45mj6szr/7pBuupNz3N/xecta?token_hash=AAEs9cDFswt98D1IhLnab4dHwhwh5z2Lmhq_N6H-2M0LWg&top_level_offset=6");
            HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();
            urlConnection.setRequestMethod("GET");
            urlConnection.setDoOutput(true);
            urlConnection.connect();
            File SDCardRoot = Environment.getExternalStorageDirectory();
            File file = new File(SDCardRoot,"hello.zip");
            FileOutputStream fileOutput = new FileOutputStream(file);
            InputStream inputStream = urlConnection.getInputStream();
            int totalSize = urlConnection.getContentLength();
            int downloadedSize = 0;
            byte[] buffer = new byte[1024];
            int bufferLength = 0;
            while ((bufferLength = inputStream.read(buffer)) > 0) {
                fileOutput.write(buffer, 0, bufferLength);
                downloadedSize += bufferLength;
                updateProgress(downloadedSize, totalSize);
            }
            fileOutput.close();
        } catch (MalformedURLException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

MainActivity:

package com.Matt7262.download.app;
import android.support.v7.app.ActionBarActivity;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
//聊天机器人库
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);
    }
    public void buttonOnClick(View v) {
        input = (TextView) findViewById(R.id.editText1);
        String dbPath = Environment.getExternalStorageDirectory().getAbsolutePath() + "/Download/Ab";
        Button button=(Button) v;
        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) {
        getMenuInflater().inflate(R.menu.main, menu);
        return true;
    }
    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        int id = item.getItemId();
        if (id == R.id.action_settings) {
            return true;
        }
        return super.onOptionsItemSelected(item);
    }
}

我认为这就是我从logcat中获取的所有内容。

0
0 Comments

在Kotlin中,这个函数很有用,其中的try / catch避免了崩溃并处理了向用户发送Toast的操作。

之后可能需要解压这个文件,所以请参考这个链接

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()

}

问题的原因是需要从URL下载zip文件,解决方法是使用HttpURLConnection打开连接,读取输入流并将其写入文件中。如果文件已经存在,先将其删除。最后,使用Toast向用户显示下载完成的消息。

0
0 Comments

你在声明DownloadFile对象时没有进行初始化。

private DownloadFile df;
df.Download(); // 抛出空指针异常

不要忘记进行初始化。

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

编辑:

现在你初始化了对象并避免了空指针异常,但是这次你遇到了NetworkOnMainThreadException。从Honeycomb版本开始,Android不允许在主线程上进行网络操作。你可以使用AsyncTask来解决这个问题。

谢谢,但是我将private DownloadFile df;放在'public class MainActivity extends ActionBarActivity'下,并且加上df = new DownloadFile(); df.Download();但是还是不起作用。

通过进行初始化,你解决了空指针异常的问题。现在可能是另一个问题。查看一下logcat。

我会在帖子中添加新的logcat。

我添加了新的logcat。

0