需要添加的权限
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.DOWNLOAD_WITHOUT_NOTIFICATION"/>
代码实现部分
获取服务端版本号与本地应用版本号比对的过程此处省略,下面是Activity中代码
//弹出版本更新提示框
Dialog dialog = new AlertDialog.Builder(context)
.setIcon(R.drawable.ic_launcher)
.setTitle("更新提示")
.setMessage(updateMessage())
.setPositiveButton("后台更新", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface arg0, int arg1) {
// TODO Auto-generated method stub
Toast.makeText(context, "开始下载", 0).show();
//下载Apk文件
new ApkDownLoad(getApplicationContext(), APK_URL, "美丽说", "版本升级").execute();
}
})
.setNegativeButton("取消", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface arg0, int arg1) {
// TODO Auto-generated method stub
arg0.cancel();
}
})
.create();
dialog.show();
也可以将这段代码写在自定义Application类的OnCreate()方法中, 如果在Application中写入以上代码需要添加一个全局弹出Dialog的权限和属性。
//在dialog.show()之前添加
dialog.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT);
//系统权限
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
ApkDownLoad.java
public class ApkDownLoad {
public static final String DOWNLOAD_FOLDER_NAME = "Download"; //Sd卡根目录文件夹名称
public static final String DOWNLOAD_FILE_NAME = "MeiLiShuo.apk"; //下载Apk名称
public static final String APK_DOWNLOAD_ID = "apkDownloadId";
private Context context;
private String url;
private String notificationTitle;
private String notificationDescription;
private DownloadManager downloadManager;
private CompleteReceiver completeReceiver;
/**
* @param context
* @param url 下载apk的url
* @param notificationTitle 通知栏标题
* @param notificationDescription 通知栏描述
*/
public ApkDownLoad(Context context, String url, String notificationTitle,
String notificationDescription) {
super();
this.context = context;
this.url = url;
this.notificationTitle = notificationTitle;
this.notificationDescription = notificationDescription;
downloadManager = (DownloadManager)context.getSystemService(context.DOWNLOAD_SERVICE);
completeReceiver = new CompleteReceiver();
/** register download success broadcast **/
context.registerReceiver(completeReceiver, new IntentFilter(DownloadManager.ACTION_DOWNLOAD_COMPLETE));
}
public void execute() {
//清除已下载的内容重新下载
long downloadId = PreferencesUtils.getLong(context, APK_DOWNLOAD_ID);
if(downloadId != -1){
downloadManager.remove(downloadId);
PreferencesUtils.removeSharedPreferenceByKey(context, APK_DOWNLOAD_ID);
}
Request request = new Request(Uri.parse(url));
//设置Notification中显示的文字
request.setTitle(notificationTitle);
request.setDescription(notificationDescription);
//设置可用的网络类型
request.setAllowedNetworkTypes(Request.NETWORK_MOBILE | Request.NETWORK_WIFI);
//设置状态栏中显示Notification
request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED);
//不显示下载界面
request.setVisibleInDownloadsUi(false);
//设置下载后文件存放的位置
File folder = Environment.getExternalStoragePublicDirectory(DOWNLOAD_FOLDER_NAME);
if (!folder.exists() || !folder.isDirectory()) {
folder.mkdirs();
}
request.setDestinationInExternalPublicDir(DOWNLOAD_FOLDER_NAME, DOWNLOAD_FILE_NAME);
//设置文件类型
MimeTypeMap mimeTypeMap = MimeTypeMap.getSingleton();
String mimeString = mimeTypeMap.getMimeTypeFromExtension(MimeTypeMap.getFileExtensionFromUrl(url));
request.setMimeType(mimeString);
//保存返回唯一的downloadId
PreferencesUtils.putLong(context, APK_DOWNLOAD_ID, downloadManager.enqueue(request));
}
class CompleteReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
/**
* get the id of download which have download success, if the id is my id and it's status is successful,
* then install it
**/
long completeDownloadId = intent.getLongExtra(DownloadManager.EXTRA_DOWNLOAD_ID, 0);
long downloadId = PreferencesUtils.getLong(context, APK_DOWNLOAD_ID);
if (completeDownloadId == downloadId) {
// if download successful
if (queryDownloadStatus(downloadManager, downloadId) == DownloadManager.STATUS_SUCCESSFUL) {
//clear downloadId
PreferencesUtils.removeSharedPreferenceByKey(context, APK_DOWNLOAD_ID);
//unregisterReceiver
context.unregisterReceiver(completeReceiver);
//install apk
String apkFilePath = new StringBuilder(Environment.getExternalStorageDirectory().getAbsolutePath())
.append(File.separator).append(DOWNLOAD_FOLDER_NAME).append(File.separator)
.append(DOWNLOAD_FILE_NAME).toString();
install(context, apkFilePath);
}
}
}
};
/** 查询下载状态 */
public static int queryDownloadStatus(DownloadManager downloadManager, long downloadId){
int result = -1;
DownloadManager.Query query = new DownloadManager.Query().setFilterById(downloadId);
Cursor c = null;
try {
c = downloadManager.query(query);
if (c != null && c.moveToFirst()) {
result = c.getInt(c.getColumnIndex(DownloadManager.COLUMN_STATUS));
}
} finally {
if (c != null) {
c.close();
}
}
return result;
}
/**
* install app
*
* @param context
* @param filePath
* @return whether apk exist
*/
public static boolean install(Context context, String filePath) {
Intent i = new Intent(Intent.ACTION_VIEW);
File file = new File(filePath);
if (file != null && file.length() > 0 && file.exists() && file.isFile()) {
i.setDataAndType(Uri.parse("file://" + filePath), "application/vnd.android.package-archive");
i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(i);
return true;
}
return false;
}
}
PreferencesUtils.java
public class PreferencesUtils {
public static String PREFERENCE_NAME = "VersionUpdate";
/**
* put long preferences
*
* @param context
* @param key The name of the preference to modify
* @param value The new value for the preference
* @return True if the new values were successfully written to persistent storage.
*/
public static boolean putLong(Context context, String key, long value) {
SharedPreferences settings = context.getSharedPreferences(PREFERENCE_NAME, Context.MODE_PRIVATE);
SharedPreferences.Editor editor = settings.edit();
editor.putLong(key, value);
return editor.commit();
}
/**
* get long preferences
*
* @param context
* @param key The name of the preference to retrieve
* @return The preference value if it exists, or -1. Throws ClassCastException if there is a preference with this
* name that is not a long
* @see #getLong(Context, String, long)
*/
public static long getLong(Context context, String key) {
return getLong(context, key, -1);
}
/**
* get long preferences
*
* @param context
* @param key The name of the preference to retrieve
* @param defaultValue Value to return if this preference does not exist
* @return The preference value if it exists, or defValue. Throws ClassCastException if there is a preference with
* this name that is not a long
*/
public static long getLong(Context context, String key, long defaultValue) {
SharedPreferences settings = context.getSharedPreferences(PREFERENCE_NAME, Context.MODE_PRIVATE);
return settings.getLong(key, defaultValue);
}
/**
* remove obj in preferences
* @param context
* @param key
* @return
*/
public static boolean removeSharedPreferenceByKey(Context context, String key){
SharedPreferences settings = context.getSharedPreferences(PREFERENCE_NAME, Context.MODE_PRIVATE);
SharedPreferences.Editor editor = settings.edit();
editor.remove(key);
return editor.commit();
}
}