您的位置:首页 > 移动开发 > Android开发

Android版本更新并安装工具类

2017-08-11 11:07 204 查看
自己用系统的DownloadManager工具封装了一个版本更新帮助类,代码如下:

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系统
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐