WVector / AppUpdate

🚀 Android 版本更新 🚀 a library for android version update 🚀

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

android 状态栏显示

ackers-zhang opened this issue · comments

我这边使用你的方式 通知栏中并没有显示下载的进度

commented
  • 我这边也遇到了,测试手机是mate9 8.0系统;
  • 另外还有一个问题是,使用模拟器会报下面的问题:
  • 第三个问题是,我下载源代码示例工程,可以提示我安装,但是换成我自己的工程在下载完毕就直接闪了一下,还有就是,因为我们有自己的后台返回的数据格式,我已经通过下面进转换了,只是没有使用您说的appkey,因为我们后台接口就不需要嘛,难道还和这个有关系?
    下面是我【自定义接口协议的代码】:
AppUpdateUtil.update(activity, BaseConfig.TRANSCODE_UPDATE_URL, null, true, new UpdateCallback() {
            /**
             * 解析json,自定义协议
             *
             * @param resp 服务器返回的json
             * @return UpdateAppBean
             */
            @Override
            protected UpdateAppBean parseJson(String resp) {
                UpdateAppBean updateAppBean = new UpdateAppBean();
                JSONObject data = JSONObject.parseObject(resp);
                final boolean appHasNewVer = appHasNewVer(activity, data);
                final boolean h5HasNewVer = h5HasNewVer(data);
//                final String apkFileUrl = getApkFileUrl(data);
                final String apkFileUrl = "https://raw.githubusercontent.com/WVector/AppUpdateDemo/master/apk/app-debug.apk";
                final String update = (appHasNewVer || h5HasNewVer) && !TextUtils.isEmpty(apkFileUrl) ? "Yes" : "No";
                LoggerProxy.d("update %s", update);
                updateAppBean
                        //(必须)是否更新Yes,No
//                        .setUpdate(update)
                        .setUpdate(update)
                        //(必须)新版本号,
                        .setNewVersion(String.valueOf(getNewVersion(data)))
                        //(必须)下载地址
                        .setApkFileUrl(apkFileUrl)
                        //(必须)更新内容
                        .setUpdateLog(getUpdateLogFull(data))
                        //大小,不设置不显示大小,可以不设置
                        // 如果是1标识app存在更新
//                        .setTargetSize(appHasNewVer ? "1" : HACK_FALG_IS_ONLEY_H5_UPDATE)
                        //设置md5,可以不设置
                        //.setNewMd5();
                        //是否强制更新,可以不设置
                        .setConstraint(appMustBeForceUpdateToNewVer(data));
                return updateAppBean;
            }

            @Override
            public void onBefore() {
                LoggerProxy.d("更新请求网络请求之前");
//                        CProgressDialogUtils.showProgressDialog(JavaActivity.this);
            }

            @Override
            protected void hasNewApp(UpdateAppBean updateApp, UpdateAppManager updateAppManager) {
                LoggerProxy.d("hasNewApp %s", updateApp);
                updateAppManager.showDialogFragment();
            }

            @Override
            public void onAfter() {
                LoggerProxy.d("更新请求网络请求之后");
//                        CProgressDialogUtils.cancelProgressDialog(JavaActivity.this);
            }

            /**
             * 没有新版本
             */
            @Override
            public void noNewApp() {
                // ToastUtils.showLong("没有新版本", Toast.LENGTH_SHORT).show();
            }
        });



public class AppUpdateUtil {

    public static void update(Activity activity, String updateUrl, Map<String, String> params, boolean isPost, UpdateCallback updateCallback) {
        if(params == null){
            params = new WeakHashMap<>();
            params.put("appKey", "ab55ce55Ac4bcP408cPb8c1Aaeac179c5f6f");
            params.put("appVersion", "1.0");
        }
        new UpdateAppManager
                .Builder()
                //必须设置,当前Activity
                .setActivity(activity)
                //必须设置,实现httpManager接口的对象
                 .setHttpManager(new UpdateAppHttpUtil(activity))
                //必须设置,更新地址
                .setUpdateUrl(updateUrl)
                //以下设置,都是可选
                //设置请求方式,默认get
                .setPost(isPost)
                //添加自定义参数,默认version=1.0.0(app的versionName);apkKey=唯一表示(在AndroidManifest.xml配置)
                .setParams(params)
                //设置点击升级后,消失对话框,默认点击升级后,对话框显示下载进度
                .hideDialogOnDownloading(false)
                //设置头部,不设置显示默认的图片,设置图片后自动识别主色调,然后为按钮,进度条设置颜色
                // .setTopPic(R.mipmap.top_8)
                //为按钮,进度条设置颜色,默认从顶部图片自动识别。
                //.setThemeColor(ColorUtil.getRandomColor())
                //设置apk下砸路径,默认是在下载到sd卡下/Download/1.0.0/test.apk
                // .setTargetPath(path)
                //设置appKey,默认从AndroidManifest.xml获取,如果,使用自定义参数,则此项无效
                //.setAppKey("ab55ce55Ac4bcP408cPb8c1Aaeac179c5f6f")
                //不显示通知栏进度条
                //.dismissNotificationProgress()
                //是否忽略版本
                //.showIgnoreVersion()
                .build()
                //检测是否有新版本
                .checkNewApp(updateCallback);
    }
}

package cn.jiiiiiin.vplus.core.update;

import android.app.Activity;
import android.support.annotation.NonNull;

import com.vector.update_app.HttpManager;
import com.zhy.http.okhttp.callback.FileCallBack;

import java.io.File;
import java.util.Map;
import java.util.WeakHashMap;

import cn.jiiiiiin.vplus.core.net.RestClientBuilder;
import cn.jiiiiiin.vplus.core.net.RestOkHttpUtilsClient;
import cn.jiiiiiin.vplus.core.util.log.LoggerProxy;
import okhttp3.Call;
import okhttp3.Request;

/**
 * Created by Vector
 * on 2017/6/19 0019.
 */

public class UpdateAppHttpUtil implements HttpManager {


    private final Activity ACTIVITY;

    public UpdateAppHttpUtil(Activity activity) {
        this.ACTIVITY = activity;
    }

    /**
     * 异步get
     *
     * @param url      get请求地址
     * @param params   get参数
     * @param callBack 回调
     */
    @Override
    public void asyncGet(@NonNull String url, @NonNull Map<String, String> params, @NonNull final Callback callBack) {
        RestClientBuilder restClientBuilder = RestOkHttpUtilsClient.builder(ACTIVITY)
                .ignoreCommonCheck()
                // loader 由前端控制
                //.loader()
                .url(url);
        restClientBuilder.params(new WeakHashMap<>(params));
        // 业务判断由前端完成
        restClientBuilder.ignoreCommonCheck()
                .success(response -> {
                    callBack.onResponse(response.toJSONString());
                })
                .failure(() -> callBack.onError("请求失败,请稍后尝试"))
                .error(errRes -> callBack.onError(String.format("请求失败,请稍后尝试[%s]", errRes)))
                .build()
                .get();
    }

    /**
     * 异步post
     *
     * @param url      post请求地址
     * @param params   post请求参数
     * @param callBack 回调
     */
    @Override
    public void asyncPost(@NonNull String url, @NonNull Map<String, String> params, @NonNull final Callback callBack) {
        RestClientBuilder restClientBuilder = RestOkHttpUtilsClient.builder(ACTIVITY)
                .ignoreCommonCheck()
                // loader 由前端控制
                //.loader()
                .url(url);
        restClientBuilder.params(new WeakHashMap<>(params));
        // 业务判断由前端完成
        restClientBuilder.ignoreCommonCheck()
                .success(response -> {
                    callBack.onResponse(response.toJSONString());
                })
                .failure(() -> callBack.onError("请求失败,请稍后尝试"))
                .error(errRes -> callBack.onError(String.format("请求失败,请稍后尝试[%s]", errRes)))
                .build()
                .post();
    }

    /**
     * 下载
     *
     * @param url      下载地址
     * @param path     文件保存路径
     * @param fileName 文件名称
     * @param callback 回调
     */
    @Override
    public void download(@NonNull String url, @NonNull String path, @NonNull String fileName, @NonNull final FileCallback callback) {
        LoggerProxy.e("fileCallBack %s %s %s ", url, path, fileName);
        RestOkHttpUtilsClient.builder(ACTIVITY)
                .ignoreCommonCheck()
                // loader 由前端控制
                //.loader()
                .url(url)
                .fileCallBack(new FileCallBack(path, fileName) {
                    @Override
                    public void inProgress(float progress, long total, int id) {
                        LoggerProxy.e("inProgress %s", progress);
                        callback.onProgress(progress, total);
                    }

                    @Override
                    public void onError(Call call, Exception e, int id) {
                        LoggerProxy.e(e, "onError");
                    }

                    @Override
                    public void onResponse(File response, int id) {
                        LoggerProxy.e("onResponse %s", response.exists());
                        callback.onResponse(response);
                    }

                    @Override
                    public void onBefore(Request request, int id) {
                        LoggerProxy.e("onBefore %s", request);
                        super.onBefore(request, id);
                        callback.onBefore();
                    }
                })
                .build()
                .download();

    }
}

download方法已经执行到了onResponse ,而且 LoggerProxy.e("onResponse %s", response.exists());这一行打出来的为true,为啥还不能安装呢?
@WVector 麻烦您帮忙看看。

commented

刚才我用华为mate8 7.0系统可以使用。
但是8.0的系统还是不支持,安装,而且会出现状态栏通知不出来问题:

03-29 20:44:53.785 8925-8925/com.csii.mobilebank E/NotificationManager: notifyAsUser: tag=null, id=0, user=UserHandle{0}
03-29 20:45:04.684 8925-8925/com.csii.mobilebank E/NotificationManager: notifyAsUser: tag=null, id=0, user=UserHandle{0}
03-29 20:45:16.283 8925-8925/com.csii.mobilebank E/NotificationManager: notifyAsUser: tag=null, id=0, user=UserHandle{0}
03-29 20:45:16.473 8925-8932/com.csii.mobilebank I/zygote64: Compiler allocated 6MB to compile void android.view.ViewRootImpl.performTraversals()
03-29 20:45:29.406 8925-8925/com.csii.mobilebank E/NotificationManager: notifyAsUser: tag=null, id=0, user=UserHandle{0}
03-29 20:45:32.300 8925-8925/com.csii.mobilebank E/NotificationManager: notifyAsUser: tag=null, id=0, user=UserHandle{0}
03-29 20:45:37.086 8925-8925/com.csii.mobilebank E/NotificationManager: notifyAsUser: tag=null, id=0, user=UserHandle{0}

但是我奇怪的是,为什么官方demo是ok的呢?

android8.0 通知的问题已经适配

commented

@WVector 我更新之后测试:

static void appUpdate(final Activity activity, boolean needShowProgress) {
        DeviceUtil.generateWriteExternalStorage(activity, (granted) -> {
            if (granted) {
                _update(activity, needShowProgress);
            } else {
                ToastUtils.showLong("未授权SD卡写权限,应用更新无法正常进行,存在某些应用不能得到及时更新的风险");
            }
        });
}


    private static void _update(Activity activity, boolean needShowProgress) {
        // 官方测试
        new UpdateAppManager
                .Builder()
                //当前Activity
                .setActivity(activity)
                //更新地址
                .setUpdateUrl("https://raw.githubusercontent.com/WVector/AppUpdateDemo/master/json/json.txt")
                //实现httpManager接口的对象
                .setHttpManager(new UpdateAppHttpUtil(activity))
                .build()
                .update();
}

发现3个问题:

  1. 通知栏每每前进百分之1就【报警】一声
  2. 切换到任务栏之后,更新就会断掉,必须重新开始
  3. 下载成功不安装,之后还需要从零开始下载

控制台在更新的时候还是会报:

03-30 16:09:01.758 29447-29447/com.csii.mobilebank E/NotificationManager: notifyAsUser: tag=null, id=0, user=UserHandle{0}
03-30 16:09:02.479 29447-29447/com.csii.mobilebank E/NotificationManager: notifyAsUser: tag=null, id=0, user=UserHandle{0}
03-30 16:09:03.858 29447-29447/com.csii.mobilebank E/NotificationManager: notifyAsUser: tag=null, id=0, user=UserHandle{0}
03-30 16:09:05.987 29447-29447/com.csii.mobilebank E/NotificationManager: notifyAsUser: tag=null, id=0, user=UserHandle{0}
03-30 16:09:07.324 29447-29447/com.csii.mobilebank E/NotificationManager: notifyAsUser: tag=null, id=0, user=UserHandle{0}
commented

另外一个,其实appkey和appVersion是框架所需的后台交易需要的参数,针对一般的应用来说都会存在自身的交易和返回值,所以这个应该不是必须的:

//        if(params == null){
//            params = new WeakHashMap<>();
//            params.put("appKey", "ab55ce55Ac4bcP408cPb8c1Aaeac179c5f6f");
//            params.put("appVersion", "1.0");
//        }

避免误导有些同学,觉得是不是非得用,其实这个插件好的地方出了UI还有就是.checkNewApp(updateCallback)提供了我们这个回调自己去适配的功能,这就够了。因为需求其实是千变万化的,比如我这边的需求就是"https://www.easy-mock.com/mock/5abc903ff5c35b191f472d79/example/QryMobileClientVerNew.do" 请求这样一个后台地址(POST),返回的不仅仅是app的更新信息还有h5的离线缓存包更新信息。