编写不易,如有转载,请声明出处:http://blog.csdn.net/zxc514257857/article/details/72667640
广告屏上安装的Apk程序,没有人操作,也很少有人去管理,软件需要进行自动更新
Apk程序一打开进行判断当前版本和服务器上软件版本,如果服务器版本大于当前版本,进行自动更新。如果设备Root过,通过pm命名进行自动更新,如果没Root过,通过无障碍服务,指定“安装”、“确定”、“打开”等进行自动点击,从而实现自动更新功能
下载AutoInstaller-master , 下载地址
https://github.com/a-voyager/AutoInstaller/blob/master/README_zh.md
新建一个module改名为installerlibrary
删除里面内容,将AutoInstaller-master---->installerlibrary中的文件全部拷贝进去
会出现如下错误:
Error:(2, 0) Plugin with id 'com.github.dcendents.android-maven' not found.
解决:在项目的build.gradle---->dependencies添加
classpath 'com.github.dcendents:android-maven-gradle-plugin:1.5'
android.os.FileUriExposedException
解决方法: Android 7.0的适配问题,android.os.FileUriExposedException
http://blog.csdn.net/zxc514257857/article/details/70766998
import android.app.ProgressDialog;
import android.content.Context;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.support.v7.app.AppCompatActivity;
import android.widget.Toast;
import com.example.administrator.autoupdate.R;
import com.example.administrator.autoupdate.conf.Url;
import com.example.administrator.autoupdate.utils.LogUtils;
import com.squareup.okhttp.Callback;
import com.squareup.okhttp.OkHttpClient;
import com.squareup.okhttp.Request;
import com.squareup.okhttp.Response;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import java.io.BufferedInputStream;
import java.io.IOException;
import java.net.HttpURLConnection;
import java.net.URL;
import top.wuhaojie.installerlibrary.AutoInstaller;
public class MainActivity extends AppCompatActivity {
private static final String TAG = "MainActivity";
private Context mContext = MainActivity.this;
private static final int UPDATESUCCESS = 1;
private static final int UPDATEFAIL = 2;
// 服务器中两个文件的访问URL
public static String updateConfigAspxURL;
public static String updateConfigApkURL;
// 本软件版本名称
private String mPackageVersionName;
// 本软件版本号
private int mPackageVersionCode;
// 本软件包名
private String mPackageName;
// 对话弹窗
private ProgressDialog mProgressDialog;
// aspx中获取的三个字段
private String mGetServerVersionName = null;
private int mGetServerVersionCode;
private String mGetServerPackageName = null;
private Handler handler = new Handler() {
@Override
public void handleMessage(Message msg) {
switch (msg.what) {
// 如果访问配置信息成功
case UPDATESUCCESS:
String updateURL = (String) msg.obj;
try {
// 获取网址并拼接
JSONObject jso = new JSONObject(updateURL);
// 0表示不存在 1表示存在
int isFileExist = jso.getInt("isFileExist");
String url = jso.getString("url");
JSONArray jsArr = jso.getJSONArray("files");
LogUtils.i(TAG, "isFileExist:" + isFileExist);
LogUtils.i(TAG, "url:" + url);
LogUtils.i(TAG, "jsArr:" + jsArr);
// 如果两个文件都存在
if (isFileExist == 1) {
LogUtils.i(TAG, "isFileExist:" + isFileExist);
LogUtils.i(TAG, "两个文件都存在,继续进行判断!");
for (int i = 0; i < jsArr.length(); i++) {
String name = (String) jsArr.get(i);
LogUtils.i(TAG, "name:" + name);
String urlName = url + name;
LogUtils.i(TAG, "urlName:" + urlName);
if (urlName.contains(".aspx")) {
updateConfigAspxURL = urlName;
}
if (urlName.contains(".apk")) {
updateConfigApkURL = urlName;
}
LogUtils.i(TAG, "aspxURL:" + updateConfigAspxURL);
LogUtils.i(TAG, "apkURL:" + updateConfigApkURL);
}
// 比较版本号 并静默安装
compareVersionAndInstall();
}
} catch (JSONException e) {
e.printStackTrace();
}
break;
// 如果访问配置信息失败
case UPDATEFAIL:
break;
}
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initView();
initData();
}
private void initView(){
mPackageVersionName = getPackageVersionName(mContext, mContext.getPackageName());
mPackageVersionCode = getPackageVersionCode(mContext, mContext.getPackageName());
}
private void initData(){
updateConfigSuccess();
}
private void updateConfigSuccess(){
mPackageName = getPackageName();
OkHttpClient client = new OkHttpClient();
Request request = new Request.Builder()
.url(Url.UPDATE)
.build();
client.newCall(request).enqueue(new Callback() {
@Override
public void onFailure(Request request, IOException e) {
LogUtils.i(TAG , "访问配置信息失败");
}
@Override
public void onResponse(Response response) throws IOException {
String updateConfigURL = response.body().string();
LogUtils.i(TAG , "从网络上获取的配置信息updateConfigURL:" + updateConfigURL);
Message msg = Message.obtain();
msg.what = UPDATESUCCESS;
msg.obj = updateConfigURL;
handler.sendMessage(msg);
}
});
runOnUiThread(new Runnable() {
@Override
public void run() {
mProgressDialog = new ProgressDialog(mContext);
mProgressDialog.setMessage("正在下载");
}
});
}
//获取本地VersionName
public static String getPackageVersionName(Context context, String pkgName) {
try {
PackageManager manager = context.getPackageManager();
PackageInfo info = manager.getPackageInfo(pkgName, 0); //PackageManager.GET_CONFIGURATIONS
return info.versionName;
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
//获取本地VersionCode
public static int getPackageVersionCode(Context context, String pkgName) {
try {
PackageManager manager = context.getPackageManager();
PackageInfo info = manager.getPackageInfo(pkgName, 0);
return info.versionCode;
} catch (Exception e) {
e.printStackTrace();
return -1;
}
}
//获取服务器版本号
public String getServerVersion(){
String serverJson = null;
byte[] buffer = new byte[128];
try {
LogUtils.i(TAG , "updateConfigAspxURL: "+ updateConfigAspxURL);
URL serverURL = new URL(updateConfigAspxURL);
HttpURLConnection connect = (HttpURLConnection) serverURL.openConnection();
BufferedInputStream bis = new BufferedInputStream(connect.getInputStream());
int n = 0;
while((n = bis.read(buffer))!= -1){
serverJson = new String(buffer);
}
} catch (Exception e) {
// 如果没有传递这apk及ver文件 程序这里会报错
LogUtils.i(TAG , "获取服务器版本号异常!"+e);
}
return serverJson;
}
/**
* 比较版本号 并静默安装
*/
private void compareVersionAndInstall() {
new Thread() {
public void run() {
Looper.prepare();
try {
String serverJson = getServerVersion();
LogUtils.i(TAG, "serverJson" + serverJson);
JSONArray jsArr = new JSONArray(serverJson);
JSONObject jso = jsArr.getJSONObject(0);
mGetServerPackageName = jso.getString("packageName");
mGetServerVersionCode = Integer.parseInt(jso.getString("versionCode"));
mGetServerVersionName = jso.getString("versionName");
LogUtils.i(TAG, "服务器端版本号:" + mGetServerVersionCode + ",当前版本号:" + mPackageVersionCode);
LogUtils.i(TAG, "服务器端版本包名:" + mGetServerPackageName + ",当前版本包名:" + mPackageName);
// 如果包名相同
if (mGetServerPackageName.equals(mPackageName)) {
LogUtils.i(TAG, "包名相同!");
// 如果服务器版本大于当前版本 静默升级
if (mPackageVersionCode < mGetServerVersionCode) {
LogUtils.i(TAG, "服务器端版本号大于本地版本号!开始更新!");
LogUtils.i(TAG, "updateConfigApkURL: " + updateConfigApkURL);
AutoInstaller installer = AutoInstaller.getDefault(mContext);
installer.installFromUrl(updateConfigApkURL);
installer.setOnStateChangedListener(new AutoInstaller.OnStateChangedListener() {
@Override
public void onStart() {
runOnUiThread(new Runnable() {
@Override
public void run() {
mProgressDialog.show();
}
});
}
@Override
public void onComplete() {
runOnUiThread(new Runnable() {
@Override
public void run() {
mProgressDialog.dismiss();
}
});
}
@Override
public void onNeed2OpenService() {
runOnUiThread(new Runnable() {
@Override
public void run() {
Toast.makeText(mContext, "请打开辅助功能服务", Toast.LENGTH_SHORT).show();
}
});
}
});
} else {
LogUtils.i(TAG , "当前版本大于服务器邦本,不更新!");
}
}else{
LogUtils.i(TAG , "包名不同,不更新!");
}
} catch (JSONException e) {
e.printStackTrace();
}
Looper.loop();
}
}.start();
}
}
{
"files": [
// 服务器上放置这两个文件,每次需要更新时将最新的这两个文件进行替换
// version.aspx文件内容[{"packageName":"com.example.administrator.autoupdate","versionName":"1.0.7","versionCode":"7"}]
"version.aspx",
// 最新的安装包
"AutoUpdate.apk"
],
// 服务器端判断这两个文件是否都存在,都存在返回1,否则返回0
"isFileExist": 1,
}
> ----------**因本人才疏学浅,如博客或Demo中有错误的地方请大家随意指出,与大家一起讨论,共同进步,谢谢!**----------Demo下载请移步:http://download.csdn.net/detail/zxc514257857/9850244