apk的版本更新

昨天在做apk的版本更新时遇到一个问题是,安装后会提示已有不同签名的应用存在。然后我就蒙圈了,一一进行排查,后来才发现,是我手机上已有低版本的应用,而这个应用是直接用android studio 部署上去的,它会是用的默认签名,所以会报有不同签名的应用存在,所以我又重新打个包安装后,提示更新,下载后就成功了。

后来又遇到一种情况,就是apk下载不下来,然后我把从后台获取的apk下载的url放到pc端,同样下载不下来,和后台反应,原来是后台配置错了,给返回的url是错误的。。。。也是醉了。

更新代码如下:

public class UpdateService extends Service {
    // 标题
    private int titleId = 0;
    // 文件存储
    private File updateDir = null;
    private File updateFile = null;
    // 通知栏
    private NotificationManager updateNotificationManager = null;
    private Notification.Builder updateNotification = null;
    // 通知栏跳转Intent
    private Intent updateIntent = null;
    private PendingIntent updatePendingIntent = null;
    // 下载状态
    private final static int DOWNLOAD_COMPLETE = 0;
    private final static int DOWNLOAD_FAIL = 1;
    //获取更新apk的 url路径
//    private String urlString;
    //更新apk的路径  是从后台获取的
    private String apkUrl;
    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }
    @SuppressWarnings("deprecation")
    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {

        // 获取传值
        if (intent!=null){

            titleId = intent.getIntExtra("titleId", 0);
            apkUrl = intent.getStringExtra("apkUrl");
        }
        System.out.println("titleId-----------" + titleId);
        // 创建文件
        if (Environment.MEDIA_MOUNTED.equals(Environment
                .getExternalStorageState())) {

            updateDir = new File(Environment.getExternalStorageDirectory(),
                    App.downloadDir);
            updateFile = new File(updateDir.getPath(), getResources()
                    .getString(titleId) + ".apk");


        }
        this.updateNotificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
        this.updateNotification = new Notification.Builder(this);

        // 设置下载过程中,点击通知栏,回到主界面
        updateIntent = new Intent(this, SettingAct.class);
        updatePendingIntent = PendingIntent.getActivity(this, 0, updateIntent,
                0);

        // 设置通知栏显示内容
        updateNotification.setSmallIcon(R.mipmap.logo).setContentTitle("").setContentText("开始下载");
        updateNotification.setContentIntent(updatePendingIntent);

        // 发出通知
        updateNotificationManager.notify(0, updateNotification.getNotification());
        // 开启一个新的线程下载,如果使用Service同步下载,会导致ANR问题,Service本身也会阻塞
        new Thread(new updateRunnable()).start();// 这个是下载的重点,是下载的过程
        return super.onStartCommand(intent, flags, startId);

    }

    private Handler updateHandler = new Handler() {
        @SuppressWarnings("deprecation")
        @Override
        public void handleMessage(Message msg) {
            switch (msg.what) {
                case DOWNLOAD_COMPLETE:
                    // 点击安装PendingIntent
                    Uri uri = Uri.fromFile(updateFile);
                    Intent installIntent = new Intent(Intent.ACTION_VIEW);
                    installIntent.setDataAndType(uri,
                            "application/vnd.android.package-archive");
                    updatePendingIntent = PendingIntent.getActivity(
                            UpdateService.this, 0, installIntent, 0);
                    updateNotification.setDefaults(Notification.DEFAULT_SOUND);// 铃声提醒
//          updateNotification.setLatestEventInfo(UpdateService.this,
//                "惠逛街", "下载完成,点击安装。", updatePendingIntent);
                    updateNotification.setSmallIcon(R.mipmap.logo).setContentTitle("惠逛街").setContentText("下载完成,点击安装").setContentIntent(updatePendingIntent);
                    updateNotificationManager.notify(0, updateNotification.getNotification());

                    // 停止服务
                    stopSelf();
                    break;
                case DOWNLOAD_FAIL:
                    // 下载失败
//                    updateNotification.setLatestEventInfo(UpdateService.this,
//                            "", "下载完成,点击安装。", updatePendingIntent);
                    updateNotification.setSmallIcon(R.mipmap.logo).setContentTitle("").setContentText("下载完成,点击安装").setContentIntent(updatePendingIntent);
                    updateNotificationManager.notify(0, updateNotification.getNotification());
                    break;
                default:
                    stopSelf();
            }
        }
    };

    class updateRunnable implements Runnable {
        Message message = updateHandler.obtainMessage();

        public void run() {
            message.what = DOWNLOAD_COMPLETE;
            //开启请求获取http://t.doolii.cn/m/pub/upgrade?versionCode=1  中的url  其中的参数只是versionCode
//       getUrl();
            try {
                // 增加权限;
                if (!updateDir.exists()) {
                    updateDir.mkdirs();
                }
                if (!updateFile.exists()) {
                    updateFile.createNewFile();
                }
                // 下载函数,以QQ为例子
                // 增加权限;
                //测试环境
                //http://www.doolii.cn/static/doolii/apk/test-apk/doolii.apk
                //生产环境
//          http://www.doolii.cn/static/doolii/apk/doolii.apk
                long downloadSize = downloadUpdateFile(
                       apkUrl,
                        updateFile);
                if (downloadSize > 0) {
                    // 下载成功
                    updateHandler.sendMessage(message);
                }
            } catch (Exception ex) {
                ex.printStackTrace();
                message.what = DOWNLOAD_FAIL;
                // 下载失败
                updateHandler.sendMessage(message);
            }
        }

    }



    @SuppressWarnings("deprecation")
    public long downloadUpdateFile(String downloadUrl, File saveFile)
            throws Exception {

        // 这样的下载代码很多,我就不做过多的说明
        int downloadCount = 0;
        int currentSize = 0;
        long totalSize = 0;
        int updateTotalSize = 0;
        HttpURLConnection httpConnection = null;
        InputStream is = null;
        FileOutputStream fos = null;
        try {
            URL url = new URL(downloadUrl);
            httpConnection = (HttpURLConnection) url.openConnection();
            httpConnection
                    .setRequestProperty("User-Agent", "PacificHttpClient");
            if (currentSize > 0) {
                httpConnection.setRequestProperty("RANGE", "bytes="
                        + currentSize + "-");
            }
            httpConnection.setConnectTimeout(10000);
            httpConnection.setReadTimeout(20000);
            updateTotalSize = httpConnection.getContentLength();
            if (httpConnection.getResponseCode() == 404) {
                throw new Exception("fail!");
            }
            is = httpConnection.getInputStream();
            fos = new FileOutputStream(saveFile, false);
            byte buffer[] = new byte[1024];
            int readsize = 0;
            while ((readsize = is.read(buffer)) > 0) {
                fos.write(buffer, 0, readsize);
                totalSize += readsize;
                // 为了防止频繁的通知导致应用吃紧,百分比增加10才通知一次
                if ((downloadCount == 0)
                        || (int) (totalSize * 100 / updateTotalSize) - 10 > downloadCount) {
                    downloadCount += 10;
//             updateNotification.setLatestEventInfo(UpdateService.this,
//                   "正在下载", (int) totalSize * 100 / updateTotalSize
//                         + "%", updatePendingIntent);
                   
  updateNotification.setSmallIcon(R.mipmap.logo).setContentTitle("下载进度").setContentText("正在下载中...");
//                    for (int i = 0; i < updateTotalSize-1; i++) {
//                        updateNotification.setProgress(updateTotalSize, (int) totalSize / updateTotalSize, false); // i 代表当前进度值
                        updateNotification.setProgress(100, downloadCount, false); // i 代表当前进度值
// } updateNotificationManager.notify(0, updateNotification.getNotification()); } } fos.flush(); Log.i("apk....", saveFile.length()+""); } finally { if (httpConnection != null) { httpConnection.disconnect(); } if (is != null) { is.close(); } if (fos != null) { fos.close(); } } return totalSize; }}而检查版本是否需要更新是在闪屏页进行检查的。代码如下:
/*
* 闪屏页:判断用户是否已经登录,如果已经登录,直接进入主页,否则,进入登录页面?
*/
public class SplashActivity extends BaseActivity {


    private Button login;
    private RelativeLayout rlBackground;

    //商场列表
    private ArrayList<MarketEntity> marketList;
    private String name;
    private int targetId;//商场id
    private UpdateBean update;
    private String apkUrl;//apk下载地址

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_splash);
        // 检查版本
        checkVersion();



    }
    //闪屏页 判断是否第一次登陆
    private void splash() {
        // 闪屏的核心代码
        new Handler().postDelayed(new Runnable() {
            @Override
            public void run() {
                Intent intent = new Intent(); // 从启动动画ui跳转到主ui
                // 判断是否已经登录,若登录跳转到首页,否则跳转到登录页面
                if (SharedPerferenceUtils.getBoolean(SplashActivity.this, "isLogin", false)) {
                    initMarketData();
                    intent.setClass(SplashActivity.this, MainActivity.class);
                } else {
                    intent.setClass(SplashActivity.this, LoginActivity.class);
                }
                startActivity(intent);
                overridePendingTransition(R.anim.base_slide_in,
                        R.anim.base_slide_right_out);
                SplashActivity.this.finish(); // 结束启动动画界面

            }
        }, 1000); // 启动动画持续3秒钟
    }

    private void checkVersion() {
        Integer versionCode = getVersion();

        // 判断网络状态
        if (!NetUtils.checkConnected(this)) {
            CommonUtils.showToastMsg(this, "网络不可用");
            return;
        }

//        String url = Constant.Upgrade + "?current=" + getVersionName();
        String url = Constant.Upgrade + "?current=" + 2;
        VolleyRequest.jsonRequest(SplashActivity.this, Request.Method.GET, url, Constant.HGJ_TAG, null, new VolleyInterface(SplashActivity.this, VolleyInterface.mListener, VolleyInterface.mErrorListener) {
            @Override
            public void onMySuccess(JSONObject result) {
                System.out.println("版本升级result---" + result);
                if (result != null) {
                    try {
                        if (result.getInt("code") == 200) {
                            update = GsonUtils.jsonToBean(result.getJSONObject("entity").toString(), UpdateBean.class);

                            if (Integer.valueOf(update.getCode()) <= getVersion()) {
                                // 无需升级,
//                                NOUpdate();
                                splash();

                            } else {//请求下来的版本》本地版本 需要升级
                                apkUrl = update.getUrl();
                                if (!StringUtils.isEmptyString(apkUrl)){
                                    if (update.isMust()) {
                                        //强制升级
                                        mustUpdate();
                                    } else {
                                        Update();
                                    }
                                }

                            }
                        }
                    } catch (JSONException e) {
                        e.printStackTrace();
                    }
                }
            }

            @Override
            public void onMyError(VolleyError error) {
//                CommonUtils.showToastMsg(SplashActivity.this, "请求失败check");
                Log.i("请求走了吗","请求失败check");
            }
        });




    }
    protected void mustUpdate() {


        // TODO Auto-generated method stub
        CustomDialog.Builder customBuilder = new CustomDialog.Builder(
                SplashActivity.this);
        customBuilder
                .setTitle("版本信息")
                .setMessage("有新版本" + update.getCode() + "。")
                .setNegativeButton("去升级",
                        new DialogInterface.OnClickListener() {
                            public void onClick(DialogInterface dialog,
                                                int which) {
                                dialog.dismiss();
                                splash();
                                //开启更新服务UpdateService
                                //这里为了把update更好模块化,可以传一些updateService依赖的值
                                //如布局ID,资源ID,动态获取的标题,这里以app_name为例
                                Intent updateIntent = new Intent(SplashActivity.this, UpdateService.class);
                                updateIntent.putExtra("titleId", R.string.app_name);
                                updateIntent.putExtra("apkUrl",apkUrl);
                                startService(updateIntent);

                            }
                        });

        CustomDialog dialog = customBuilder.create();
        dialog.show();


    }

    /**
     * @param 设定文件
     * @return void 返回类型
     * @Description: TODO()
     */
    protected void Update() {

        // TODO Auto-generated method stub
        CustomDialog.Builder customBuilder = new CustomDialog.Builder(
                SplashActivity.this);
        customBuilder
                .setTitle("版本信息")
                .setMessage("有新版本" + update.getCode() + "。")

                .setPositiveButton("知道了",
                        new DialogInterface.OnClickListener() {
                            public void onClick(DialogInterface dialog,
                                                int which) {
                                dialog.dismiss();

                            }
                        })
                .setNegativeButton("去升级",
                        new DialogInterface.OnClickListener() {
                            public void onClick(DialogInterface dialog,
                                                int which) {
                                dialog.dismiss();
                                splash();
                                //开启更新服务UpdateService
                                //这里为了把update更好模块化,可以传一些updateService依赖的值
                                //如布局ID,资源ID,动态获取的标题,这里以app_name为例
                                Intent updateIntent = new Intent(SplashActivity.this, UpdateService.class);
                                updateIntent.putExtra("titleId", R.string.app_name);
                                updateIntent.putExtra("apkUrl",apkUrl);
                                startService(updateIntent);

                            }
                        });

        CustomDialog dialog = customBuilder.create();
        dialog.show();

    }

    /**
     * @param 设定文件
     * @return void 返回类型
     * @Description: TODO()
     */
    protected void NOUpdate() {

        // TODO Auto-generated method stub
        CustomDialog.Builder customBuilder = new CustomDialog.Builder(
                SplashActivity.this);
        customBuilder
                .setTitle("版本信息")
                .setMessage("当前已是最新版本。")

                .setNegativeButton("知道了",
                        new DialogInterface.OnClickListener() {
                            public void onClick(DialogInterface dialog,
                                                int which) {
                                dialog.dismiss();

                            }
                        });

        CustomDialog dialog = customBuilder.create();
        dialog.show();

    }

    // 获取版本号
    private int getVersion() {
        // 获取packagemanager的实例
        PackageManager packageManager = getPackageManager();
        // getPackageName()是你当前类的包名,0代表是获取版本信息
        PackageInfo packInfo = null;
        try {
            packInfo = packageManager.getPackageInfo(getPackageName(), 0);
        } catch (PackageManager.NameNotFoundException e) {
            e.printStackTrace();
        }
        Integer version = packInfo.versionCode;
        return version;

    }

    // 获取版本
    private String getVersionName() {
        // 获取packagemanager的实例
        PackageManager packageManager = getPackageManager();
        // getPackageName()是你当前类的包名,0代表是获取版本信息
        PackageInfo packInfo = null;
        try {
            packInfo = packageManager.getPackageInfo(getPackageName(), 0);
        } catch (PackageManager.NameNotFoundException e) {
            e.printStackTrace();
        }
        String version = packInfo.versionName;
        return version;

    }

    //商场列表
    private void initMarketData() {
        Map<Object, Object> params = new HashMap<>();
        final JSONObject json = new JSONObject(params);//map转换成JSONObject
        VolleyRequest.jsonRequest(this, Request.Method.GET, Constant.MarketList, Constant.HGJ_TAG, json, new VolleyInterface(SplashActivity.this, VolleyInterface.mListener, VolleyInterface.mErrorListener) {
            @Override
            public void onMySuccess(JSONObject result) {
                if (result != null) {
                    System.out.println("商场列表请求marketList------" + result);
                    try {
                        if (result.getInt("code") == 200) {
                            JSONArray jsonArray = result.getJSONArray("entity");
                            marketList = new ArrayList<MarketEntity>();
                            if (jsonArray!=null&&jsonArray.length()!=0){
                                for (int i = 0; i < jsonArray.length(); i++) {
                                    JSONObject jsonObject = jsonArray.optJSONObject(i);
                                    MarketEntity marketEntity = new MarketEntity();
                                    marketEntity.setAddress(jsonObject.optString("address"));
                                    targetId = jsonObject.optInt("id");
                                    marketEntity.setId(targetId);
                                    name = jsonObject.optString("name");
                                    marketEntity.setName(name);
                                    marketEntity.setPhone(jsonObject.optString("phone"));
                                    marketList.add(marketEntity);
                                    App.markets = marketList;
                                }
                                System.out.println("商场列表list---" + marketList);
                            }

                        } else {
                            CommonUtils.showToastMsg(SplashActivity.this, result.getString("msg"));
                        }
                    } catch (JSONException e) {
                        e.printStackTrace();
                    }
                }
            }

            @Override
            public void onMyError(VolleyError error) {
                CommonUtils.showToastMsg(SplashActivity.this, "请求失败");
                Log.i("----VolleyError----", error + "");
            }
        });
    }

}









评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值