版本检测接口说明:
(1)请求post,无参数
(2)调用地址:http://www.baidu.com/rs/ver/info
(3)返回结果:
{
"verCode": "2",
"verName": "0.1.1.20170428_beta",
"forced": false,
"updateMsg": "优化部分功能",
"apkURL": "http://www.baidu.com/meiriyiti_app/V0.1.1.20170428_beta.apk"
}
原理1(支持android原生开发):
①将最新的apk挂载到自己的网站;
②在APP进入的第一个页面或者版本更新的的入口调用后台版本更新接口,请求到最新版本信息,获取手机上APP的版本号,进行对比。
③如果服务器的版本号比手机安装的版本号大的话,就提醒用户更新最新版。
Android原声版的我这里做了通过apkUrl来自动下载和安装,下面是自动安装的工具类和调用时候的代码:
调用代码:
//声明 private UpdateVersionUtils downloadUtil; //初始化 downloadUtil = new UpdateVersionUtils(getContext()); //在获取服务器的新版本信息后调用 downloadUtil.isNewVersion(getActivity(), verCode, appVersionCode, verName, apkURL, updateMsg, false);
下面是两个用到的工具类 :
import android.app.Activity; import android.app.AlertDialog; import android.app.DownloadManager; import android.content.Context; import android.content.DialogInterface; import android.content.Intent; import android.content.IntentFilter; import android.net.Uri; import android.os.Build; import android.os.Environment; import android.support.v4.content.FileProvider; import android.text.TextUtils; import android.webkit.MimeTypeMap; import com.blankj.utilcode.utils.NetworkUtils; import com.blankj.utilcode.utils.TimeUtils; import com.xiaoyu.adailyproblem.App; import java.io.File; import java.text.SimpleDateFormat; /** * Created by Administrator on 2017/4/12. */ public class UpdateVersionUtils { private static final String APK_TYPE = "application/vnd.android.package-archive"; public static DownloadManager mDownloadManager; // 下载管理器 public static long mDownloadId; // 下载ID private UpdateReceiver mReceiver; /** * 默认构造器, 下载每日一题APK * * @param context 上下文 */ public UpdateVersionUtils(Context context) { initArgs(context); } /** * 下载文件 */ public void download(Activity activity, String verName, String apkURL) { // 设置下载Url Uri resource = Uri.parse(apkURL); DownloadManager.Request request = new DownloadManager.Request(resource); // // 设置文件类型 MimeTypeMap mimeTypeMap = MimeTypeMap.getSingleton(); String mimeString = mimeTypeMap.getMimeTypeFromExtension(MimeTypeMap.getFileExtensionFromUrl(apkURL)); request.setMimeType(mimeString); // 下载完成时在进度条提示 request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED); // 存储sdcard目录的download文件夹 request.setDestinationInExternalPublicDir(Environment.DIRECTORY_DOWNLOADS, "mryt"); request.setTitle(verName); request.setVisibleInDownloadsUi(true); // 开始下载 mDownloadId = mDownloadManager.enqueue(request); activity.registerReceiver(mReceiver, new IntentFilter(DownloadManager.ACTION_DOWNLOAD_COMPLETE)); } // 安装Apk public void installApk(Context context, long downloadApkId, String verName) { File apkFile = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS), verName); Intent install = new Intent(Intent.ACTION_VIEW); install.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { Uri apkUri = FileProvider.getUriForFile(context, context.getPackageName() + ".provider", apkFile); install.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); install.setDataAndType(apkUri, APK_TYPE); } else { install.setDataAndType(Uri.fromFile(apkFile), APK_TYPE); } context.startActivity(install); } // 初始化 private void initArgs(Context context) { mDownloadManager = (DownloadManager) context.getSystemService((Context.DOWNLOAD_SERVICE)); context.registerReceiver(mReceiver, new IntentFilter(DownloadManager.ACTION_DOWNLOAD_COMPLETE)); } public void isNewVersion(Activity activity, int verCode, int appVersionCode, String verName, String apkURL, String updateMsg, boolean isAuto) { if (verCode == appVersionCode) { // 如果版本一致提示当前为最新版本 if (!isAuto) { CustomToastUtils.getInstance().showToast(activity, "当前为最新版本"); }else { } } else { // 否则会弹出提示更新的提示框 showUpdateDialog(activity, isAuto, verCode, verName, updateMsg, apkURL); } } /** * 显示是否更新新版本的对话框 * * @param isAuto 是否自动检测更新 */ public void showUpdateDialog(final Activity activity, boolean isAuto, int verCode, final String verName, String updateMsg, final String apkURL) { String currentDate = TimeUtils.getCurTimeString(new SimpleDateFormat("yyyyMMdd")); String lastDate = ACache.get(activity).getAsString(App.CACHE_KEY_APP_UPDATE_DATE); if (!isAuto || TextUtils.isEmpty(currentDate) || !currentDate.equals(lastDate)) { ACache.get(activity).put(App.CACHE_KEY_APP_UPDATE_DATE, currentDate); new AlertDialog.Builder(activity) .setTitle("发现新版本") .setMessage(updateMsg) .setPositiveButton("立即更新", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialogInterface, int i) { //下载新版本时判断用户当前网络环境,非wifi提示 if (NetworkUtils.isWifiAvailable(activity)) { CustomToastUtils.getInstance().showToast(activity, "当前wifi环境良好,请在通知栏查看下载进度!"); download(activity, verName, apkURL); } else if (NetworkUtils.is4G(activity)) { new AlertDialog.Builder(activity) .setTitle("更新版本") .setMessage("当前4G网络状态良好,您是否要继续下载!") .setPositiveButton("继续下载", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialogInterface, int i) { download(activity, verName, apkURL); } }).setNegativeButton("取消下载", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialogInterface, int i) { return; } }).create().show(); } } }).setNegativeButton("以后再说", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialogInterface, int i) { return; } }).create().show(); } } }
import android.app.DownloadManager; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.database.Cursor; import static com.xiaoyu.adailyproblem.comm.utils.UpdateVersionUtils.mDownloadId; import static com.xiaoyu.adailyproblem.comm.utils.UpdateVersionUtils.mDownloadManager; /** * Created by Administrator on 2017/4/28. */ public class UpdateReceiver extends BroadcastReceiver { UpdateVersionUtils updateVersionUtils; @Override public void onReceive(Context context, Intent intent) { updateVersionUtils = new UpdateVersionUtils(context); long downloadId = intent.getLongExtra(DownloadManager.EXTRA_DOWNLOAD_ID, -1); if (downloadId == mDownloadId) { checkStatus(context); } } /** * 检查下载状态 */ private void checkStatus(Context context) { DownloadManager.Query query = new DownloadManager.Query(); query.setFilterById(mDownloadId); Cursor cursor = mDownloadManager.query(query); if (cursor.moveToFirst()) { int status = cursor.getInt(cursor.getColumnIndex(DownloadManager.COLUMN_STATUS)); switch (status) { //下载暂停 case DownloadManager.STATUS_PAUSED: break; //下载延迟 case DownloadManager.STATUS_PENDING: break; //正在下载 case DownloadManager.STATUS_RUNNING: break; //下载完成 case DownloadManager.STATUS_SUCCESSFUL: updateVersionUtils.installApk(context,mDownloadId,"mryt"); break; //下载失败 case DownloadManager.STATUS_FAILED: CustomToastUtils.getInstance().showToast(context,"下载失败"); break; } } cursor.close(); } }
原理2(支持unity开发Android版):
①在APP进入的第一个页面或者版本更新的的入口调用后台版本更新接口,请求到最新版本信息,获取手机上APP的版本号,进行对比。
②如果服务器的版本号比手机安装的版本号大的话,就提醒用户更新最新版。
③在Assets/Plugins/Android/bin目录下添加一个jar包(网盘),如果有需要的朋友可以私信我。
点击更新按钮的时候调用以下代码:
1 using Assets.Scripts.Common.AudioFrame; 2 using Assets.Scripts.Common.AudioFrame.Core; 3 using LitJson; 4 using System; 5 using System.Collections; 6 using System.Collections.Generic; 7 using UnityEngine; 8 using UnityEngine.UI; 9 10 public class Version : MonoBehaviour { 11 public GameObject Bg; 12 public GameObject VersionBg; 13 public Button VerUpBtn; 14 public Button CloseBtn; 15 public Text TextVerCode; 16 public Text TextMsg; 17 string LocalVersion=""; 18 19 // Use this for initialization 20 void Start () { 21 22 #if UNITY_ANDROID 23 24 LocalVersion = "8"; 25 26 /* 功能:网络请求*/ 27 28 Request request = new Request(); 29 JsonData data = new JsonData(); 30 31 string jsonDataPost = data.ToJson(); 32 StartCoroutine(request.IPostData("ver/info", jsonDataPost, OnMainContentReady)); 33 34 #endif 35 } 36 37 /* 功能:网络请求的委托方法*/ 38 void OnMainContentReady(string jsonResult) 39 { 40 string ServerVersion = ""; 41 string ServerName = ""; 42 string ServerMsg=""; 43 string apkUrl = ""; 44 45 VersionResult verReuslt = JsonUtility.FromJson<VersionResult>(jsonResult); 46 47 if (verReuslt.code == 0) 48 { 49 ServerVersion = verReuslt.data.verCode; 50 ServerName = verReuslt.data.verName ; 51 ServerMsg = verReuslt.data.updateMsg ; 52 apkUrl = verReuslt.data.apkURL; 53 //判断如果服务器的app版本大于用户自身的版本,则提示更新 54 if (ServerVersion != null && "" != ServerVersion) { 55 if (int.Parse(ServerVersion) > int.Parse(LocalVersion)) 56 { 57 VersionBg.SetActive(true); 58 TextVerCode.text = "最新版本:" + ServerName; 59 TextMsg.text = ServerMsg; 60 } 61 62 } 63 64 } 65 } 66 //点击版本更新按钮调用 67 public void ClickVerUpBtn() 68 { 69 GameObject.Find("GameMusic").GetComponent<AudioFrame>().PlayEffect(EffectName.SoundBg); 70 // openApplicationMarket跳转手机应用商店去更新 71 AndroidJavaClass jc = new AndroidJavaClass("com.unity3d.player.UnityPlayer"); 72 AndroidJavaObject jo = jc.GetStatic<AndroidJavaObject>("currentActivity"); 73 jo.Call("openApplicationMarket"); 74 75 } 76 77 public void ClickCloseBtn() 78 { 79 GameObject.Find("GameMusic").GetComponent<AudioFrame>().PlayEffect(EffectName.SoundBg); 80 VersionBg.SetActive(false); 81 82 } 83 84 85 [Serializable] 86 public class VersionResult 87 { 88 /// <summary> 89 /// 90 /// </summary> 91 public int code; /// <summary> 92 /// 登陆成功 93 /// </summary> 94 public string message; /// <summary> 95 /// 96 /// </summary> 97 public VersionData data; /// <summary> 98 /// 99 /// </summary> 100 public int totalCount; /// <summary> 101 /// 102 /// </summary> 103 public int type; /// <summary> 104 /// 105 /// </summary> 106 public int[] lvs; 107 108 } 109 110 [Serializable] 111 public class VersionData 112 { 113 /// <summary> 114 /// 115 /// </summary> 116 public string verCode; /// <summary> 117 /// 118 /// </summary> 119 public string verName; /// <summary> 120 /// 121 /// </summary> 122 public string updateMsg; /// <summary> 123 /// 124 /// </summary> 125 public string apkURL; /// <summary> 126 /// 127 /// </summary> 128 public bool forced; /// <summary> 129 /// 130 /// </summary> 131 132 133 134 } 135 }
此文用了同一个思想,实现了:
①Android原生app的自动更新和安装;
②Unity的Android版app的跳转应用市场更新。