废话少说,直接上干货
1.首先需要你获取本地的程序版本号
//获取当前版本 public int getAppVersion(Context context) { try { PackageInfo packageInfo = context.getPackageManager().getPackageInfo(context.getPackageName(), 0); return packageInfo.versionCode; } catch (PackageManager.NameNotFoundException e) { // 应用程序没有找到,这应该不会发生 e.printStackTrace(); return 0; } }
2,获取服务器APP版本号
我这里是直接发布到蒲公英平台的,所以我直接调用的蒲公英接口,你们这个发布到哪里就直接调用哪里的接口查询一下最新的版本
3.比较当前版本是否小于服务器的版本,判断是否更新
这里是重点
如果需要更新弹出提示框
我遇到的问题,开始没有弹出提示框,改为子线程中运行
// 创建一个新的Thread实例 Thread thread = new Thread(new Runnable() { @Override public void run() { // 在这里执行你的任务 // 这里的代码将在子线程中运行 Looper.prepare(); AlertDialog.Builder builer = new AlertDialog.Builder(LoginActivity.this) ; builer.setTitle("版本升级"); builer.setMessage("软件更新"); //当点确定按钮时从服务器上下载 新的apk 然后安装 builer.setPositiveButton("确定", (dialog, which) -> downLoadApk(updateInfo.downloadURL)); //当点取消按钮时不做任何举动 builer.setNegativeButton("取消", (dialogInterface, i) -> {}); AlertDialog dialog = builer.create(); dialog.show(); Looper.loop(); } }); // 启动线程 thread.start();
下载APK方法downLoadApk
protected void downLoadApk(String dowUrl) { //进度条 final ProgressDialog pd; pd = new ProgressDialog(this); pd.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL); pd.setMessage("正在下载更新"); pd.show(); new Thread(){ @Override public void run() { try { File file = getFileFromServer(dowUrl, pd); //安装APK installAPK(file.getAbsolutePath()); pd.dismiss(); //结束掉进度条对话框 } catch (Exception e) { } }}.start(); }
获取文件下载方法getFileFromServer
public static File getFileFromServer(String path, ProgressDialog pd) throws Exception{ //如果相等的话表示当前的sdcard挂载在手机上并且是可用的 if(Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)){ URL url = new URL(path); HttpURLConnection conn = (HttpURLConnection) url.openConnection(); conn.setConnectTimeout(5000); //获取到文件的大小 pd.setMax(conn.getContentLength()); InputStream is = conn.getInputStream(); File file = new File(Environment.getExternalStorageDirectory(), "爱智牧.apk"); FileOutputStream fos = new FileOutputStream(file); BufferedInputStream bis = new BufferedInputStream(is); byte[] buffer = new byte[1024]; int len ; int total=0; while((len =bis.read(buffer))!=-1){ fos.write(buffer, 0, len); total+= len; //获取当前下载量 pd.setProgress(total); } fos.close(); bis.close(); is.close(); return file; } else{ return null; } }
下载后跳转安装的方法installAPK
/** * * @param Path apk路径 */ public void installAPK(String Path) { File apkFile = new File(Path); if (!apkFile.exists()){ return; } Intent intent = new Intent(Intent.ACTION_VIEW); // 安装完成后,启动app intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); // Android 版本在7.0以上 if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.N){ if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) { boolean hasInstallPermission = this.getPackageManager().canRequestPackageInstalls(); if (!hasInstallPermission) { //请求安装未知应用来源的权限 ActivityCompat.requestPermissions((Activity) this, new String[]{Manifest.permission.REQUEST_INSTALL_PACKAGES}, 6666); } } Uri apkUri = FileProvider.getUriForFile(this, "包名.fileprovider", apkFile); intent.setDataAndType(apkUri, "application/vnd.android.package-archive"); this.startActivity(intent); }else { Log.e("安装","-----333----"); Uri uri = Uri.parse("file://" + apkFile.toString()); intent.setDataAndType(uri, "application/vnd.android.package-archive"); } LoginActivity.this.startActivity(intent); }
说明:因为版本的要求,我们这里获取安装路径需要做一些配置,要不下载apk后不会自动跳转到安装界面。
1.在Android.xml中配置相关权限
这个可能还不够,我在我的项目中只添加了这两个,其他的可以百度查询一下。
<uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE"/>
<!-- 安装未知来源权限-->
<uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES" />
2.在Android.xml中配置provider
<provider
android:name="androidx.core.content.FileProvider"
android:authorities="包名.fileprovider"
android:grantUriPermissions="true"
tools:replace="android:authorities"
android:exported="false">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/provider_paths" />
</provider>
3.在res/xml中新建文件file_paths.xml
<?xml version="1.0" encoding="utf-8"?>
<resources>
<paths>
<external-path path="" name="download"/>
</paths>
</resources>
配置好这些才能自动跳转到安装界面