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); } }
代码就是这么简单,如果还是不清楚可以下载下面的源码文件直接使用,如有疑问,欢迎提出。
或者在这里下载:点击打开链接