Android手機版本更新,使用okhttp網絡框架進行網絡請求和文件下載操作,使用Handler線程處理progress進度的實時更新,下載之後用戶進行選擇安裝新版本,點擊手機返回鍵或者對話框取消按鈕取消文件下載,代碼簡單易懂,適合初學者,可以直接使用。
第一次寫博客,如有不足之處敬請指教。下面先看效果。
1.首先,得去清單文件配置好權限。
<!-- 允許程序接入網絡 --> <uses-permission android:name="android.permission.INTERNET" /> <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" /> <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" /> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> <uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS" /> <uses-permission android:name="android.permission.DOWNLOAD_WITHOUT_NOTIFICATION" />
2.由於這裏使用到了okhttp框架,所以還要去gradle裏面加上
compile 'com.squareup.okhttp3:okhttp:3.4.1'
3.寫對話框的佈局
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="match_parent" android:background="#00000000" android:gravity="center" android:orientation="vertical"> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_margin="30dp" android:background="@color/white" android:orientation="vertical"> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:background="@drawable/yellowstroke_radiustop3" android:gravity="center" android:orientation="horizontal"> <TextView android:id="@+id/notify_title_tv" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_weight="1" android:gravity="center_vertical" android:paddingLeft="10dp" android:text="發現新版本" android:textColor="@color/white" android:textSize="16sp" /> <TextView android:id="@+id/update_cancel_tv" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center_horizontal" android:padding="10dp" android:text="取消" android:textColor="@color/white" /> </LinearLayout> <TextView android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginTop="10dp" android:text="提醒" android:textColor="@color/colorAccent" android:textSize="16sp" android:visibility="gone" /> <LinearLayout android:id="@+id/progress_linear" android:layout_width="match_parent" android:layout_height="wrap_content" android:gravity="center_vertical" android:orientation="horizontal" android:padding="15dp"> <ProgressBar android:id="@+id/progressBar" style="?android:attr/progressBarStyleHorizontal" android:layout_width="fill_parent" android:layout_height="10dp" android:layout_gravity="center_vertical" android:layout_marginLeft="10dp" android:layout_marginRight="10dp" android:layout_weight="1" android:max="100" android:progress="0" android:progressDrawable="@drawable/download_progress" /> <TextView android:id="@+id/progress_tv" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center_vertical" android:layout_marginRight="10dp" android:text="下載進度:0%" android:textColor="#333333" android:textSize="12sp" /> </LinearLayout> </LinearLayout> </LinearLayout>
4.寫Activity的相關功能實現的代碼
package com.dyl.downloadprogressdialog; import android.app.Activity; import android.app.AlertDialog; import android.app.Dialog; import android.content.Intent; import android.content.pm.PackageInfo; import android.content.pm.PackageManager; import android.net.Uri; import android.os.Bundle; import android.os.Environment; import android.os.Handler; import android.os.Message; import android.view.KeyEvent; import android.view.View; import android.view.ViewGroup; import android.view.Window; import android.widget.ProgressBar; import android.widget.TextView; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import okhttp3.Call; import okhttp3.Callback; import okhttp3.Dispatcher; import okhttp3.OkHttpClient; import okhttp3.Request; import okhttp3.Response; public class MainActivity extends Activity { public static final String HTTP_DOWNLOAD_TEST = "http://o1.exmmw.cn/uploads/soft/20160511/xiamiyy.apk"; public static final String HTTP_BAIDU_URL = "https://www.baidu.com/"; private OkHttpClient client = new OkHttpClient(); private ProgressBar apkprogressBar; private TextView mDownloadTv, progress_tv; private int fileSize, downLoadFileSize; private Dialog versionDialog; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); mDownloadTv = findViewById(R.id.download); mDownloadTv.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { VersionCheck(); } }); } private Handler handler = new Handler() { @Override public void handleMessage(Message msg) { switch (msg.what) { case 0: int p = (int) (((float) msg.arg1 / (float) fileSize) * 100); apkprogressBar.setProgress(p); progress_tv.setText("下載進度:" + p + "%"); break; case 1: versionUpdatePop(); break; } } }; //版本檢查 private void VersionCheck() { new Thread(new Runnable() { @Override public void run() { try { Request request = new Request.Builder().tag("getVersionName").url(HTTP_BAIDU_URL)//請求接口。如果需要傳參拼接到接口後面。 .build();//創建Request 對象 Response response = null; response = client.newCall(request).execute();//得到Response 對象 if (response.isSuccessful()) { String myStr = "response.code()=" + response.code() + "\n+response.message()==" + response.body().string(); PackageManager packageManager = getPackageManager(); PackageInfo packInfo = packageManager.getPackageInfo(getPackageName(), 0); if (!packInfo.versionName.equals(String.valueOf(response.code()))) { Message msg = new Message(); msg.what = 1; handler.sendMessage(msg); } } } catch (Exception e) { e.printStackTrace(); } } }).start(); } // 版本升級彈出框 private void versionUpdatePop() { versionDialog = new AlertDialog.Builder(MainActivity.this).create(); versionDialog.show(); Window window = versionDialog.getWindow(); window.setContentView(R.layout.dialog_download); window.setLayout(android.view.ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT); apkprogressBar = (ProgressBar) window.findViewById(R.id.progressBar); TextView update_cancel_tv = (TextView) window.findViewById(R.id.update_cancel_tv); progress_tv = (TextView) window.findViewById(R.id.progress_tv); update_cancel_tv.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { cancelAll("download"); versionDialog.cancel(); } }); downloadFile(HTTP_DOWNLOAD_TEST); } /** * 下載文件 */ private void downloadFile(String url) { Request request = new Request.Builder().url(url).tag("download").build(); client.newCall(request).enqueue(new Callback() { @Override public void onFailure(Call call, IOException e) { if (e.toString().contains("closed")) { //如果是主動取消的情況下 call.cancel(); } else { } } @Override public void onResponse(Call call, Response response) throws IOException { if (response.isSuccessful()) { try { InputStream is = response.body().byteStream(); fileSize = new Long(response.body().contentLength()).intValue(); String mDestFileDir = Environment.getExternalStorageDirectory() + "/"; String mdestFileName = "Test.apk"; File dir = new File(mDestFileDir); if (!dir.exists()) { dir.mkdirs(); } File file = new File(dir, mdestFileName); FileOutputStream fos = new FileOutputStream(file); byte[] buf = new byte[1024 * 8]; int len = 0; downLoadFileSize = 0; while ((len = is.read(buf)) != -1) { fos.write(buf, 0, len); downLoadFileSize += len; Message msg = new Message(); msg.what = 0; msg.arg1 = downLoadFileSize; handler.sendMessage(msg); } fos.flush(); update(mDestFileDir + mdestFileName); } catch (Exception e) { e.printStackTrace(); } } } }); } // 安裝應用 private void update(String filename) { Intent intent = new Intent(Intent.ACTION_VIEW); intent.setDataAndType(Uri.fromFile(new File(filename)), "application/vnd.android.package-archive");// app.getVersionName() startActivity(intent); } //取消指定標籤的的網絡請求 private void cancelAll(Object tag) { Dispatcher dispatcher = client.dispatcher(); if (tag != null) { synchronized (dispatcher) { for (Call call : dispatcher.queuedCalls()) { if (tag.equals(call.request().tag())) { call.cancel(); } } for (Call call : dispatcher.runningCalls()) { if (tag.equals(call.request().tag())) { call.cancel(); } } } } else { dispatcher.cancelAll(); } } @Override public boolean onKeyDown(int keyCode, KeyEvent event) { //點擊返回鍵去掉版本升級 if (versionDialog != null && versionDialog.isShowing()) { cancelAll("download"); versionDialog.cancel(); } return super.onKeyDown(keyCode, event); } }
代碼就是這麼簡單,如果還是不清楚可以下載下面的源碼文件直接使用,如有疑問,歡迎提出。
或者在這裏下載:點擊打開鏈接