Android Java - 如何从URL下载zip文件?
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中获取的所有内容。
在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向用户显示下载完成的消息。
你在声明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。