在寫自己App的時候,APP更新是非常重要的,後續版本的釋出及時送到使用者
效果圖:
看下Bmob的背景,建立應用,配置啥的就不說了
首先我們建立表update
objectID是唯一标示,不能改變,我們根據這個ID擷取APK檔案的下載下傳連結更新内容text,Code是APP版本号,伺服器上的CODE号一定要比上個版本大。
流程:開啟APP——檢測CODE——CODE大于目前CODE執行更新——下載下傳APK——install
擷取APP版本号的工具類:
import android.content.Context;
import android.content.pm.PackageManager;
/*擷取版本code和name的工具類*/
public class APKVersionCodeUtils {
/* 擷取目前本地apk的版本*/
public static int getVersionCode(Context mContext) {
int versionCode = 0;
try {
//擷取軟體版本号,對應AndroidManifest.xml下android:versionCode
versionCode = mContext.getPackageManager().getPackageInfo(mContext.getPackageName(), 0).versionCode;
} catch (PackageManager.NameNotFoundException e) {
e.printStackTrace();
}
return versionCode;
}
/* 擷取版本号名稱*/
public static String getVerName(Context context) {
String verName = "";
try {
verName = context.getPackageManager().
getPackageInfo(context.getPackageName(), 0).versionName;
} catch (PackageManager.NameNotFoundException e) {
e.printStackTrace();
}
return verName;
}
}
versionCode是版本号,,cersionName是版本号
調用:
int versionCode = APKVersionCodeUtils.getVersionCode(this) ;
String versionName = APKVersionCodeUtils.getVerName(this);
update.java
import cn.bmob.v3.BmobObject;
import cn.bmob.v3.datatype.BmobFile;
public class update extends BmobObject {
public BmobFile getAPK() {
return APK;
}
public void setAPK(BmobFile APK) {
this.APK = APK;
}
BmobFile APK;
public String getText() {
return text;
}
public void setText(String text) {
this.text = text;
}
String text;
public String getCode() {
return Code;
}
public void setCode(String code) {
Code = code;
}
String Code;
public String getapkUrl(){
return APK.getFileUrl();
}
}
需要注意的是getAPKurl()這個方法是擷取APK的下載下傳連結
擷取版本Code和APK連結以及text:
//查詢單條資料
public void querySingleData() {
BmobQuery<update> bmobQuery = new BmobQuery<update>();
bmobQuery.getObject("MF4j000B", new QueryListener<update>() {
@Override
public void done(update object, BmobException e) {
if (e == null) {
url = object.getapkUrl();
code1 = object.getCode();
text = object.getText();
System.out.println("APK更新位址:" + url);
System.out.println("版本号:" + code1);
System.out.println("更新内容" + text);
check(code1);
} else {
Log.i("bmob圖檔", "失敗:" + e.getMessage() + "," + e.getErrorCode());
}
}
});
}
檢測版本CODE:
//判斷版本大小
public void check(String code1) {
code = APKVersionCodeUtils.getVersionCode(this) ;
int i = Integer.valueOf(this.code1).intValue();
if (i > code) {
showDialog();
}
}
如果需要更新,顯示Dialog給使用者提示更新:
private void showDialog() {
AlertDialog dialog = new AlertDialog.Builder(this)
.setIcon(R.drawable.ic_launcher_background)//設定标題的圖檔
.setTitle("檢查到新版本")//設定對話框的标題
.setMessage(text)//設定對話框的内容
//設定對話框的按鈕
.setNegativeButton("取消", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
//Toast.makeText(MainActivity.this, "點選了取消按鈕", Toast.LENGTH_SHORT).show();
dialog.dismiss();
}
})
.setPositiveButton("更新", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
//Toast.makeText(MainActivity.this, "點選了确定的按鈕", Toast.LENGTH_SHORT).show();
//postUrl(url);
mIsCancel=false;
//展示對話框
showDownloadDialog(url);
dialog.dismiss();
}
}).create();
dialog.show();
}
/*
* 顯示正在下載下傳對話框
*/
protected void showDownloadDialog(String url) {
AlertDialog.Builder builder = new AlertDialog.Builder(mContext);
builder.setTitle("下載下傳中");
View view = LayoutInflater.from(mContext).inflate(R.layout.dialog_progress, null);
mProgressBar = (ProgressBar) view.findViewById(R.id.id_progress);
builder.setView(view);
builder.setNegativeButton("取消", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
// 隐藏目前對話框
dialog.dismiss();
// 設定下載下傳狀态為取消
mIsCancel = true;
}
});
mDownloadDialog = builder.create();
mDownloadDialog.show();
// 下載下傳檔案
downloadAPK(url);
}
downloadAPK()及install()
/*
* 開啟新線程下載下傳apk檔案
*/
private void downloadAPK() {
new Thread(new Runnable() {
@Override
public void run() {
try{
if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)){
String sdPath = Environment.getExternalStorageDirectory() + "/";
// 檔案儲存路徑
mSavePath = sdPath + "SITdownload";
File dir = new File(mSavePath);
if (!dir.exists()){
dir.mkdir();
}
// 下載下傳檔案
HttpURLConnection conn = (HttpURLConnection) new URL(url).openConnection();
conn.connect();
InputStream is = conn.getInputStream();
int length = conn.getContentLength();
File apkFile = new File(mSavePath, mVersion_name);
FileOutputStream fos = new FileOutputStream(apkFile);
int count = 0;
byte[] buffer = new byte[1024];
while (!mIsCancel){
int numread = is.read(buffer);
count += numread;
// 計算進度條的目前位置
mProgress = (int) (((float)count/length) * 100);
// 更新進度條
mUpdateProgressHandler.sendEmptyMessage(1);
// 下載下傳完成
if (numread < 0){
mUpdateProgressHandler.sendEmptyMessage(2);
break;
}
fos.write(buffer, 0, numread);
}
fos.close();
is.close();
}
}catch(Exception e){
e.printStackTrace();
}
}
}).start();
}
/**
* 接收消息
*/
private Handler mUpdateProgressHandler = new Handler(){
@Override
public void handleMessage(Message msg) {
switch (msg.what){
case 1:
// 設定進度條
mProgressBar.setProgress(mProgress);
break;
case 2:
// 隐藏目前下載下傳對話框
mDownloadDialog.dismiss();
// 安裝 APK 檔案
installAPK();
}
};
};
/*
* 下載下傳到本地後執行安裝
*/
protected void installAPK() {
File apkFile = new File(mSavePath, mVersion_name);
if (!apkFile.exists()){
return;
}
Intent intent = new Intent(Intent.ACTION_VIEW);
// 安裝完成後,啟動app(源碼中少了這句話)
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
Uri uri = Uri.parse("file://" + apkFile.toString());
intent.setDataAndType(uri, "application/vnd.android.package-archive");
mContext.startActivity(intent);
}
最後是mainfest權限:
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<!--往sdcard中寫入資料的權限 -->
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<!--在sdcard中建立/删除檔案的權限 -->
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
API版本不能設定太高:
apply plugin: 'com.android.application'
android {
compileSdkVersion 26
defaultConfig {
applicationId "com.example.alex233.update"
minSdkVersion 16
targetSdkVersion 22
versionCode 11
versionName "2.9"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
}
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation 'com.android.support:appcompat-v7:26.+'
implementation 'com.android.support.constraint:constraint-layout:1.1.2'
testImplementation 'junit:junit:4.12'
androidTestImplementation 'com.android.support.test:runner:1.0.2'
androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
//以下SDK開發者請根據需要自行選擇
//bmob-sdk:Bmob的android sdk包,包含了Bmob的資料存儲、檔案等服務,以下是最新的bmob-sdk:
//3.5.5:請務必檢視下面注釋[1]
compile 'cn.bmob.android:bmob-sdk:3.6.3'
//bmob-push:Bmob的推送包
compile 'cn.bmob.android:bmob-push:0.8'
//bmob-im:Bmob的即時通訊包,注意每個版本的im依賴特定版本的bmob-sdk,具體的依賴關系可檢視下面注釋[2]
compile 'cn.bmob.android:bmob-im:[email protected]'
//如果你想應用能夠相容Android6.0,請添加此依賴(org.apache.http.legacy.jar)
compile 'cn.bmob.android:http-legacy:1.0'
}
以上就是版本更新的内容了;
其實可以用android自帶的download下載下傳器
在dialog點選确認的點選事件中:
Intent intent = new Intent();
intent.setData(Uri.parse(url));//Url 就是你要打開的網址
intent.setAction(Intent.ACTION_VIEW);
startActivity(intent); //啟動浏覽器
就很簡單,不需要下面的一大堆了
完整代碼: