原文: Android項目實戰(三十一):異步下載下傳apk檔案并安裝(非靜默安裝)
前言:
實作異步下載下傳apk檔案 并 安裝。(進度條對話框顯示下載下傳進度的展現方式)
涉及技術點:
1、ProgressDialog 進度條對話框 用于顯示下載下傳進度
2、AsyncTask 異步任務的使用 耗時操作不能再主線程中進行
安卓開發_淺談AsyncTask3、File 檔案相關操作 将檔案的位元組資料生成檔案
4、自動打開安裝應用操作 下載下傳網絡apk資料并生成檔案之後需要我們去執行這個apk的安裝操作(非靜默安裝)
實作前提:
1、我們下載下傳的apk的url位址
2、檔案權限,網絡權限
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> //檔案操作權限
<uses-permission android:name="android.permission.INTERNET" /> //網絡權限
----------------------------------------------------------------------------------------------------------------------------------------
實作:
1、建立ProgressDialog對象,初始化操作,開啟下載下傳的異步任務
private void showDownloadProgressDialog(Context context) {
ProgressDialog progressDialog = new ProgressDialog(context);
progressDialog.setTitle("提示");
progressDialog.setMessage("正在下載下傳...");
progressDialog.setIndeterminate(false);
progressDialog.setMax(100);
progressDialog.setCancelable(false); //設定不可點選界面之外的區域讓對話框小時
progressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL); //進度條類型
progressDialog.show();
String downloadUrl = "http://ac-edNxPKqQ.clouddn.com/800exxxxxxx68ebcefda.apk"; //這裡寫你的apk url位址
new DownloadAPK(progressDialog).execute(downloadUrl);
}
2、下載下傳apk的異步任務
首先看一下整個異步任務的結構
private class DownloadAPK extends AsyncTask<String, Integer, String> {
ProgressDialog progressDialog;
File file;
public DownloadAPK(ProgressDialog progressDialog) {
this.progressDialog = progressDialog;
}
@Override
protected String doInBackground(String... params) {
//根據url擷取網絡資料生成apk檔案
return null;
}
@Override
protected void onProgressUpdate(Integer... progress) {
super.onProgressUpdate(progress);
// 這裡 改變ProgressDialog的進度值
}
@Override
protected void onPostExecute(String s) {
super.onPostExecute(s);
//到這裡說明下載下傳完成,判斷檔案是否存在,如果存在,執行安裝apk的操作
}
}
(1)、 局部變量
ProgressDialog 用于顯示下載下傳進度
File 根據網絡資料生成的apk檔案
ProgressDialog progressDialog;
File file;
(2)、構造方法,将外部的ProgressDialog對象傳到異步任務裡
public DownloadAPK(ProgressDialog progressDialog) {
this.progressDialog = progressDialog;
}
(3)、進度更新方法,将下載下傳進度現在在對話框中
@Override
protected void onProgressUpdate(Integer... progress) {
super.onProgressUpdate(progress);
progressDialog.setProgress(progress[0]);
}
(4)、下載下傳網絡資料生成apk檔案的操作
@Override
protected String doInBackground(String... params) {
URL url;
HttpURLConnection conn;
BufferedInputStream bis = null;
FileOutputStream fos = null;
try {
url = new URL(params[0]);
conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("GET");
conn.setConnectTimeout(5000);
int fileLength = conn.getContentLength();
bis = new BufferedInputStream(conn.getInputStream());
String fileName = Environment.getExternalStorageDirectory().getPath() + "/magkare/action.apk";
file = new File(fileName);
if (!file.exists()) {
if (!file.getParentFile().exists()) {
file.getParentFile().mkdirs();
}
file.createNewFile();
}
fos = new FileOutputStream(file);
byte data[] = new byte[4 * 1024];
long total = 0;
int count;
while ((count = bis.read(data)) != -1) {
total += count;
publishProgress((int) (total * 100 / fileLength));
fos.write(data, 0, count);
fos.flush();
}
fos.flush();
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (fos != null) {
fos.close();
}
} catch (IOException e) {
e.printStackTrace();
}
try {
if (bis != null) {
bis.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
return null;
}
(5)、檔案下載下傳完成後
判斷檔案是否存在,存在的話要打開安裝apk的操作,并關閉進度對話框
不存在的話說明檔案下載下傳失敗,進行相關提示即可
@Override
protected void onPostExecute(String s) {
super.onPostExecute(s);
openFile(file); //打開安裝apk檔案操作
progressDialog.dismiss(); //關閉對話框
}
(6)、打開apk檔案安裝apk的操作
private void openFile(File file) {
if (file!=null){
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setDataAndType(Uri.fromFile(file), "application/vnd.android.package-archive");
TaskListActivity.this.startActivity(intent);
}
}
效果圖:

完整代碼:
private void showDownloadProgressDialog(Context context) {
ProgressDialog progressDialog = new ProgressDialog(context);
progressDialog.setTitle("提示");
progressDialog.setMessage("正在下載下傳...");
progressDialog.setIndeterminate(false);
progressDialog.setMax(100);
progressDialog.setCancelable(false);
progressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
progressDialog.show();
String downloadUrl = "http://ac-edNxPKqQ.clouddn.com/80xxxxxxxebcefda.apk";
new DownloadAPK(progressDialog).execute(downloadUrl);
}
/**
* 下載下傳APK的異步任務
*/
private class DownloadAPK extends AsyncTask<String, Integer, String> {
ProgressDialog progressDialog;
File file;
public DownloadAPK(ProgressDialog progressDialog) {
this.progressDialog = progressDialog;
}
@Override
protected String doInBackground(String... params) {
URL url;
HttpURLConnection conn;
BufferedInputStream bis = null;
FileOutputStream fos = null;
try {
url = new URL(params[0]);
conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("GET");
conn.setConnectTimeout(5000);
int fileLength = conn.getContentLength();
bis = new BufferedInputStream(conn.getInputStream());
String fileName = Environment.getExternalStorageDirectory().getPath() + "/magkare/action.apk";
file = new File(fileName);
if (!file.exists()) {
if (!file.getParentFile().exists()) {
file.getParentFile().mkdirs();
}
file.createNewFile();
}
fos = new FileOutputStream(file);
byte data[] = new byte[4 * 1024];
long total = 0;
int count;
while ((count = bis.read(data)) != -1) {
total += count;
publishProgress((int) (total * 100 / fileLength));
fos.write(data, 0, count);
fos.flush();
}
fos.flush();
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (fos != null) {
fos.close();
}
} catch (IOException e) {
e.printStackTrace();
}
try {
if (bis != null) {
bis.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
return null;
}
@Override
protected void onProgressUpdate(Integer... progress) {
super.onProgressUpdate(progress);
progressDialog.setProgress(progress[0]);
}
@Override
protected void onPostExecute(String s) {
super.onPostExecute(s);
openFile(file);
progressDialog.dismiss();
}
private void openFile(File file) {
if (file!=null){
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setDataAndType(Uri.fromFile(file), "application/vnd.android.package-archive");
TaskListActivity.this.startActivity(intent);
}
}
}
異步下載下傳apk檔案并安裝
------------------------------------------------------------------------------------------------------------------------------------------
注意:
如果是一次性全部擷取到網絡檔案的位元組資料,當檔案過大的時候會出現OOM的問題。
此方法 實作邊下載下傳擷取網絡檔案的位元組資料邊生成檔案的操作。 不用擔心OOM 的問題。 其他檔案下載下傳操作都可以參考此方法。
學習自 : http://www.cnblogs.com/laujiangtao/ 同學