Skip to content

Commit fd91fed

Browse files
author
muxiannian
committed
v2.0.1 新增文件MD5校验功能
1 parent 394bb50 commit fd91fed

26 files changed

Lines changed: 652 additions & 73 deletions
1 Byte
Binary file not shown.

.idea/caches/gradle_models.ser

2.84 KB
Binary file not shown.

README.md

Lines changed: 51 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,14 @@
1212
+ **已适配Android 6.0,Android 7.0,Android 8.0,Android 9.0。**
1313
+ **提供强制更新,不更新则无法使用APP,同时可以根据后台返回受影响的版本号,可控制多个版本同时被强制更新。**
1414
+ **通知栏图片自定义**
15+
+ **新增文件MD5校验,防止安装文件被恶意替换(2019-10-22 18:48:39添加)**
16+
17+
### 新版本说明
18+
+ 2019-10-22 18:53:42更新新版,版本号为:v2.0.1
19+
+ 新版新增文件的MD5校验
20+
+ 新版新增对文件下载进度的监听
21+
+ 新版新增对文件MD5校验结果的回调
22+
+ DEMO中提供了获取文件MD5检验码的工具页面,也提供了加密工具类Md5Utils
1523

1624
### 博客地址
1725

@@ -51,42 +59,54 @@ dependencies { implementation 'com.github.MZCretin:AutoUpdateProject:latest_vers
5159
**Step 3.** Init it in BaseApplication or MainActivity before using it.And then register BaseApplication in AndroidManifest(Don't forget it).
5260

5361
```java
54-
//更新库配置
55-
UpdateConfig updateConfig = new UpdateConfig()
56-
.setDebug(true)//是否是Debug模式
57-
.setBaseUrl("http://www.cretinzp.com/system/versioninfo")//当dataSourceType为DATA_SOURCE_TYPE_URL时,配置此接口用于获取更新信息
58-
.setMethodType(TypeConfig.METHOD_GET)//当dataSourceType为DATA_SOURCE_TYPE_URL时,设置请求的方法
59-
.setDataSourceType(TypeConfig.DATA_SOURCE_TYPE_URL)//设置获取更新信息的方式
60-
.setShowNotification(true)//配置更新的过程中是否在通知栏显示进度
61-
.setNotificationIconRes(R.mipmap.download_icon)//配置通知栏显示的图标
62-
.setUiThemeType(TypeConfig.UI_THEME_AUTO)//配置UI的样式,一种有12种样式可供选择
63-
.setRequestHeaders(null)//当dataSourceType为DATA_SOURCE_TYPE_URL时,设置请求的请求头
64-
.setRequestParams(null)//当dataSourceType为DATA_SOURCE_TYPE_URL时,设置请求的请求参数
65-
.setCustomActivityClass(CustomActivity.class)//如果你选择的UI样式为TypeConfig.UI_THEME_CUSTOM,那么你需要自定义一个Activity继承自RootActivity,并参照demo实现功能,在此处填写自定义Activity的class
66-
.setModelClass(new UpdateModel());
67-
AppUpdateUtils.init(this, updateConfig);
62+
//更新库配置
63+
UpdateConfig updateConfig = new UpdateConfig()
64+
.setDebug(true)//是否是Debug模式
65+
.setBaseUrl("http://www.cretinzp.com/system/versioninfo")//当dataSourceType为DATA_SOURCE_TYPE_URL时,配置此接口用于获取更新信息
66+
.setMethodType(TypeConfig.METHOD_GET)//当dataSourceType为DATA_SOURCE_TYPE_URL时,设置请求的方法
67+
.setDataSourceType(TypeConfig.DATA_SOURCE_TYPE_URL)//设置获取更新信息的方式
68+
.setShowNotification(true)//配置更新的过程中是否在通知栏显示进度
69+
.setNotificationIconRes(R.mipmap.download_icon)//配置通知栏显示的图标
70+
.setUiThemeType(TypeConfig.UI_THEME_AUTO)//配置UI的样式,一种有12种样式可供选择
71+
.setRequestHeaders(null)//当dataSourceType为DATA_SOURCE_TYPE_URL时,设置请求的请求头
72+
.setRequestParams(null)//当dataSourceType为DATA_SOURCE_TYPE_URL时,设置请求的请求参数
73+
.setCustomActivityClass(CustomActivity.class)//如果你选择的UI样式为TypeConfig.UI_THEME_CUSTOM,那么你需要自定义一个Activity继承自RootActivity,并参照demo实现功能,在此处填写自定义Activity的class
74+
.setNeedFileMD5Check(false)//是否需要进行文件的MD5检验,如果开启需要提供文件本身正确的MD5校验码,DEMO中提供了获取文件MD5检验码的工具页面,也提供了加密工具类Md5Utils
75+
.setModelClass(new UpdateModel());
76+
AppUpdateUtils.init(this, updateConfig);
6877
```
6978

7079
**Step 4.** Start using it wherever you want as below with 3 ways.
7180

7281
```java
73-
//有三种方式实现app更新,您可选其中一种方式来进行,推荐使用第三种方式!
74-
75-
//第一种方式,使用JSON字符串,让sdk自主解析并实现功能
76-
String jsonData = "{\"versionCode\": 25,\"isForceUpdate\": 1,\"preBaselineCode\": 24,\"versionName\": \"v2.3.1\",\"downurl\": \"http://jokesimg.cretinzp.com/apk/app-release_231_jiagu_sign.apk\",\"updateLog\": \"1、优化细节和体验,更加稳定\n2、引入大量优质用户\r\n3、修复已知bug\n4、风格修改\",\"size\": \"31338250\",\"hasAffectCodes\": \"1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20|21|22|23|24\"}";
77-
AppUpdateUtils.getInstance().checkUpdate(jsonData);
78-
79-
//第二种方式,使用MODEL方式,组装好对应的MODEL,传入sdk中
80-
DownloadInfo info = new DownloadInfo().setApkUrl("http://jokesimg.cretinzp.com/apk/app-release_231_jiagu_sign.apk")
81-
.setFileSize(31338250)
82-
.setProdVersionCode(25)
83-
.setProdVersionName("2.3.1")
84-
.setForceUpdateFlag(listModel.isForceUpdate() ? 1 : 0)
85-
.setUpdateLog("1、优化细节和体验,更加稳定\n2、引入大量优质用户\r\n3、修复已知bug\n4、风格修改");
86-
AppUpdateUtils.getInstance().checkUpdate(info);
87-
88-
//第三种方式,在初始化的时候配置接口地址,sdk自主请求+解析实现功能(推荐)
89-
AppUpdateUtils.getInstance().checkUpdate();
82+
//有三种方式实现app更新,您可选其中一种方式来进行,推荐使用第三种方式!
83+
//新增下载进度和MD5检测结果的回调监听 2019-10-22 18:51:19
84+
85+
//第一种方式,使用JSON字符串,让sdk自主解析并实现功能
86+
String jsonData = "{\"versionCode\": 25,\"isForceUpdate\": 1,\"preBaselineCode\": 24,\"versionName\": \"v2.3.1\",\"downurl\": \"http://jokesimg.cretinzp.com/apk/app-release_231_jiagu_sign.apk\",\"updateLog\": \"1、优化细节和体验,更加稳定\n2、引入大量优质用户\r\n3、修复已知bug\n4、风格修改\",\"size\": \"31338250\",\"hasAffectCodes\": \"1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20|21|22|23|24\"}";
87+
AppUpdateUtils.getInstance()
88+
.addMd5CheckListener(...)
89+
.addAppDownloadListener(...)
90+
.checkUpdate(jsonData);
91+
92+
//第二种方式,使用MODEL方式,组装好对应的MODEL,传入sdk中
93+
DownloadInfo info = new DownloadInfo().setApkUrl("http://jokesimg.cretinzp.com/apk/app-release_231_jiagu_sign.apk")
94+
.setFileSize(31338250)
95+
.setProdVersionCode(25)
96+
.setProdVersionName("2.3.1")
97+
.setMd5Check("68919BF998C29DA3F5BD2C0346281AC0")
98+
.setForceUpdateFlag(listModel.isForceUpdate() ? 1 : 0)
99+
.setUpdateLog("1、优化细节和体验,更加稳定\n2、引入大量优质用户\r\n3、修复已知bug\n4、风格修改");
100+
AppUpdateUtils.getInstance()
101+
.addMd5CheckListener(...)
102+
.addAppDownloadListener(...)
103+
.checkUpdate(info);
104+
105+
//第三种方式,在初始化的时候配置接口地址,sdk自主请求+解析实现功能(推荐)
106+
AppUpdateUtils.getInstance()
107+
.addMd5CheckListener(...)
108+
.addAppDownloadListener(...)
109+
.checkUpdate();
90110

91111
```
92112

app/build.gradle

Lines changed: 3 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -28,20 +28,8 @@ dependencies {
2828
implementation 'com.android.support:recyclerview-v7:28.0.0'
2929
implementation 'com.blankj:utilcode:1.25.9'
3030

31-
//使用jirpack
32-
implementation 'com.github.MZCretin:AutoUpdateProject:v2.0.0'
31+
//使用jitpack
32+
// implementation 'com.github.MZCretin:AutoUpdateProject:v2.0.0'
3333
//使用本地库依赖
34-
// implementation project(':cretinautoupdatelibrary')
35-
36-
37-
38-
39-
40-
41-
42-
43-
44-
45-
46-
34+
implementation project(':cretinautoupdatelibrary')
4735
}

app/src/main/AndroidManifest.xml

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,12 @@
1414
android:label="@string/app_name"
1515
android:supportsRtl="true"
1616
android:theme="@style/AppTheme">
17+
<activity
18+
android:name=".MD5HelperActivity"
19+
android:label="文件MD5校验码"></activity>
1720
<activity
1821
android:name=".CustomActivity"
19-
android:theme="@style/DialogActivityTheme"></activity>
22+
android:theme="@style/DialogActivityTheme" />
2023
<activity
2124
android:name=".InfoActivity"
2225
android:label="相关介绍" />

app/src/main/java/com/cretin/www/autoupdateproject/CustomActivity.java

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,15 +8,17 @@
88
import com.cretin.www.cretinautoupdatelibrary.activity.RootActivity;
99
import com.cretin.www.cretinautoupdatelibrary.activity.UpdateType2Activity;
1010
import com.cretin.www.cretinautoupdatelibrary.interfaces.AppDownloadListener;
11+
import com.cretin.www.cretinautoupdatelibrary.interfaces.MD5CheckListener;
1112
import com.cretin.www.cretinautoupdatelibrary.utils.ResUtils;
1213

1314
/**
1415
* 自定义UI类型
1516
* 你需要注意:
1617
* 1、Activity需要继承RootActivity才有效,并实现需要实现的方法
1718
* 2、你需要在你的AndroidManifest.xml中为这个自定义的Activity设置
18-
* @style/DialogActivityTheme 这个对话框的主题;
19-
* 当然这只是建议,你只要撸出来的页面好看,咋地都行
19+
*
20+
* @style/DialogActivityTheme 这个对话框的主题;
21+
* 当然这只是建议,你只要撸出来的页面好看,咋地都行
2022
*/
2123
public class CustomActivity extends RootActivity {
2224
private TextView tvInfo;
@@ -105,4 +107,24 @@ public void pause() {
105107
}
106108
};
107109
}
110+
111+
/**
112+
* 如果需要知道文件MD5校验结果就重写此方法
113+
*
114+
* @return
115+
*/
116+
@Override
117+
public MD5CheckListener obtainMD5CheckListener() {
118+
return new MD5CheckListener() {
119+
@Override
120+
public void fileMd5CheckFail(String originMD5, String localMD5) {
121+
122+
}
123+
124+
@Override
125+
public void fileMd5CheckSuccess() {
126+
127+
}
128+
};
129+
}
108130
}
Lines changed: 122 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,122 @@
1+
package com.cretin.www.autoupdateproject;
2+
3+
import android.content.pm.PackageManager;
4+
import android.os.Build;
5+
import android.os.Bundle;
6+
import android.support.v4.app.ActivityCompat;
7+
import android.support.v4.content.ContextCompat;
8+
import android.support.v7.app.AppCompatActivity;
9+
import android.text.TextUtils;
10+
import android.view.View;
11+
import android.widget.EditText;
12+
import android.widget.TextView;
13+
import android.widget.Toast;
14+
15+
import com.cretin.www.autoupdateproject.utils.Md5Utils;
16+
import com.liulishuo.filedownloader.BaseDownloadTask;
17+
import com.liulishuo.filedownloader.FileDownloadListener;
18+
import com.liulishuo.filedownloader.FileDownloader;
19+
20+
import java.io.File;
21+
22+
import static com.cretin.www.cretinautoupdatelibrary.activity.RootActivity.permission;
23+
import static com.cretin.www.cretinautoupdatelibrary.utils.AppUtils.getAppLocalPath;
24+
25+
public class MD5HelperActivity extends AppCompatActivity {
26+
private TextView tvDownload;
27+
private EditText edContent;
28+
private TextView tvDetails;
29+
private boolean isDownloading;
30+
31+
@Override
32+
protected void onCreate(Bundle savedInstanceState) {
33+
super.onCreate(savedInstanceState);
34+
setContentView(R.layout.activity_md5_helper);
35+
36+
tvDownload = findViewById(R.id.tv_download);
37+
tvDetails = findViewById(R.id.tv_details);
38+
edContent = findViewById(R.id.ed_content);
39+
40+
tvDownload.setOnClickListener(new View.OnClickListener() {
41+
@Override
42+
public void onClick(View v) {
43+
if (isDownloading) {
44+
return;
45+
}
46+
if (TextUtils.isEmpty(edContent.getText().toString().trim())) {
47+
Toast.makeText(MD5HelperActivity.this, "请输入文件下载地址", Toast.LENGTH_SHORT).show();
48+
return;
49+
}
50+
if ((Build.VERSION.SDK_INT < Build.VERSION_CODES.M)) {
51+
downloadFile(edContent.getText().toString().trim());
52+
} else {
53+
//下载权限
54+
int writePermission = ContextCompat.checkSelfPermission(MD5HelperActivity.this, permission);
55+
if (writePermission == PackageManager.PERMISSION_GRANTED) {
56+
//拥有权限则直接下载
57+
downloadFile(edContent.getText().toString().trim());
58+
} else {
59+
// 申请权限
60+
ActivityCompat.requestPermissions(MD5HelperActivity.this, new String[]{permission}, 1000);
61+
}
62+
}
63+
}
64+
});
65+
}
66+
67+
//下载文件
68+
private void downloadFile(String appUrl) {
69+
FileDownloader.setup(this);
70+
71+
final String downloadUpdateApkFilePath = getAppLocalPath("test");
72+
73+
BaseDownloadTask downloadTask = FileDownloader.getImpl().create(appUrl)
74+
.setPath(downloadUpdateApkFilePath);
75+
downloadTask
76+
.addHeader("Accept-Encoding", "identity")
77+
.addHeader("User-Agent", "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/37.0.2062.120 Safari/537.36")
78+
.setListener(new FileDownloadListener() {
79+
@Override
80+
protected void pending(BaseDownloadTask task, int soFarBytes, int totalBytes) {
81+
isDownloading = true;
82+
}
83+
84+
@Override
85+
protected void progress(BaseDownloadTask task, int soFarBytes, int totalBytes) {
86+
tvDownload.setText("已下载:" + (soFarBytes * 100l / totalBytes) + "%");
87+
}
88+
89+
@Override
90+
protected void completed(BaseDownloadTask task) {
91+
isDownloading = false;
92+
tvDownload.setText("下载完成(点击可重新下载)");
93+
//获取校验码
94+
try {
95+
String fileMD5String = Md5Utils.getFileMD5(new File(downloadUpdateApkFilePath));
96+
tvDetails.setText(fileMD5String);
97+
} catch (Exception e) {
98+
e.printStackTrace();
99+
}
100+
}
101+
102+
@Override
103+
protected void paused(BaseDownloadTask task, int soFarBytes, int totalBytes) {
104+
isDownloading = false;
105+
tvDownload.setText("下载出错(点击可重新下载)");
106+
}
107+
108+
@Override
109+
protected void error(BaseDownloadTask task, Throwable e) {
110+
isDownloading = false;
111+
tvDownload.setText("下载出错(点击可重新下载)");
112+
}
113+
114+
@Override
115+
protected void warn(BaseDownloadTask task) {
116+
117+
}
118+
})
119+
.setAutoRetryTimes(3)
120+
.start();
121+
}
122+
}

app/src/main/java/com/cretin/www/autoupdateproject/MainActivity.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@ private void obtainData() {
5252
ListModel listModel = new ListModel();
5353
listModel.setForceUpdate(false);
5454
listModel.setUiTypeValue(300 + i);
55+
listModel.setCheckFileMD5(true);
5556
listModel.setSourceTypeVaule(TypeConfig.DATA_SOURCE_TYPE_MODEL);
5657
list.add(listModel);
5758
}
@@ -87,6 +88,10 @@ public boolean onOptionsItemSelected(MenuItem item) {
8788
AppUpdateUtils.getInstance().checkUpdate(recyclerviewAdapter.jsonDataUnForce);
8889
Toast.makeText(this, "为了展示是真的可以自定义UI的,我写了个很丑的页面", Toast.LENGTH_SHORT).show();
8990
break;
91+
case R.id.action_04:
92+
//获取文件MD5检验码工具
93+
startActivity(new Intent(this, MD5HelperActivity.class));
94+
break;
9095
}
9196
return super.onOptionsItemSelected(item);
9297
}

0 commit comments

Comments
 (0)