1、需求分析android
一、查詢線上版本號,而後拿本地版本號與之對比。二、若線上版本號比本地版本號大,則下載線上版本號。三、把下載好的版本號安裝,並替換當前舊版本api
2、權限bash
根據上面的需求咱們能夠知道,須要用到的權限應該有網絡權限、本地文件寫入權限,本地文件讀取權限。使用網絡權限去獲取線上的版本號,而後下載保存到本地,安裝的時候再去本地取來。另外8.0上google把未知應用的安裝權限的管理放到了每一個app上,每一個app都有容許安裝未知應用的設置開關,因此這裏也須要權限網絡
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE> <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"> <uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES"/>---8.0安裝權限 複製代碼
3、步驟app
1.先判斷8.0以上的須要檢測是否有權限,有的直接去檢測版本更新,沒有去申請ide
if (!checkInstall()){
if (conn) {
this.checkUpdate(splashView);
} else {
Toast.makeText(this, "請檢查網絡~", Toast.LENGTH_LONG).show();
}
}
/**
* 若是想讓應用自動安裝下載的新版本apk,那麼必須打開應用的這個權限,否則是不會自動安裝的
*/
public boolean checkInstall() {
boolean haveInstallPermission;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
//先獲取是否有安裝未知來源應用的權限
haveInstallPermission = getPackageManager().canRequestPackageInstalls();
if (!haveInstallPermission) {//沒有權限
android.support.v7.app.AlertDialog alertDialog = new android.support.v7.app.AlertDialog.Builder(this)
.setTitle("請開啓未知來源權限")
.setMessage("應用須要打開安裝未知來源應用權限,請去設置中開啓權限")
.setCancelable(false)
.setNegativeButton("取消",
new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
dialog.dismiss();
Toast.makeText(WelcomeActivity.this, "您拒絕了權限,應用沒法正常使用!", Toast.LENGTH_SHORT).show();
finish();
}
})
.setPositiveButton("去設置", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
dialog.dismiss();
toInStallPermissionSettingActivity();
}
}).create();
alertDialog.show();
return true;
}
}
return false;
}
@RequiresApi(api = Build.VERSION_CODES.O)
private void toInStallPermissionSettingActivity() {
Uri packageURI = Uri.parse("package:" + getPackageName());
//注意這個是8.0新API
Intent intent = new Intent(Settings.ACTION_MANAGE_UNKNOWN_APP_SOURCES, packageURI);
startActivityForResult(intent, REQUEST_CODE_INSTALL_PERMISSION);
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (resultCode==RESULT_OK&&requestCode==REQUEST_CODE_INSTALL_PERMISSION){
if (conn) {
this.checkUpdate(splashView);
} else {
Toast.makeText(this, "請檢查網絡~", Toast.LENGTH_LONG).show();
}
}else {
finish();
Toast.makeText(WelcomeActivity.this, " 您拒絕了權限,應用沒法正常使用!", Toast.LENGTH_SHORT).show();
}
}
複製代碼
2網絡請求檢測更新學習
/**
* 檢測軟件更新
*/
public void checkUpdate(final View splashView) {
// 建立okHttpClient對象
OkHttpClient mOkHttpClient = new OkHttpClient();
Request request = new Request.Builder().url(Urls.UPDATEXML).build();//http://ushevapp-10060464.cos.myqcloud.com/version.xml
mOkHttpClient.newCall(request).enqueue(
new okhttp3.Callback() {
@Override
public void onFailure(okhttp3.Call call, IOException e) {
Message msg = new Message();
msg.what = 0;
mmHandler.sendMessage(msg);
Log.d("h_bl", "失敗");
}
@Override
public void onResponse(okhttp3.Call call, okhttp3.Response response) throws IOException {
InputStream is = null;
byte[] buf = new byte[2048];
int len = 0;
String SDPath = Environment.getExternalStorageDirectory().getAbsolutePath();
try {
is = response.body().byteStream();
ParseXmlService pxs = new ParseXmlService();
stringStringHashMap = pxs.parseXml(is);
Message msg = new Message();
msg.what = 1;
mmHandler.sendMessage(msg);
Log.d("h_bl", "檢測軟件更新文件下載成功");
} catch (Exception e) {
Message msg = new Message();
msg.what = 0;
mmHandler.sendMessage(msg);
Log.d("h_bl", "文檢測軟件更新件下載失敗");
} finally {
try {
if (is != null) {
is.close();
}
} catch (IOException e) {
}
}
}
}
);
複製代碼
三、去開啓服務下載apk,而後安裝ui
/**
* 下載文件:Okhttp
*/
private void loadFileByOkhttp() {
initNotification();
OkHttpClient mOkHttpClient = new OkHttpClient();
Request request = new Request.Builder()
.url(url)
// .addHeader("Accept-Encoding", "identity")
.build();
mOkHttpClient.newCall(request).enqueue(
new Callback() {
@Override
public void onFailure(okhttp3.Call call, IOException e) {
cancelNotification();
Log.d("h_bl", "新版本下載失敗");
}
@Override
public void onResponse(okhttp3.Call call, Response response) throws IOException {
InputStream is = null;
byte[] buf = new byte[2048];
int len = 0;
FileOutputStream fos = null;
try {
is = response.body().byteStream();
long total = response.body().contentLength();
File file = new File(destFileDir, destFileName);
fos = new FileOutputStream(file);
long sum = 0;
int progress = 0;
while ((len = is.read(buf)) != -1) {
fos.write(buf, 0, len);
sum += len;
progress = (int) (sum * 1.0f / total * 100);
updateNotification(progress);
}
if (progress == 100) {
cancelNotification();
installApk(file);
}
fos.flush();
Log.d("h_bl", "apk文件下載成功");
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
if (is != null) {
is.close();
}
} catch (IOException e) {
e.printStackTrace();
}
try {
if (fos != null) {
fos.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
);
}
複製代碼
另外這裏也有8·0的坑,就是不作特殊處理下載沒有通知顯示,那麼看代碼this
/**
* 初始化Notification通知
*/
public void initNotification() {
destFileDir = getTempDirectoryPath();
notificationManager = (NotificationManager) mContext.getSystemService(Context.NOTIFICATION_SERVICE);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
builder = new NotificationCompat.Builder(mContext, PUSH_CHANNEL_ID);
NotificationChannel channel = new NotificationChannel(PUSH_CHANNEL_ID, PUSH_CHANNEL_NAME, NotificationManager.IMPORTANCE_HIGH);
channel.enableVibration(false);
channel.setVibrationPattern(new long[]{0});
channel.setSound(null, null);
if (notificationManager != null) {
notificationManager.createNotificationChannel(channel);
}
builder.setSmallIcon(R.mipmap.logo)
.setContentText("0%")
.setContentTitle("住保服務更新")
.setChannelId(PUSH_CHANNEL_ID);
} else {
builder = new NotificationCompat.Builder(mContext)
.setSmallIcon(R.mipmap.logo)
.setContentText("0%")
.setContentTitle("住保服務更新");
}
notificationManager.notify(NOTIFY_ID, builder.build());
}
複製代碼
最後安裝apk,注意一些細節,更新的包須要和舊包有相同的簽名文件不然會安裝失敗,還有就是8.0的坑了,前面之後給出權限解決google
/**
* 安裝軟件
*
* @param file
*/
private void installApk(File file) {
Uri uri = Uri.fromFile(file);
Intent install = new Intent(Intent.ACTION_VIEW);
install.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
install.setDataAndType(uri, "application/vnd.android.package-archive");
// 執行意圖進行安裝
mContext.startActivity(install);
}
複製代碼
歐了,如今應該自動更新沒問題能夠解決了,若有問題歡迎指正,互相學習