Android中自己实现App一打开判断是否有更新,并通过依赖AutoInstaller实现自动更新
来源:互联网 发布:微信淘宝客怎么拉人 编辑:程序博客网 时间:2024/06/05 11:11
编写不易,如有转载,请声明出处: 梦回河口:http://blog.csdn.net/zxc514257857/article/details/72667640
应用场景
广告屏上安装的Apk程序,没有人操作,也很少有人去管理,软件需要进行自动更新
实现原理
Apk程序一打开进行判断当前版本和服务器上软件版本,如果服务器版本大于当前版本,进行自动更新。如果设备Root过,通过pm命名进行自动更新,如果没Root过,通过无障碍服务,指定“安装”、“确定”、“打开”等进行自动点击,从而实现自动更新功能
AutoInstaller的依赖过程
下载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'
- module在android N 7.0使用的时候会报出如下错误:
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(); }}
访问String UPDATE,服务器返回:
{ "files": [ // 服务器上放置这两个文件,每次需要更新时将最新的这两个文件进行替换 // version.aspx文件内容[{"packageName":"com.example.administrator.autoupdate","versionName":"1.0.7","versionCode":"7"}] "version.aspx", // 最新的安装包 "AutoUpdate.apk" ], // 服务器端判断这两个文件是否都存在,都存在返回1,否则返回0 "isFileExist": 1,}
Demo下载请移步:http://download.csdn.net/detail/zxc514257857/9850244
———-因本人才疏学浅,如博客或Demo中有错误的地方请大家随意指出,与大家一起讨论,共同进步,谢谢!———-
- Android中自己实现App一打开判断是否有更新,并通过依赖AutoInstaller实现自动更新
- Android实现APP自动更新
- iOS 判断APP是否打开定位,并实现直接跳转打开定位
- JS实现点击网页判断是否安装app并打开否则跳转app store
- android 在webapp中判断native app是否安装并直接打开
- 判断android系统中是否有指定apk存在,并打开
- Android 通过蒲公英pgyer的接口 Service 实现带进度下载App 通知栏显示 在线更新 自动更新Demo
- Android 通过蒲公英pgyer的接口 Service 实现带进度下载App 通知栏显示 在线更新 自动更新Demo
- Android实现APP自动更新功能
- Android实现App版本自动更新
- Android实现App版本自动更新
- Android实现App版本自动更新
- Android App应用程序实现自动更新
- Android实现App版本自动更新
- Android如何实现APP自动更新
- 通过RSS实现app的自动更新
- 实现一个单链表,并判断是否有环
- android 判断APP是否打开的方法
- laravel(二)-目录结构
- (78)自定义事件
- 跨页面的操作
- ajax解析Json数据的方法
- 监控JAVA应用的好工具javamelody
- Android中自己实现App一打开判断是否有更新,并通过依赖AutoInstaller实现自动更新
- codeforces 347 c Alice and Bob(博弈 && 数学)
- win10安装时提示 “我们无法创建分区也找不到现有的分区”
- Uva10305 Ordering Tasks(拓扑排序)
- 点击不同按钮换不同标题栏图标
- Android之模拟网易新闻客户端
- Spring 设计模式——观察者|事件驱动模型
- 如何处理fast_recovery_area无剩余空间
- stringr数据处理