Android版本更新并安装工具类
2017-08-11 11:07
204 查看
自己用系统的DownloadManager工具封装了一个版本更新帮助类,代码如下:
1.功能具体实现的Java代码
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
2.用到的布局文件dialog_custom.xml,放在layout目录下
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
3.用到的背景设置dialog_background.xml文件,放在drawable目录下
2
3
4
5
1
2
3
4
5
使用说明书
* 说明:版本更新帮助类,负责下载apk文件并打开安装
* 用法:直接new本类,构造方法里分别传
* Context Activity的context
* String apk下载地址
* boolean 允许跳过本次更新
* 示例:
* 普通版本更新 new VersionUpdataHelper(MainActivity.this, info.getUrl());
* 强制版本更新 new VersionUpdataHelper(MainActivity.this, info.getUrl(), false);
*
测试过红米note 4.4,三星 5.1.1,华为 6.0系统
1.功能具体实现的Java代码
public class VersionUpdataHelper { private static final String TAG = "VersionUpdataHelper"; public static final String DOWNLOAD_FILE_NAME = "new_version.apk"; private Context mContext; private DownloadManager mDownloadManager; private String mUrl; private long mDownloadId; private CompleteReceiver mReceiver; private int mCancleDownload; private CustomDialog mDialog; private CustomDialog.Builder mBuilder; private boolean mCancelable; public VersionUpdataHelper(Context context, String url){ this(context, url, true); } public VersionUpdataHelper(Context context, String url, boolean cancelable) { mContext = context; mUrl = url; mCancelable = cancelable; showNewVersionDialog(); } private void showNewVersionDialog() { mBuilder = new CustomDialog.Builder(mContext); mBuilder.setMessage("发现新版本,是否下载并更新...") .setPositiveButton("确定", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { dialog.dismiss(); startDownload(mUrl); initDownloadingDialog(); mDialog.show(); mCancleDownload = 0; } }); if (mCancelable) { mBuilder.setNegativeButton("取消", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { dialog.dismiss(); } }); } mDialog = mBuilder.create(); mDialog.setCancelable(false); mDialog.show(); } private void initDownloadingDialog() { mCancleDownload = 0; mBuilder = new CustomDialog.Builder(mContext); mBuilder.setMessage("软件更新中..."); mBuilder.setNegativeButton("取消", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { mDownloadManager.remove(mDownloadId); dialog.dismiss(); mCancleDownload = 1; unregisterUpdataReceiver(); } }); mDialog = mBuilder.create(); mReceiver = new CompleteReceiver(); mContext. 11fd7 registerReceiver(mReceiver, new IntentFilter(DownloadManager.ACTION_DOWNLOAD_COMPLETE)); } public void unregisterUpdataReceiver() { mContext.unregisterReceiver(mReceiver); } private void startDownload(String url) { mDownloadManager = (DownloadManager) mContext.getSystemService(Context.DOWNLOAD_SERVICE); Uri resource = Uri.parse(url); DownloadManager.Request request = new DownloadManager.Request(resource); request.setAllowedNetworkTypes(DownloadManager.Request.NETWORK_MOBILE | DownloadManager.Request.NETWORK_WIFI); request.setAllowedOverRoaming(false); MimeTypeMap mimeTypeMap = MimeTypeMap.getSingleton(); String mimeString = mimeTypeMap.getMimeTypeFromExtension(MimeTypeMap.getFileExtensionFromUrl(url)); request.setMimeType(mimeString); request.setShowRunningNotification(true); request.setVisibleInDownloadsUi(true); request.setDestinationInExternalPublicDir(Environment.DIRECTORY_DOWNLOADS, DOWNLOAD_FILE_NAME); mDownloadId = mDownloadManager.enqueue(request); mContext.getContentResolver().registerContentObserver(Uri.parse("content://downloads/"), true, new DownloadObserver(handler, mContext, mDownloadId)); } //启动安装 private void openFile(long downloadId) { if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) { Intent updateApk = new Intent(Intent.ACTION_VIEW); Uri downloadFileUri = mDownloadManager.getUriForDownloadedFile(downloadId); updateApk.setDataAndType(downloadFileUri, "application/vnd.android.package-archive"); updateApk.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); mContext.startActivity(updateApk); } else { File file = new File(Environment.getExternalStorageDirectory().getAbsolutePath() + "/" + Environment.DIRECTORY_DOWNLOADS + "/", DOWNLOAD_FILE_NAME); openFile(file, mContext); } } public void openFile(File file, Context context) { Intent intent = new Intent(); intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); intent.setAction(Intent.ACTION_VIEW); String mimeType = getMIMEType(file); intent.setDataAndType(Uri.fromFile(file), mimeType); try { context.startActivity(intent); } catch (Exception e) { e.printStackTrace(); } } public String getMIMEType(File file) { String type = ""; String name = file.getName(); String fileName = name.substring(name.lastIndexOf(".") + 1, name.length()).toLowerCase(); type = MimeTypeMap.getSingleton().getMimeTypeFromExtension(fileName); return type; } public class CompleteReceiver extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { long completeDownloadId = intent.getLongExtra(DownloadManager.EXTRA_DOWNLOAD_ID, -1); if (mDownloadId == completeDownloadId && mCancleDownload == 0) { mDialog.dismiss(); openFile(completeDownloadId); unregisterUpdataReceiver(); } } } private Handler handler = new Handler() { @Override public void handleMessage(Message msg) { float mDownloadSoFar = (float) msg.arg1 / (1024 * 1024); float mDownloadAll = (float) msg.arg2 / (1024 * 1024); DecimalFormat decimalFormat = new DecimalFormat("0.00"); if (mDialog.isShowing()) { TextView mDownloadDialogMessageCancelTv = (TextView) mDialog.findViewById(R.id.tv_dialog_message); mDownloadDialogMessageCancelTv.setText("已下载" + decimalFormat.format(mDownloadSoFar) + "M,共" + decimalFormat.format(mDownloadAll) + "M"); } } }; public class DownloadObserver extends ContentObserver { private long downid; private Handler handler; private Context context; public DownloadObserver(Handler handler, Context context, long downid) { super(handler); this.handler = handler; this.downid = downid; this.context = context; } @Override public void onChange(boolean selfChange) { super.onChange(selfChange); DownloadManager.Query query = new DownloadManager.Query().setFilterById(downid); DownloadManager downloadManager = (DownloadManager) context.getSystemService(Context.DOWNLOAD_SERVICE); Cursor cursor = downloadManager.query(query); while (cursor.moveToNext()) { int mDownload_so_far = cursor.getInt(cursor.getColumnIndexOrThrow(DownloadManager.COLUMN_BYTES_DOWNLOADED_SO_FAR)); int mDownload_all = cursor.getInt(cursor.getColumnIndexOrThrow(DownloadManager.COLUMN_TOTAL_SIZE_BYTES)); if (mDownload_so_far < 0) { mDownload_so_far = 0; } Message message = Message.obtain(); message.arg1 = mDownload_so_far; message.arg2 = mDownload_all; message.obj = downid; handler.sendMessage(message); } } } public static class CustomDialog extends Dialog { private TextView mMessageTv; private Button mPositiveBtn; private Button mNegativeBtn; private View mButtonDividerView; private String message; private String positiveButtonText; private String negativeButtonText; private OnClickListener positiveButtonClickListener; private OnClickListener negativeButtonClickListener; public CustomDialog(Context context) { super(context); } public CustomDialog(Context context, int theme) { super(context, theme); } @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.dialog_custom); mMessageTv = (TextView) findViewById(R.id.tv_dialog_message); mPositiveBtn = (Button) findViewById(R.id.btn_dialog_positive); mNegativeBtn = (Button) findViewById(R.id.btn_dialog_negative); mButtonDividerView = findViewById(R.id.view_dialog_button_divider); if (message != null) { mMessageTv.setText(message); } if (positiveButtonText != null) { mPositiveBtn.setText(positiveButtonText); if (positiveButtonClickListener != null) { mPositiveBtn.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { positiveButtonClickListener.onClick(CustomDialog.this, Dialog.BUTTON_POSITIVE); } }); } } else { mPositiveBtn.setVisibility(View.GONE); mButtonDividerView.setVisibility(View.GONE); } if (negativeButtonText != null) { mNegativeBtn.setText(negativeButtonText); if (negativeButtonClickListener != null) { mNegativeBtn.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { negativeButtonClickListener.onClick(CustomDialog.this, Dialog.BUTTON_NEGATIVE); } }); } } else { mNegativeBtn.setVisibility(View.GONE); mButtonDividerView.setVisibility(View.GONE); } } private void setMessage(String msg) { message = msg; } private void setPositiveButtonText(String text) { positiveButtonText = text; } private void setNegativeButtonText(String text) { negativeButtonText = text; } private void setOnNegativeListener(OnClickListener listener) { negativeButtonClickListener = listener; } private void setOnPositiveListener(OnClickListener listener) { positiveButtonClickListener = listener; } public static class Builder { private Context context; private String message; private String positiveButtonText; private String negativeButtonText; private OnClickListener positiveButtonClickListener; private OnClickListener negativeButtonClickListener; public Builder(Context context) { this.context = context; } public Builder setMessage(String message) { this.message = message; return this; } public Builder setMessage(int message) { this.message = context.getString(message); return this; } public Builder setPositiveButton(int positiveButtonText, OnClickListener listener) { return setPositiveButton(context.getString(positiveButtonText), listener); } public Builder setPositiveButton(String positiveButtonText, OnClickListener listener) { this.positiveButtonText = positiveButtonText; this.positiveButtonClickListener = listener; return this; } public Builder setNegativeButton(int negativeButtonText, OnClickListener listener) { return setNegativeButton(context.getString(negativeButtonText), listener); } public Builder setNegativeButton(String negativeButtonText, OnClickListener listener) { this.negativeButtonText = negativeButtonText; this.negativeButtonClickListener = listener; return this; } public CustomDialog create() { CustomDialog dialog = new CustomDialog(context); dialog.setCancelable(false); dialog.requestWindowFeature(Window.FEATURE_NO_TITLE); dialog.getWindow().setBackgroundDrawableResource(android.R.color.transparent); dialog.setMessage(message); dialog.setNegativeButtonText(negativeButtonText); dialog.setPositiveButtonText(positiveButtonText); dialog.setOnNegativeListener(negativeButtonClickListener); dialog.setOnPositiveListener(positiveButtonClickListener); return dialog; } } } }1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
2.用到的布局文件dialog_custom.xml,放在layout目录下
<?xml version="1.0" encoding="utf-8"?> <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent"> <LinearLayout android:layout_width="300dp" android:layout_height="wrap_content" android:layout_gravity="center" android:background="@drawable/dialog_background" android:orientation="vertical"> <TextView android:id="@+id/tv_dialog_message" android:layout_width="match_parent" android:layout_height="100dp" android:gravity="center" android:text="message" android:textColor="#333333" android:textSize="16sp" /> <View android:layout_width="match_parent" android:layout_height="1dp" android:background="#e8e8e8" /> <LinearLayout android:layout_width="match_parent" android:layout_height="50dp" android:orientation="horizontal"> <Button android:id="@+id/btn_dialog_positive" android:layout_width="0px" android:layout_height="match_parent" android:layout_weight="1" android:background="@null" android:text="todo" android:textColor="#EE6911" android:textSize="16sp" /> <View android:id="@+id/view_dialog_button_divider" android:layout_width="1dp" android:layout_height="match_parent" android:background="#e8e8e8" /> <Button android:id="@+id/btn_dialog_negative" android:layout_width="0px" android:layout_height="match_parent" android:layout_weight="1" android:background="@null" android:text="cancel" android:textColor="#EE6911" android:textSize="16sp" /> </LinearLayout> </LinearLayout> </FrameLayout>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
3.用到的背景设置dialog_background.xml文件,放在drawable目录下
<?xml version="1.0" encoding="utf-8"?> <shape xmlns:android="http://schemas.android.com/apk/res/android"> <solid android:color="@color/sweet_dialog_bg_color" /> <corners android:radius="6dp"/> </shape>1
2
3
4
5
1
2
3
4
5
使用说明书
* 说明:版本更新帮助类,负责下载apk文件并打开安装
* 用法:直接new本类,构造方法里分别传
* Context Activity的context
* String apk下载地址
* boolean 允许跳过本次更新
* 示例:
* 普通版本更新 new VersionUpdataHelper(MainActivity.this, info.getUrl());
* 强制版本更新 new VersionUpdataHelper(MainActivity.this, info.getUrl(), false);
*
测试过红米note 4.4,三星 5.1.1,华为 6.0系统
相关文章推荐
- android检查版本更新、下载、安装工具类
- Android版本更新并安装工具类
- Android程序版本更新--通知栏更新下载安装
- Android程序版本更新之通知栏更新下载安装
- Android 更新版本 应用程序未安装 解决办法
- [置顶] Android开发必有功能,更新版本提示,检测是否有新版本更新。下载完成后进行安装。
- Android程序版本更新--通知栏更新下载安装(转)
- Android获取SD卡上的APK文件,并且判断是否安装过、是否可以更新到新版本的工具类
- android 版本更新 静默安装及自启动
- android的APP自动更新程序,检测版本,然后下载安装,但app安装后不提示“完成,打开”?
- Android做检测版本更新安装完以后就什么都没有了,没有出现安装成功的界面
- 关于Android 2.2与2.3 adb.exe版本更新问题(在安装android——SDK时候找不到相应的 /tools/adb.exe! )
- 关于Android 2.2与2.3 adb.exe版本更新问题(在安装android——SDK时候找不到相应的 /tools/adb.exe! )
- android版本自动检测更新 版本检测 自动更新 自动安装
- 关于android中版本自动更新,从服务器下载下来的文件不能安装的问题
- Android获取SD卡上的APK文件,并且判断是否安装过、是否可以更新到新版本的工具类
- android 实现版本更新和下载安装
- Android版本检测,更新,安装及运行APK
- Android 版本更新下载自动安装APK,并解决Android6.0安装失败的问题
- Android获取SD卡上的APK文件,并且判断是否安装过、是否可以更新到新版本的工具类