美文网首页
Android实现自动下载更新和跳转到应用市场更新

Android实现自动下载更新和跳转到应用市场更新

作者: 简单点的笨演员 | 来源:发表于2020-10-28 15:03 被阅读0次

Android使用AutoUpdateProject库实现自动下载更新很简单,不需要自制UI,不需要写代码(几乎直接复制就行了)

  1. 在你的项目的根目录的build.gradle添加如下代码:
allprojects { repositories { ... maven { url 'https://jitpack.io' } } }
  1. 在你的app的目录的build.gradle添加如下代码:
    dependencies { implementation 'com.github.MZCretin:AutoUpdateProject:latest_version' }
  1. 填写版本信息json文件,上传到远程目录,如假设上传到https://www.xxx.com/apps/app-update.json,并将apk上传到配置里的路径:
{
  "versionCode": 1144,
  "isForceUpdate": 0,
  "preBaselineCode": 55,
  "versionName": "v1.144",
  "downurl": "https://www.xxx.com/apps/app-update.apk",
  "updateLog": "v1.144\r\n1、优化体验\n2、修复已知bug",
  "size": "5913570",
  "hasAffectCodes": "",
  "originMD5":"E083D1253220B10F8EACBE21A562C7E2"
}
  1. 添加版本信息json解析Model文件,保存为UpdateModel.java(代码来源自动更新库的demo):
package com.xxx.app;

import com.cretin.www.cretinautoupdatelibrary.model.LibraryUpdateEntity;

/**
 * Created by cretin on 2017/4/21.
 * 这个model是调用 http://www.cretinzp.com/system/versioninfo 这个接口之后返回的数据
 */
public class UpdateModel implements LibraryUpdateEntity {

    /**
     * id : test
     * page : 1
     * rows : 10
     * isForceUpdateFlag : 0
     * preBaselineCode : 0
     * versionName : V1.0.1
     * versionCode : 3
     * downurl : http://120.24.5.102/Webconfig/frj01_211_jiagu_sign.apk
     * updateLog : 1、修复bug
     * size : 10291218
     * hasAffectCodes : 1|2
     * createTime : 1489651956000
     * iosVersion : 1
     */

    private int isForceUpdate;
    private int preBaselineCode;
    private String versionName;
    private int versionCode;
    private String downurl;
    private String updateLog;
    private String size;
    private String hasAffectCodes;
    private long createTime;
    private int iosVersion;
    private String originMD5;

    public int getIsForceUpdate() {
        return isForceUpdate;
    }

    public void setIsForceUpdate(int isForceUpdate) {
        this.isForceUpdate = isForceUpdate;
    }

    public int getPreBaselineCode() {
        return preBaselineCode;
    }

    public void setPreBaselineCode(int preBaselineCode) {
        this.preBaselineCode = preBaselineCode;
    }

    public String getVersionName() {
        return versionName;
    }

    public void setVersionName(String versionName) {
        this.versionName = versionName;
    }

    public int getVersionCode() {
        return versionCode;
    }

    public void setVersionCode(int versionCode) {
        this.versionCode = versionCode;
    }

    public String getDownurl() {
        return downurl;
    }

    public void setDownurl(String downurl) {
        this.downurl = downurl;
    }

    public String getUpdateLog() {
        return updateLog;
    }

    public void setUpdateLog(String updateLog) {
        this.updateLog = updateLog;
    }

    public String getSize() {
        return size;
    }

    public void setSize(String size) {
        this.size = size;
    }

    public String getHasAffectCodes() {
        return hasAffectCodes;
    }

    public void setHasAffectCodes(String hasAffectCodes) {
        this.hasAffectCodes = hasAffectCodes;
    }

    public long getCreateTime() {
        return createTime;
    }

    public void setCreateTime(long createTime) {
        this.createTime = createTime;
    }

    public int getIosVersion() {
        return iosVersion;
    }

    public void setIosVersion(int iosVersion) {
        this.iosVersion = iosVersion;
    }

    public String getOriginMD5() {
        return originMD5;
    }

    public void setOriginMD5(String originMD5) {
        this.originMD5 = originMD5;
    }

    @Override
    public int getAppVersionCode() {
        return getVersionCode();
    }

    @Override
    public int forceAppUpdateFlag() {
        return getIsForceUpdate();
    }

    @Override
    public String getAppVersionName() {
        return getVersionName().replaceFirst("v", "");
    }

    @Override
    public String getAppApkUrls() {
        return getDownurl();
    }

    @Override
    public String getAppUpdateLog() {
        return getUpdateLog();
    }

    @Override
    public String getAppApkSize() {
        return getSize();
    }

    @Override
    public String getAppHasAffectCodes() {
        return getHasAffectCodes();
    }

    @Override
    public String getFileMd5Check() {
        return getOriginMD5();
    }
}

  1. 在app的启动界面或者主界面的onCreate方法中添加检查更新的代码:
//当你希望使用配置请求链接的方式,让插件自己解析并实现更新
UpdateConfig updateConfig = new UpdateConfig()
        .setDebug(true)//是否是Debug模式
        .setBaseUrl("https://www.xxx.com/apps/app-update.json") ///// 版本信息的url
        .setMethodType(TypeConfig.METHOD_GET)
        .setDataSourceType(TypeConfig.DATA_SOURCE_TYPE_URL)
        .setShowNotification(true)//配置更新的过程中是否在通知栏显示进度
        .setUiThemeType(TypeConfig.UI_THEME_B)//配置UI的样式,一种有12种样式可供选择
        .setRequestHeaders(null)
        .setRequestParams(null)
        .setAutoDownloadBackground(false)//是否需要后台静默下载
        .setNeedFileMD5Check(false)//是否需要进行文件的MD5检验
        .setModelClass(new UpdateModel());
AppUpdateUtils.init(this, updateConfig);
AppUpdateUtils.getInstance().checkUpdate();

至此,App自动下载更新的功能就完成了,接下来是跳转到App应用市场更新部分。

  1. 由于自动更新库没有提供跳转到App应用市场的功能,只提供自定义更新弹窗UI的功能,所以我们需要添加一个UI,利用自定义的弹窗UI上的“立即更新”按钮来跳转到应用市场,将下面的代码保存到UpdateActivity.java(需要修改tvBtn2.setOnClickListener里的两个变量):
package com.xxx.app;

import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.net.Uri;
import android.os.Bundle;
import android.text.TextUtils;
import android.text.method.ScrollingMovementMethod;
import android.util.Log;
import android.view.View;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;

import com.cretin.www.cretinautoupdatelibrary.R;
import com.cretin.www.cretinautoupdatelibrary.interfaces.AppDownloadListener;
import com.cretin.www.cretinautoupdatelibrary.model.DownloadInfo;
import com.cretin.www.cretinautoupdatelibrary.utils.LogUtils;
import com.cretin.www.cretinautoupdatelibrary.utils.ResUtils;
import com.cretin.www.cretinautoupdatelibrary.utils.RootActivity;

import java.util.ArrayList;
import java.util.List;

/**
 * 类似虎牙直播的更新样式
 */
public class UpdateActivity extends RootActivity {

    private TextView tvMsg;
    private TextView tvBtn2;
    private ImageView ivClose;
    private TextView tvVersion;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_update_type2);

        findView();

        setDataAndListener();
    }

    private void setDataAndListener() {
        tvMsg.setText(downloadInfo.getUpdateLog());
        tvMsg.setMovementMethod(ScrollingMovementMethod.getInstance());
        tvVersion.setText("v"+downloadInfo.getProdVersionName());

        if (downloadInfo.isForceUpdateFlag()) {
            ivClose.setVisibility(View.GONE);
        } else {
            ivClose.setVisibility(View.VISIBLE);
        }

        ivClose.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                finish();
            }
        });

        tvBtn2.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                //更新按钮
                String shopName = "com.tencent.android.qqdownloader";   // 需要修改
                String appId = "com.xxx.app";           // 需要修改
                if (isAvilible(shopName)) {  // 有应用商店
                    launchAppDetail(appId, shopName);
                } else {
                    download();
                }
            }
        });
    }

    private void findView() {
        tvMsg = findViewById(R.id.tv_content);
        tvBtn2 = findViewById(R.id.tv_update);
        ivClose = findViewById(R.id.iv_close);
        tvVersion = findViewById(R.id.tv_version);
    }

    @Override
    public AppDownloadListener obtainDownloadListener() {
        return new AppDownloadListener() {
            @Override
            public void downloading(int progress) {
                tvBtn2.setText(ResUtils.getString(R.string.downloading)+progress+"%");
            }

            @Override
            public void downloadFail(String msg) {
                tvBtn2.setText(ResUtils.getString(R.string.btn_update_now));
                Toast.makeText(UpdateActivity.this, ResUtils.getString(R.string.apk_file_download_fail), Toast.LENGTH_SHORT).show();
            }

            @Override
            public void downloadComplete(String path) {
                tvBtn2.setText(ResUtils.getString(R.string.btn_update_now));
            }

            @Override
            public void downloadStart() {
                tvBtn2.setText(ResUtils.getString(R.string.downloading));
            }

            @Override
            public void reDownload() {
                LogUtils.log("下载失败后点击重试");
            }

            @Override
            public void pause() {

            }
        };
    }

    /**
     * 启动Activity
     *
     * @param context
     * @param info
     */
    public static void launch(Context context, DownloadInfo info) {
        launchActivity(context, info, UpdateActivity.class);
    }

    /**
     * 判断应用市场是否存在的方法
     *
     *
     * 主流应用商店对应的包名
     * com.android.vending    -----Google Play
     * com.tencent.android.qqdownloader     -----应用宝
     * com.qihoo.appstore    -----360手机助手
     * com.baidu.appsearch    -----百度手机助
     * com.xiaomi.market    -----小米应用商店
     * com.wandoujia.phoenix2    -----豌豆荚
     * com.huawei.appmarket    -----华为应用市场
     * com.taobao.appcenter    -----淘宝手机助手
     * com.hiapk.marketpho    -----安卓市场
     * cn.goapk.market        -----安智市场
     */
    public boolean isAvilible(String marketPkg) {
        // 获取packagemanager
        final PackageManager packageManager = this.getPackageManager();
        // 获取所有已安装程序的包信息
        List<PackageInfo> pinfo = packageManager.getInstalledPackages(0);
        // 用于存储所有已安装程序的包名
        List<String> pName = new ArrayList<String>();
        // 从pinfo中将包名字取出
        if (pinfo != null) {
            for (int i = 0; i < pinfo.size(); i++) {
                String pf = pinfo.get(i).packageName;
                pName.add(pf);
            }
        }
        // 判断pName中是否有目标程序的包名,有true,没有false
        return pName.contains(marketPkg);
    }

    /**
     * 启动到应用商店app详情界面
     *
     * @param appPkg    目标App的包名
     * @param marketPkg 应用商店包名 ,如果为""则由系统弹出应用商店列表供用户选择,否则调转到目标市场的应用详情界面
     */
    public void launchAppDetail(String appPkg, String marketPkg) {
        try {
            if (TextUtils.isEmpty(appPkg)) {
                return;
            }

            Uri uri = Uri.parse("market://details?id=" + appPkg);
            Intent intent = new Intent(Intent.ACTION_VIEW, uri);
            if (!TextUtils.isEmpty(marketPkg)) {
                intent.setPackage(marketPkg);
            }
            intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
            this.startActivity(intent);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
  1. 在app的AndroidManifest.xml添加下面的Activity代码:
<activity
    android:name=".UpdateActivity"
    android:theme="@style/DialogActivityTheme" />
  1. 修改第五步的代码:
//当你希望使用配置请求链接的方式,让插件自己解析并实现更新
UpdateConfig updateConfig = new UpdateConfig()
        .setDebug(true)//是否是Debug模式
        .setBaseUrl("https://www.xxx.com/apps/app-update.json") ///// 版本信息的url
        .setMethodType(TypeConfig.METHOD_GET)
        .setDataSourceType(TypeConfig.DATA_SOURCE_TYPE_URL)
        .setShowNotification(true)
        .setUiThemeType(TypeConfig.UI_THEME_CUSTOM)//使用自定义UI
        .setCustomActivityClass(UpdateActivity.class)//使用自定义UI
        .setRequestHeaders(null)
        .setRequestParams(null)
        .setAutoDownloadBackground(false)
        .setNeedFileMD5Check(false)
        .setModelClass(new UpdateModel());
AppUpdateUtils.init(this, updateConfig);
AppUpdateUtils.getInstance().checkUpdate();

至此,App自动跳转到App应用市场更新的功能也完成了。

参考:
https://github.com/MZCretin/AutoUpdateProject
https://www.cnblogs.com/showly/p/11088078.html

相关文章

网友评论

      本文标题:Android实现自动下载更新和跳转到应用市场更新

      本文链接:https://www.haomeiwen.com/subject/ffpxvktx.html