当前位置: 首页 > 工具软件 > AutoInstaller > 使用案例 >

Android中自己实现App一打开判断是否有更新,并通过依赖AutoInstaller实现自动更新

叶裕
2023-12-01

编写不易,如有转载,请声明出处: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中有错误的地方请大家随意指出,与大家一起讨论,共同进步,谢谢!**----------
 类似资料: