Android 软件升级
Android 软件升级:
逻辑:1.首先获取本地版本号和服务器版本号,如果服务器版本号大于本地版本号,则需要更新,否则不需要更新。
2. 如果需要更新,那么先查看下本地是否有这个安装包,如果有则直接安装,如果没有则需要网络下载,下载完成时直接安装。(下载的安装包命名:淘宝3.0.2.apk)
3. 那么应该在什么地方更新呢?如图:
应该在①②处判断更新,倘若在①处判断了,则不必在②处判断,倘若是登录状态,则会直接进入main页面,此时需要在②处判断,另外还需要在设置中的软件更新处判断(如果有这个需求)
注意:6.0需要动态获取读取权限。
package com.skt.itrip.common;
import android.app.AlertDialog;
import android.app.Dialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.SharedPreferences;
import android.net.Uri;
import android.os.Build;
import android.os.Environment;
import android.support.v4.content.FileProvider;import com.skt.itrip.R;
import com.skt.itrip.dialog.DownloadDialog;
import com.zhy.http.okhttp.OkHttpUtils;
import com.zhy.http.okhttp.callback.FileCallBack;import java.io.File;
import okhttp3.Call;
import okhttp3.Request;public class UpdateUtils {
private static Dialog mDownloadDialog;
private static SharedPreferences sp;/**
* 版本对比,如果服务器的版本 > 本地版本 ----->升级
*/
public static boolean CheckUpdate(Context context,int serverVersionCode, int localVersionCode,String serverVersionName){
if(serverVersionCode > localVersionCode){
hasNewVersion(context,true,serverVersionName,serverVersionCode);
return true;
}else{
hasNewVersion(context,false,serverVersionName,serverVersionCode);
return false;
}
// return true;
}private static void hasNewVersion(Context context,boolean hasNewVersion,String serverVersionName,int serverVersionCode){
sp = context.getSharedPreferences(Constant.SP_FILE_NAME, Context.MODE_PRIVATE);
SharedPreferences.Editor editor = sp.edit();
editor.putBoolean("hasNewVersion", hasNewVersion);
editor.putString("serverVersionName", serverVersionName);
editor.putInt("serverVersionCode", serverVersionCode);
editor.apply();
}public static void notNewVersionShow(final Context context, String localVersionName, int localVersionCode) {
String sb = context.getResources().getString(R.string.current_version) +
localVersionName +
" Code:" +
localVersionCode +
",已是最新版,无需更新!";
Dialog dialog = new android.support.v7.app.AlertDialog.Builder(context).setTitle(context.getResources().getString(R.string.update_software))
.setMessage(sb)// 设置内容
.setPositiveButton(context.getResources().getString(R.string.common_confirm),// 设置确定按钮
new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog,
int which) {
dialog.dismiss();
}
}).create();// 创建
// 显示对话框
dialog.show();
}
/**
* 升级
*/
public static void doNewVersionUpdate(final Context context, String localVersionName, int localVersionCode, final String serverVersionName, int serverVersionCode) {
String sb = context.getResources().getString(R.string.current_version) +
localVersionName +
" Code:" +
localVersionCode +
", 发现新版本:" +
serverVersionName +
" Code:" +
serverVersionCode +
", 是否更新?";
Dialog dialog = new AlertDialog.Builder(context)
.setTitle(context.getResources().getString(R.string.update_software))
.setMessage(sb)
.setCancelable(false)
// 设置内容
.setPositiveButton(context.getResources().getString(R.string.update_now),// 设置确定按钮
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog,
int which) {//先检查本地有没有,如果本地存在,直接安装
if(fileIsExists(getPath(context))){
LOG.e("localFile","path==" + getPath(context));
File file = new File(getPath(context));
install(context,file);
}else{//网络下载
mDownloadDialog = DownloadDialog.createdownloadDialog(context);
DownloadDialog.showDialog(mDownloadDialog);
//执行下载操作downloadFile(context,serverVersionName);
}
}
})
.setNegativeButton(context.getResources().getString(R.string.update_later),
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog,
int whichButton) {
// 点击"取消"按钮之后退出程序
// finish();
dialog.dismiss();
}}).create();// 创建
// 显示对话框
dialog.show();
}private static String getPath(Context context){
sp = context.getSharedPreferences("skt_demo", Context.MODE_PRIVATE);
return sp.getString("apkPath","");
}// 下载时给文件命名时带上服务器返回的最新的版本号,然后去查找手机里有无该文件,有就直接安装,否则下载
// 文件命名可以是应用名+版本号
private static boolean fileIsExists(String strFile)
{
try
{
File f=new File(strFile);
if(!f.exists())
{
return false;
}}
catch (Exception e)
{
return false;
}return true;
}private static void downloadFile(final Context context,final String serverVersionName)
{
String downLoadUrl = Constant.baseUrl + "AppWebService.do?downloadLocal";
OkHttpUtils//
.get()//
.url(downLoadUrl)//
.build()//
.execute(new FileCallBack(Environment.getExternalStorageDirectory().getAbsolutePath(), context.getString(R.string.app_name) + serverVersionName + ".apk")//
{@Override
public void onBefore(Request request, int id)
{}
@Override
public void inProgress(float progress, long total, int id)
{
LOG.e("AlterPasswordModelImpl","inProgress :" + (int) (100 * progress));
DownloadDialog.setProgress((int) (100 * progress));}
@Override
public void onError(Call call, Exception e, int id)
{
LOG.e("AlterPasswordModelImpl", "onError :" + e.getMessage());
DownloadDialog.closeDialog(mDownloadDialog);
ShowToast.showToast("下载失败,请检查网络连接",context);
}@Override
public void onResponse(File file, int id)
{
LOG.e("localFile", "onResponse :" + file.getAbsolutePath());
// /storage/emulated/0/旅行家3.apk
saveFilePath(context,file.getAbsolutePath());
DownloadDialog.closeDialog(mDownloadDialog);
install(context,file);
}
});
}private static void saveFilePath(Context context,String path){
sp = context.getSharedPreferences("skt_demo", Context.MODE_PRIVATE);
SharedPreferences.Editor editor = sp.edit();
editor.putString("apkPath", path);
editor.apply();
}/**
* 安装apk
*
* @param context
* Context
* @param apkFile
* apk文件
*/
private static void install(Context context, File apkFile) {
Intent intent = new Intent(Intent.ACTION_VIEW);
Uri uri;
if (Build.VERSION.SDK_INT >= 24) {// 7.0+
uri = FileProvider.getUriForFile(context, "com.skt.itrip.fileprovider", apkFile);
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
} else {
uri = Uri.fromFile(apkFile);
}
intent.setDataAndType(uri, "application/vnd.android.package-archive");
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(intent);
}}
调用:
/** * 获取版本信息成功的回调 */
@Override
public void getServerVersionSuccess(int serverVersionCode,String serverVersionName) {
// url = "http://www.goodstong.com/apk/hgwl-v1.1.0-beta4.apk";
this.serverVersionName = serverVersionName;
this.serverVersionCode = serverVersionCode;
if(UpdateUtils.CheckUpdate(context,serverVersionCode,localVersionCode,serverVersionName)){//需要更新 checkPermission();
}
}
/*** 动态申请读取权限*/ private void checkPermission(){if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {//6.0以上if(context.checkSelfPermission(Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED &&context.checkSelfPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {// 申请一个(或多个)权限,并提供用于回调返回的获取码(用户定义)requestPermissions( new String[]{Manifest.permission.READ_EXTERNAL_STORAGE,Manifest.permission.WRITE_EXTERNAL_STORAGE }, CODE_READ_EXTERNAL_STORAGE);}else{UpdateUtils.doNewVersionUpdate(context,localVersionName,localVersionCode,serverVersionName,serverVersionCode); // 更新新版本}}else{UpdateUtils.doNewVersionUpdate(context,localVersionName,localVersionCode,serverVersionName,serverVersionCode); // 更新新版本} }/*** 动态申请权限的回调*/ @Override public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {super.onRequestPermissionsResult(requestCode, permissions,grantResults);switch(requestCode) {// requestCode即所声明的权限获取码,在checkSelfPermission时传入case CODE_READ_EXTERNAL_STORAGE:if(grantResults[0] == PackageManager.PERMISSION_GRANTED) {// 获取到权限,作相应处理(调用定位SDK应当确保相关权限均被授权,否则可能引起定位失败)UpdateUtils.doNewVersionUpdate(context,localVersionName,localVersionCode,serverVersionName,serverVersionCode); // 更新新版本} else{Toast.makeText(context,"没有获取读取手机权限,请到应用中心手动打开该权限",Toast.LENGTH_SHORT).show();// 没有获取到权限,做特殊处理}break;} }
8.0:
<!-- 用于8.0允许安装未知来源的apk -->
<uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES" />
7.0:manifest.xml
<providerandroid:name="android.support.v4.content.FileProvider"android:authorities="com.skt.itrip.fileprovider"android:exported="false"android:grantUriPermissions="true"><meta-dataandroid:name="android.support.FILE_PROVIDER_PATHS"android:resource="@xml/file_paths" />
</provider>
file_paths.xml:
<?xml version="1.0" encoding="utf-8"?>
<resource xmlns:android="http://schemas.android.com/apk/res/android"><external-path name="name" path="" /><!--<cache-path name="name" path="path" />-->
</resource >
.java
private static void install(Context context, File apkFile) {
Intent intent = new Intent(Intent.ACTION_VIEW);
Uri uri;
if (Build.VERSION.SDK_INT >= 24) {// 7.0+
uri = FileProvider.getUriForFile(context, "com.skt.itrip.fileprovider", apkFile);
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
} else {
uri = Uri.fromFile(apkFile);
}
intent.setDataAndType(uri, "application/vnd.android.package-archive");
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(intent);
}
资源:https://download.csdn.net/download/silence_sep/10438031
常用工具类:https://download.csdn.net/download/silence_sep/10438088
Android 软件升级相关推荐
- 有道云笔记 协作android版,有道云笔记Android版升级_软件资讯软件快报-中关村在线...
有道云笔记2.5.0发布: 有道云笔记2.5.0 软件大小:17.6MB 应用平台:Android 软件特点:增加笔记离线阅读与收藏. 有道云笔记Android版升级至2.5版,增加了iPhone版中 ...
- android电视系统升级,如何对安卓电视机进行固件(软件)升级?
如果电视机已连接到网络,将电视机的"自动检查更新"或"自动软件下载"功能打开,则当有适用的新软件升级推送时,电视机会自动下载. 对于2018至2020年发布的如 ...
- 【转】Android OTA 升级之一:编译升级包
Android OTA 升级之一:编译升级包 作者: 宋立新 Email : zjujoe@yahoo.com 前言 OTA 升级是 Android 系统提供的标准软件升级方式. 它功能强大,提供了完 ...
- Android OTA 升级之三:生成recovery.img
Android OTA 升级之三:生成recovery.img 作者: 宋立新 Email:zjujoe@yahoo.com 前言 得到了ota升级包后,我们就可以用它来升级系统了.Android 手 ...
- 逆向Android软件的步骤
2019独角兽企业重金招聘Python工程师标准>>> 逆向Android软件的步骤: 首先使用反编译的工具对反编译,然后阅读反汇编代码,如果有必要还会对其进行动态调试,找到突破口后 ...
- android studio 无法输入中文,Android Studio 升级到3.0后输入法中文状态下无法选词的终极解决方案...
AndroidStudio终于出3.0正式版了,内置了kotlin(虽然我安了插件一直能用).一直忍着没敢下rc版的好奇猫,总算装了正式版.当然,伴随每次大版本更新,总有一些恼人的后遗症,其中以gra ...
- android ROM ---(1)高通平台 Android O 升级学习
1. Android Project Treble 与iOS相比,安卓系统有一个致命弱点,那就是新版本系统升级太慢,除了谷歌Nexus和Pixel等亲儿子机型,其他OEM商的机型更新新系统需要用户漫长 ...
- tcl电视linux软件升级,【高清范】TCL电视升级刷机常见问题大汇总!
原标题:[高清范]TCL电视升级刷机常见问题大汇总! 升级花屏倒屏解决办法: 遥控器按键:062598+子菜单+XXX,XXX即屏参数代码,为三位阿拉伯数字,如010,055,实际操作时如从001,0 ...
- 国内最全的Android市场,最全Android软件商店
摘要: 2010年在国内出现了Android系统智能机的大规模发展,而应用商城也在火拼起来,下面我推荐一下国内Android的免费软件商城.开始吧: 迈奔灵动(mAPPn) 机锋市场 海量Androi ...
最新文章
- HarmonyOS 输入框TextField的使用
- R语言gganimate包创建可视化gif动图、并使用anim_save函数保存可视化gif动图(gganimate export to gif)
- 年中盘点:2021年炙手可热的10家数据科学和机器学习初创公司
- Python 笔试集(4):True + True == ?
- BLE Mesh(2)—— 基本术语及含义
- 斯坦福CS229机器学习课程的数学基础(概率论)翻译完成
- 内存条ar开头的如何看大小_软网推荐:明明白白看内存
- 我对架构师的理解(如何成为一个合格的架构师)
- HDU(1175),连连看,BFS
- 【图像处理】MATLAB:表示与描述
- python正则表达式re模块_详解Python正则表达式re模块
- c语言循环重新输入Y,大佬们帮帮忙 帮我改改 怎样能在输入Y后 再次进行for循环...
- Navicat MySql 注册码
- 极简fseek()函数讲解,一分钟掌握
- Excel自定义格式详解
- python题目-奇偶数调用函数
- intelx79服务器芯片组,Intel X79 高速芯片组是什么
- 前端之路:一款轻量的tooltip插件tippy.js
- grep、sed、awk
- TPO “Java运行环境未找到”
热门文章
- DEPRECATION: Python 2.7 reached the end of its life on January 1st, 2020. Please upgrade your Pytho
- PHP对接阿里云虚拟号-号码隐私保护
- Windows下安装python2与python3以及分别对应的virtualenv
- JavaScript中的 NaN 与 isNaN
- Allegro PCB封装焊盘介绍(一)
- speedtree树木软件for unity(导出树木/草随风飘动画)
- 【C语言】英文文章出现次数最多的单词
- python3环境下使用cv_bridge
- 源码推荐:目前为止最为接近iBook的翻页效果
- 微信iOS7.0.9更新!除了朋友圈可以评论表情包,还有这些你可能不知道的功能!