自己用系統的DownloadManager工具封裝了一個版本更新幫助類,代碼如下:
1.功能具體實現的java代碼
private static final String TAG = "VersionUpdataHelper";
private final String DOWNLOAD_FILE_NAME;
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;
private String mUpdateInfo;
public VersionUpdataHelper(Activity activity, String url) {
this(activity, url, true);
}
public VersionUpdataHelper(Activity activity, String url, boolean cancelable) {
this(activity, url, cancelable, "");
}
public VersionUpdataHelper(Activity activity, String url, boolean cancelable, String info){
DOWNLOAD_FILE_NAME = System.currentTimeMillis() + ".apk";
if (activity == null || activity.isFinishing()){
return;
}
mContext = activity;
mUrl = url;
mCancelable = cancelable;
mUpdateInfo = info;
showNewVersionDialog();
}
private void showNewVersionDialog() {
String message = "發現新版本,是否下載並更新...";
if (!TextUtils.isEmpty(mUpdateInfo)){
message = message + "\n\n" + mUpdateInfo;
Lg.i(TAG, "---message===" + message);
}
mBuilder = new CustomDialog.Builder(mContext);
mBuilder.setMessage(message)
.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) {
if (mCancelable) {
mDownloadManager.remove(mDownloadId);
dialog.dismiss();
mCancleDownload = 1;
unregisterUpdataReceiver();
}
}
});
mDialog = mBuilder.create();
mReceiver = new CompleteReceiver();
mContext.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) {
Uri downloadFileUri = mDownloadManager.getUriForDownloadedFile(downloadId);
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) {
Intent updateApk = new Intent(Intent.ACTION_VIEW);
updateApk.setDataAndType(downloadFileUri, "application/vnd.android.package-archive");
updateApk.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
mContext.startActivity(updateApk);
}else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N){
Intent install = new Intent(Intent.ACTION_VIEW);
install.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
install.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
install.setDataAndType(downloadFileUri, "application/vnd.android.package-archive");
mContext.startActivity(install);
} 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;
}
}
}
}
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>
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>
使用說明書
* 說明:版本更新幫助類,負責下載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系統