1 在manifests中加上
<provider
android:name="android.support.v4.content.FileProvider"
android:authorities="包名"
android:exported="false"
android:grantUriPermissions="true">
<!-- 元数据 -->
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/file_path" />
</provider>
2在闪屏页
2.1请求获取最新版本信息
相关实体:
-
@Data public class ApkUpdate implements java.io.Serializable { /** app更新id */ private String apkUpdateId; /** 版本名称 */ private String versionName; /** 版本号 */ private String versionCode; /** 版本描述 */ private String versiondes; /** 下载地址 */ private String downloadUrl; /** 更新时间 */ private String updateTime; }
2.2 获取本地版本号
-
@Override public int getVersionCode() { //1,包管理者对象packageManager PackageManager pm = MyApp.getContext().getPackageManager(); //2,从包的管理者对象中,获取指定包名的基本信息(版本名称,版本号),传0代表获取基本信息 try { PackageInfo packageInfo = pm.getPackageInfo(MyApp.getContext().getPackageName(), 0); //3,获取版本名称 return packageInfo.versionCode; } catch (Exception e) { e.printStackTrace(); } return 0; }
2.3对比版本做相关逻辑
-
//对比本地版本和服务器版本 if(localVersion < Integer.valueOf(apkUpdate.getVersionCode())){ //更新 showUpdateDialog(apkUpdate); }else{ //跳到登陆 ((ISplashView)weakReference.get()).turnToLogin(); }
2.4弹框提示更新
-
/** * 弹出对话框,提示用户更新 */ private void showUpdateDialog(ApkUpdate apkUpdate) { //对话框,是依赖于activity存在的 AlertDialog.Builder builder = new AlertDialog.Builder(weakReference.get().getContext()); //设置左上角图标 builder.setIcon(R.drawable.common_logo); builder.setTitle(MyApp.getContext().getString(R.string.splash_update_tips)); //设置描述内容 builder.setMessage(apkUpdate.getVersiondes()); //更新按钮 builder.setPositiveButton(MyApp.getContext().getString(R.string.splash_update), (dialog, which) -> { //下载apk,apk链接地址,downloadUrl downloadApk(apkUpdate); //跳到登陆 ((ISplashView)weakReference.get()).turnToLogin(); }); //稍后再说按钮 builder.setNegativeButton(MyApp.getContext().getString(R.string.splash_version_speak_later), (dialog, which) -> { //跳到登陆 ((ISplashView)weakReference.get()).turnToLogin(); }); //点击取消事件监听 builder.setOnCancelListener(dialog -> { //跳到登陆 ((ISplashView)weakReference.get()).turnToLogin(); dialog.dismiss(); }); builder.show(); }
2.5下载
-
/** * 下载 * @param apkUpdate apkUpdate */ private void downloadApk(ApkUpdate apkUpdate) { //1,判断sd卡是否可用,是否挂在上 if(Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)){ //2,获取sd路径 String path = Environment.getExternalStorageDirectory().getAbsolutePath() + File.separator+apkUpdate.getDownloadUrl().split("/")[apkUpdate.getDownloadUrl().split("/").length-1]; //3,发送请求,获取apk,并且放置到指定路径 InstallUtils.download(apkUpdate.getDownloadUrl(),path,weakReference.get().getContext()); } }
2.6下载安装工具类
-
public class InstallUtils { static NotificationManager mNotifyManager; static NotificationCompat.Builder mBuilder; /** * 下载工具类 * * @param url 下载url * @param path 本地path */ @SuppressWarnings("deprecation") public static void download(String url, final String path, final Context context) { mNotifyManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE); //mBuilder = new NotificationCompat.Builder(context); mBuilder = new NotificationCompat.Builder(context, createNotificationChannel(context)); mBuilder.setContentTitle("版本更新") .setContentText("正在下载...") .setContentInfo("0%") .setSmallIcon(R.mipmap.ic_launcher); RequestParams params = new RequestParams(url); //设置断点续传 params.setAutoResume(true); params.setSaveFilePath(path); x.http().get(params, new Callback.ProgressCallback<File>() { @Override public void onWaiting() { } @Override public void onStarted() { Toast.makeText(x.app(), "开始下载", Toast.LENGTH_LONG).show(); } @Override public void onLoading(long total, long current, boolean isDownloading) { BigDecimal b = new BigDecimal((float) current / (float) total); float f1 = b.setScale(2, BigDecimal.ROUND_HALF_UP).floatValue(); mBuilder.setProgress(100, (int) (f1 * 100), false); mBuilder.setContentInfo((int) (f1 * 100) + "%"); mNotifyManager.notify(1, mBuilder.build()); } @Override public void onSuccess(File result) { mBuilder.setContentText("正在下载...") // Removes the progress bar .setProgress(0, 0, false); mNotifyManager.notify(1, mBuilder.build()); mNotifyManager.cancel(1); Toast.makeText(x.app(), "下载成功", Toast.LENGTH_LONG).show(); //installApp(context, path); installApk(context, new File(path)); } @Override public void onError(Throwable ex, boolean isOnCallback) { } @Override public void onCancelled(CancelledException cex) { } @Override public void onFinished() { } }); } /** * 安装 * @param mContext * @param apkFile */ public static void installApk(Context mContext, File apkFile) { try{ if (!apkFile.exists()) { return; } Intent intent = new Intent(Intent.ACTION_VIEW); intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { //Uri uriForFile = FileProvider.getUriForFile(mContext, mContext.getApplicationContext().getPackageName() + ".provider", apkFile); Uri uriForFile = FileProvider.getUriForFile(mContext, "包名", apkFile); intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); intent.setDataAndType(uriForFile, mContext.getContentResolver().getType(uriForFile)); }else { intent.setDataAndType(Uri.fromFile(apkFile), "application/vnd.android.package-archive"); } mContext.startActivity(intent); }catch (Exception e){ e.printStackTrace(); ToastUtils.showShort("自动安装失败,请尝试手动安装!"); } } /** * 9.0的通知 * 在设置渠道的时候需要设置到系统中去 * @param context context * @return */ public static String createNotificationChannel(Context context) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { String channelId = "channelId"; CharSequence channelName = "channelName"; String channelDescription ="channelDescription"; int channelImportance = NotificationManager.IMPORTANCE_DEFAULT; NotificationChannel notificationChannel = new NotificationChannel(channelId, channelName, channelImportance); // 设置描述 最长30字符 notificationChannel.setDescription(channelDescription); // 该渠道的通知是否使用震动 notificationChannel.enableVibration(true); // 设置显示模式 notificationChannel.setLockscreenVisibility(NotificationCompat.VISIBILITY_PUBLIC); NotificationManager notificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE); notificationManager.createNotificationChannel(notificationChannel); return channelId; } else { return null; } }