Android使用AutoUpdateProject库实现自动下载更新很简单,不需要自制UI,不需要写代码(几乎直接复制就行了)
- 在你的项目的根目录的build.gradle添加如下代码:
allprojects { repositories { ... maven { url 'https://jitpack.io' } } }
- 在你的app的目录的build.gradle添加如下代码:
dependencies { implementation 'com.github.MZCretin:AutoUpdateProject:latest_version' }
- 填写版本信息json文件,上传到远程目录,如假设上传到https://www.xxx.com/apps/app-update.json,并将apk上传到配置里的路径:
{
"versionCode": 1144,
"isForceUpdate": 0,
"preBaselineCode": 55,
"versionName": "v1.144",
"downurl": "https://www.xxx.com/apps/app-update.apk",
"updateLog": "v1.144\r\n1、优化体验\n2、修复已知bug",
"size": "5913570",
"hasAffectCodes": "",
"originMD5":"E083D1253220B10F8EACBE21A562C7E2"
}
- 添加版本信息json解析Model文件,保存为UpdateModel.java(代码来源自动更新库的demo):
package com.xxx.app;
import com.cretin.www.cretinautoupdatelibrary.model.LibraryUpdateEntity;
/**
* Created by cretin on 2017/4/21.
* 这个model是调用 http://www.cretinzp.com/system/versioninfo 这个接口之后返回的数据
*/
public class UpdateModel implements LibraryUpdateEntity {
/**
* id : test
* page : 1
* rows : 10
* isForceUpdateFlag : 0
* preBaselineCode : 0
* versionName : V1.0.1
* versionCode : 3
* downurl : http://120.24.5.102/Webconfig/frj01_211_jiagu_sign.apk
* updateLog : 1、修复bug
* size : 10291218
* hasAffectCodes : 1|2
* createTime : 1489651956000
* iosVersion : 1
*/
private int isForceUpdate;
private int preBaselineCode;
private String versionName;
private int versionCode;
private String downurl;
private String updateLog;
private String size;
private String hasAffectCodes;
private long createTime;
private int iosVersion;
private String originMD5;
public int getIsForceUpdate() {
return isForceUpdate;
}
public void setIsForceUpdate(int isForceUpdate) {
this.isForceUpdate = isForceUpdate;
}
public int getPreBaselineCode() {
return preBaselineCode;
}
public void setPreBaselineCode(int preBaselineCode) {
this.preBaselineCode = preBaselineCode;
}
public String getVersionName() {
return versionName;
}
public void setVersionName(String versionName) {
this.versionName = versionName;
}
public int getVersionCode() {
return versionCode;
}
public void setVersionCode(int versionCode) {
this.versionCode = versionCode;
}
public String getDownurl() {
return downurl;
}
public void setDownurl(String downurl) {
this.downurl = downurl;
}
public String getUpdateLog() {
return updateLog;
}
public void setUpdateLog(String updateLog) {
this.updateLog = updateLog;
}
public String getSize() {
return size;
}
public void setSize(String size) {
this.size = size;
}
public String getHasAffectCodes() {
return hasAffectCodes;
}
public void setHasAffectCodes(String hasAffectCodes) {
this.hasAffectCodes = hasAffectCodes;
}
public long getCreateTime() {
return createTime;
}
public void setCreateTime(long createTime) {
this.createTime = createTime;
}
public int getIosVersion() {
return iosVersion;
}
public void setIosVersion(int iosVersion) {
this.iosVersion = iosVersion;
}
public String getOriginMD5() {
return originMD5;
}
public void setOriginMD5(String originMD5) {
this.originMD5 = originMD5;
}
@Override
public int getAppVersionCode() {
return getVersionCode();
}
@Override
public int forceAppUpdateFlag() {
return getIsForceUpdate();
}
@Override
public String getAppVersionName() {
return getVersionName().replaceFirst("v", "");
}
@Override
public String getAppApkUrls() {
return getDownurl();
}
@Override
public String getAppUpdateLog() {
return getUpdateLog();
}
@Override
public String getAppApkSize() {
return getSize();
}
@Override
public String getAppHasAffectCodes() {
return getHasAffectCodes();
}
@Override
public String getFileMd5Check() {
return getOriginMD5();
}
}
- 在app的启动界面或者主界面的onCreate方法中添加检查更新的代码:
//当你希望使用配置请求链接的方式,让插件自己解析并实现更新
UpdateConfig updateConfig = new UpdateConfig()
.setDebug(true)//是否是Debug模式
.setBaseUrl("https://www.xxx.com/apps/app-update.json") ///// 版本信息的url
.setMethodType(TypeConfig.METHOD_GET)
.setDataSourceType(TypeConfig.DATA_SOURCE_TYPE_URL)
.setShowNotification(true)//配置更新的过程中是否在通知栏显示进度
.setUiThemeType(TypeConfig.UI_THEME_B)//配置UI的样式,一种有12种样式可供选择
.setRequestHeaders(null)
.setRequestParams(null)
.setAutoDownloadBackground(false)//是否需要后台静默下载
.setNeedFileMD5Check(false)//是否需要进行文件的MD5检验
.setModelClass(new UpdateModel());
AppUpdateUtils.init(this, updateConfig);
AppUpdateUtils.getInstance().checkUpdate();
至此,App自动下载更新的功能就完成了,接下来是跳转到App应用市场更新部分。
- 由于自动更新库没有提供跳转到App应用市场的功能,只提供自定义更新弹窗UI的功能,所以我们需要添加一个UI,利用自定义的弹窗UI上的“立即更新”按钮来跳转到应用市场,将下面的代码保存到UpdateActivity.java(需要修改tvBtn2.setOnClickListener里的两个变量):
package com.xxx.app;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.net.Uri;
import android.os.Bundle;
import android.text.TextUtils;
import android.text.method.ScrollingMovementMethod;
import android.util.Log;
import android.view.View;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;
import com.cretin.www.cretinautoupdatelibrary.R;
import com.cretin.www.cretinautoupdatelibrary.interfaces.AppDownloadListener;
import com.cretin.www.cretinautoupdatelibrary.model.DownloadInfo;
import com.cretin.www.cretinautoupdatelibrary.utils.LogUtils;
import com.cretin.www.cretinautoupdatelibrary.utils.ResUtils;
import com.cretin.www.cretinautoupdatelibrary.utils.RootActivity;
import java.util.ArrayList;
import java.util.List;
/**
* 类似虎牙直播的更新样式
*/
public class UpdateActivity extends RootActivity {
private TextView tvMsg;
private TextView tvBtn2;
private ImageView ivClose;
private TextView tvVersion;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_update_type2);
findView();
setDataAndListener();
}
private void setDataAndListener() {
tvMsg.setText(downloadInfo.getUpdateLog());
tvMsg.setMovementMethod(ScrollingMovementMethod.getInstance());
tvVersion.setText("v"+downloadInfo.getProdVersionName());
if (downloadInfo.isForceUpdateFlag()) {
ivClose.setVisibility(View.GONE);
} else {
ivClose.setVisibility(View.VISIBLE);
}
ivClose.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
finish();
}
});
tvBtn2.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
//更新按钮
String shopName = "com.tencent.android.qqdownloader"; // 需要修改
String appId = "com.xxx.app"; // 需要修改
if (isAvilible(shopName)) { // 有应用商店
launchAppDetail(appId, shopName);
} else {
download();
}
}
});
}
private void findView() {
tvMsg = findViewById(R.id.tv_content);
tvBtn2 = findViewById(R.id.tv_update);
ivClose = findViewById(R.id.iv_close);
tvVersion = findViewById(R.id.tv_version);
}
@Override
public AppDownloadListener obtainDownloadListener() {
return new AppDownloadListener() {
@Override
public void downloading(int progress) {
tvBtn2.setText(ResUtils.getString(R.string.downloading)+progress+"%");
}
@Override
public void downloadFail(String msg) {
tvBtn2.setText(ResUtils.getString(R.string.btn_update_now));
Toast.makeText(UpdateActivity.this, ResUtils.getString(R.string.apk_file_download_fail), Toast.LENGTH_SHORT).show();
}
@Override
public void downloadComplete(String path) {
tvBtn2.setText(ResUtils.getString(R.string.btn_update_now));
}
@Override
public void downloadStart() {
tvBtn2.setText(ResUtils.getString(R.string.downloading));
}
@Override
public void reDownload() {
LogUtils.log("下载失败后点击重试");
}
@Override
public void pause() {
}
};
}
/**
* 启动Activity
*
* @param context
* @param info
*/
public static void launch(Context context, DownloadInfo info) {
launchActivity(context, info, UpdateActivity.class);
}
/**
* 判断应用市场是否存在的方法
*
*
* 主流应用商店对应的包名
* com.android.vending -----Google Play
* com.tencent.android.qqdownloader -----应用宝
* com.qihoo.appstore -----360手机助手
* com.baidu.appsearch -----百度手机助
* com.xiaomi.market -----小米应用商店
* com.wandoujia.phoenix2 -----豌豆荚
* com.huawei.appmarket -----华为应用市场
* com.taobao.appcenter -----淘宝手机助手
* com.hiapk.marketpho -----安卓市场
* cn.goapk.market -----安智市场
*/
public boolean isAvilible(String marketPkg) {
// 获取packagemanager
final PackageManager packageManager = this.getPackageManager();
// 获取所有已安装程序的包信息
List<PackageInfo> pinfo = packageManager.getInstalledPackages(0);
// 用于存储所有已安装程序的包名
List<String> pName = new ArrayList<String>();
// 从pinfo中将包名字取出
if (pinfo != null) {
for (int i = 0; i < pinfo.size(); i++) {
String pf = pinfo.get(i).packageName;
pName.add(pf);
}
}
// 判断pName中是否有目标程序的包名,有true,没有false
return pName.contains(marketPkg);
}
/**
* 启动到应用商店app详情界面
*
* @param appPkg 目标App的包名
* @param marketPkg 应用商店包名 ,如果为""则由系统弹出应用商店列表供用户选择,否则调转到目标市场的应用详情界面
*/
public void launchAppDetail(String appPkg, String marketPkg) {
try {
if (TextUtils.isEmpty(appPkg)) {
return;
}
Uri uri = Uri.parse("market://details?id=" + appPkg);
Intent intent = new Intent(Intent.ACTION_VIEW, uri);
if (!TextUtils.isEmpty(marketPkg)) {
intent.setPackage(marketPkg);
}
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
this.startActivity(intent);
} catch (Exception e) {
e.printStackTrace();
}
}
}
- 在app的AndroidManifest.xml添加下面的Activity代码:
<activity
android:name=".UpdateActivity"
android:theme="@style/DialogActivityTheme" />
- 修改第五步的代码:
//当你希望使用配置请求链接的方式,让插件自己解析并实现更新
UpdateConfig updateConfig = new UpdateConfig()
.setDebug(true)//是否是Debug模式
.setBaseUrl("https://www.xxx.com/apps/app-update.json") ///// 版本信息的url
.setMethodType(TypeConfig.METHOD_GET)
.setDataSourceType(TypeConfig.DATA_SOURCE_TYPE_URL)
.setShowNotification(true)
.setUiThemeType(TypeConfig.UI_THEME_CUSTOM)//使用自定义UI
.setCustomActivityClass(UpdateActivity.class)//使用自定义UI
.setRequestHeaders(null)
.setRequestParams(null)
.setAutoDownloadBackground(false)
.setNeedFileMD5Check(false)
.setModelClass(new UpdateModel());
AppUpdateUtils.init(this, updateConfig);
AppUpdateUtils.getInstance().checkUpdate();
至此,App自动跳转到App应用市场更新的功能也完成了。
参考:
https://github.com/MZCretin/AutoUpdateProject
https://www.cnblogs.com/showly/p/11088078.html
网友评论