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
<provider
android:name="android.support.v4.content.FileProvider"
android:authorities="com.skt.itrip.fileprovider"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android: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);
}