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);
}
复制代码
欧了,如今应该自动更新没问题能够解决了,若有问题欢迎指正,互相学习