看到各大平台更新android版本,都是开着应用的时候下载,下载完成后自动替换,用户体验上似乎不错,很想弄出来一个试试。
开着应用更新的原理
把android的apk当做普通文件下载
打开apk文件进行安装
之前别人问到到的时候,我也是一脸懵逼,为啥能一边用一边安装。。。。直到某次从网页上下载apk然后直接安装,突然想到。自己可能想复杂了,不需要热更新,直接下载,然后打开文件,这么简单的工作居然想了这么久才想通,顿时惭愧了,我真是程序猿么,思维呢?
于是开做,没后台就临时在Bmob建个表“down”,字段File类型,myfile,测试一下,代码好简单,我下面一个一个贴:
app build.gradle:
// Top-level build file where you can add configuration options common to all
sub-projects/modules.
buildscript {
repositories {
jcenter()
}
dependencies {
classpath
'com.android.tools.build:gradle:2.3.2'
// NOTE: Do
not place your application dependencies here; they belong
// in the individual module build.gradle files
}
}
allprojects {
repositories {
jcenter()
maven { url
"https://raw.github.com/bmob/bmob-android-sdk/master" }
}
}
task clean(type: Delete) {
delete rootProject.buildDir
}
project build.gradle
apply plugin:
'com.android.application'
android {
compileSdkVersion
25
buildToolsVersion
"25.0.3"
useLibrary
'org.apache.http.legacy'
defaultConfig {
applicationId
"com.dyy.skin.testall"
minSdkVersion
14
targetSdkVersion
25
versionCode
1
versionName
"1.0"
testInstrumentationRunner
"android.support.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
minifyEnabled
false
proguardFiles getDefaultProguardFile(
'proguard-android.txt'),
'proguard-rules.pro'
}
}
}
dependencies {
compile fileTree(dir:
'libs',
include: [
'*.jar'])
androidTestCompile(
'com.android.support.test.espresso:espresso-core:2.2.2', {
exclude group:
'com.android.support',
module:
'support-annotations'
})
compile
'com.android.support:appcompat-v7:25.+'
compile
'com.android.support.constraint:constraint-layout:1.0.2'
compile
'cn.bmob.android:bmob-sdk:3.5.5'
compile
'cn.bmob.android:http-legacy:1.0'
testCompile
'junit:junit:4.12'
}
down.java(抱歉,类名该大写,表名写错了。。。将错就错)
package com.dyy.skin.testall;
import cn.bmob.v3.BmobObject;
import cn.bmob.v3.datatype.BmobFile;
public class down extends BmobObject {
private BmobFile myfile;
public BmobFile
getMyfile() {
return myfile;
}
public void setMyfile(BmobFile myfile) {
this.myfile = myfile;
}
}
MainActivity:
package com.dyy.skin.testall;
import android.app.Activity;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.os.Environment;
import android.util.Log;
import android.widget.ProgressBar;
import android.widget.TextView;
import java.io.File;
import java.util.List;
import cn.bmob.v3.Bmob;
import cn.bmob.v3.BmobQuery;
import cn.bmob.v3.datatype.BmobFile;
import cn.bmob.v3.exception.BmobException;
import cn.bmob.v3.listener.DownloadFileListener;
import cn.bmob.v3.listener.FindListener;
public class MainActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
final ProgressBar progressBar = (ProgressBar) findViewById(R.id.down_progress);
TextView txt = (TextView) findViewById(R.id.progress_txt);
Bmob.initialize(
this,
"我的key");
BmobQuery<down> bmobQuery =
new BmobQuery<down>();
bmobQuery.addQueryKeys(
"myfile");
bmobQuery.findObjects(
new FindListener<down>() {
@Override
public void done(List<down> object, BmobException e) {
if(e==
null){
down downLoad = object.get(
0);
BmobFile bmobfile = downLoad.getMyfile();
if(bmobfile!=
null){
final File saveFile =
new File(Environment.getExternalStorageDirectory(), bmobfile.getFilename());
bmobfile.download(saveFile,
new DownloadFileListener() {
@Override
public void done(String s, BmobException e) {
openFile(saveFile);
}
@Override
public void onProgress(Integer integer,
long l) {
progressBar.setProgress(integer);
}
});
}
}
else{
}
}
});
}
private void openFile(File file) {
Log.e(
"OpenFile", file.getName());
Intent intent =
new Intent();
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
intent.setAction(android.content.Intent.ACTION_VIEW);
intent.setDataAndType(Uri.fromFile(file),
"application/vnd.android.package-archive");
startActivity(intent);
}
}
布局文件,activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.dyy.skin.testall">
<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.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity
android:name="cn.bmob.v3.update.UpdateDialogActivity"
android:theme="@android:style/Theme.Translucent.NoTitleBar" >
</activity>
<meta-data android:value="Channel ID" android:name="BMOB_CHANNEL"/>
</application>
</manifest>
就这么简单,重要的是原理,如果公司带宽足够,可以考虑用这种方式更新,接入公司平台用DownloadManager都可以.友盟现在用不了了,bmob如果只用升级功能不划算,只是测试,所以也没按它的更新方法写了,如果要好的更新第三方平台,欢迎推荐留言。