Java4Android之APP自动升级

一个成熟的商业APP必须不断的退出新的版本。那么,不可能让用户自己去应用市场去下载新 版本的应用,我们应该在应用内部提供自动升级的功能。自动升级其实包含两个层面,一个是整个APP的升级,也就是下载新版本的APP,然后安装替换掉现有 的。还有一种升级是模块升级,这种升级一般采用静默升级,就是用户完全不知道。这个在我大迅雷里面经常做的,拿各个渠道去试错,对于一个互联网公司而言是 再普通不过的了。而这些模块,肯定是诸如,解析库,下载库,播放库,这些后台库。。

不过今天,我要说的是APP的自动升级,模块的静默升级我们下次有时间再说。

APP升级流程

盗用别人的图,来说明一下升级APP的整体流程。  \

对,这个图是盗用别人的。因为,这就是APP升级的一般流程。 所以,我们知道了,第一步,我们需要去服务器查询版本信息,确定是不是要进行升级。

到服务器查询版本信息

具体见代码,
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
private  static  final  class  UpgradeLoader  extends  AsyncTask< void void ,= ""  updateinfo= "" > {
         private  WeakReference mContext;
         private  boolean  mAuto;
         private  IUpgradeCheck mUpgradeCheckListener;
         protected  boolean  mChecked;
 
         public  UpgradeLoader(Activity context,  boolean  auto, IUpgradeCheck listener) {
             mContext =  new  WeakReference(context);
             mAuto = auto;
             mUpgradeCheckListener = listener;
         }
 
         @Override
         protected  void  onPreExecute() {
             if  (mUpgradeCheckListener !=  null ) {
                 mUpgradeCheckListener.beforeCheck();
             }
         }
 
         @Override
         protected  UpdateInfo doInBackground(Void... params) {
             if  (mUpgradeCheckListener !=  null ) {
                 mUpgradeCheckListener.onCheck();
             }
             Context ctx = mContext.get();
             String channel =  "" ;
             if  (ctx !=  null ) {
                 channel = Util.getChannelID(ctx);
             }
 
             return  DataProxy.getInstance().getUpdateInfo(Util.getVersionName(MyApplication.sInstance),
                     Util.getOSVersion(), channel);  //去服务器查询版本信息,这个是我们对http的一个封装,在这里,每个公司可以自己定义一些自己的地址和参数,非常简单的。
         }
 
         @Override
         protected  void  onPostExecute(UpdateInfo result) { //从服务器查询回来,决定要不要升级
             if  (mUpgradeCheckListener !=  null ) {
                 mUpgradeCheckListener.afterCheck();
             }
             if  (!isCancelled()) {
                 if  (result ==  null ) {
                     if  (!mAuto) {
                         UIHelper.showToast(MyApplication.sInstance,  "检查更新失败" , Toast.LENGTH_SHORT);
                     }
                 else  {
                     switch  (result.type) {
                     case  UpdateInfo.NO_UPGRADE:
                         if  (!mAuto) {
                             UIHelper.showToast(KankanApplication.sInstance,  "已经是最新版本,没有更新" , Toast.LENGTH_SHORT);
                         }
                         break ;
 
                     case  UpdateInfo.UPDATE_NOT_TIPS:
                         if  (!mAuto) {
                             buildDialog(result);
                         else  {
                             downloadApk(KankanApplication.sInstance, result.latestUrl);
                         }
 
                         break ;
                     case  UpdateInfo.UPDATE_TIPS:
                     case  UpdateInfo.UPDATE_FOURCE:
                         if  (!(mAuto && PreferenceManager.instance(mContext.get()).isVerionSkiped(result.latestVersion))) {
                             buildDialog(result);
                         }
 
                     default :
                         break ;
                     }
                 }
             }
         }</activity></activity></ void ,>
注意上述代码。我们仅仅是示意,所以不可能把所有代码提供给大家学习。就是你第一步是去服务器查询版本信息。然后确定要下载APK的时候,则会调用downloadApk函数。对APK进行下载。

下载APK

在网上,很多人提供了采用 httpclient 去下载APK的方法,我这里给出另外一种思路。两种方法都可以,建议采用我们的提供的,因为,这个是针对下载较大文件的系统方法。 
详见代码:
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
private  static  void  downloadApk(Context context, String url) {
         DownloadManager manager = (DownloadManager) context.getSystemService(Context.DOWNLOAD_SERVICE);
         Uri uri = Uri.parse(url);
         String scheme = uri.getScheme();
         if  (scheme ==  null  || (!scheme.equals( "http" ) && !scheme.equals( "https" ))) {
             LOG.error( "only supports http/https url={}" , url);
         else  {
             try  {
                 DownloadManager.Request down =  new  DownloadManager.Request(uri);
                 down.setAllowedNetworkTypes(DownloadManager.Request.NETWORK_MOBILE
                         | DownloadManager.Request.NETWORK_WIFI);
                 down.setShowRunningNotification( true );
                 down.setVisibleInDownloadsUi( true );
                 down.setDestinationInExternalFilesDir(context,  null , APK_NAME);
                 manager.enqueue(down); //开始下载
             catch  (Exception e) {
                 e.printStackTrace();
 
                 UIHelper.showToast(context,  "下载应用失败,请您去应用市场升级" , Toast.LENGTH_LONG);
             }
         }
     }
这样,使用 DownloadManager 可以非常方便的实现APK的下载。如果想对这个类进行更加深入的了解,大家可以去查询相关的资料。你可以查询下载进度等等相关的信息。 
下载完成了,接下来就是要安装了。我们需要一个事件去触发安装。做法是,我们应该监听下载完成这件事情,下载完成之后,会有个广播发生,当监听到这个广播的时候我们就开始安装。

安装APK

监听下载完成,并安装。
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public  void  onReceive(Context context, Intent intent) {
     if  (intent.getAction().equals(DownloadManager.ACTION_DOWNLOAD_COMPLETE)) { //监听下载完成
         long  id = intent.getLongExtra(DownloadManager.EXTRA_DOWNLOAD_ID, - 1 );
         if  (id > - 1 ) {
             File file = queryFile(context, id);
             if  (file !=  null  && file.exists()) {
                 Intent startInent =  new  Intent();
                 startInent.setAction(Intent.ACTION_VIEW);
                 startInent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                 startInent.setDataAndType(Uri.fromFile(file),  "application/vnd.android.package-archive" );
                 context.startActivity(startInent); //安装APK
             }
         }
     }
}

至此,一个APK的自动升级就完成了。其实还有一些善后工作需要做的是,你需要删除APK,删除APK的方法应该是在安装完成之后删除,网上有说通过广播监听的方法来删除,就是监听到安装完成之后删除。这个大家去搜索一下就可以。

删除APK文件

这里,我还是给出点示例: 首先是要获取应用的安装状态,通过广播的形式
以下是和应用程序相关的Broadcast Action
ACTION_PACKAGE_ADDED 一个新应用包已经安装在设备上,数据包括包名(最新安装的包程序不能接收到这个广播)
ACTION_PACKAGE_REPLACED 一个新版本的应用安装到设备,替换之前已经存在的版本
ACTION_PACKAGE_CHANGED 一个已存在的应用程序包已经改变,包括包名
ACTION_PACKAGE_REMOVED 一个已存在的应用程序包已经从设备上移除,包括包名(正在被安装的包程序不能接收到这个广播)
ACTION_PACKAGE_RESTARTED 用户重新开始一个包,包的所有进程将被杀死,所有与其联系的运行时间状态应该被移除,包括包名(重新开始包程序不能接收到这个广播)
ACTION_PACKAGE_DATA_CLEARED 用户已经清楚一个包的数据,包括包名(清除包程序不能接收到这个广播)

代码实现 
AndroidManifest.xml 中定义广播

?
1
2
3
4
5
6
7
8
<receiver android:name= ".AppInstallReceiver"  android:label= "@string/app_name" >
             <intent-filter>
                  
                 
                 
                 <data android:scheme= "package" >
             </data></action></action></action></intent-filter>
         </receiver>
然后是接收端:
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public  class  AppInstallReceiver  extends  BroadcastReceiver {
     @Override
     public  void  onReceive(Context context, Intent intent) {
         PackageManager manager = context.getPackageManager();
         if  (intent.getAction().equals(Intent.ACTION_PACKAGE_ADDED)) {
             String packageName = intent.getData().getSchemeSpecificPart();
             Toast.makeText(context,  "安装成功" +packageName, Toast.LENGTH_LONG).show();
         }
         if  (intent.getAction().equals(Intent.ACTION_PACKAGE_REMOVED)) {
             String packageName = intent.getData().getSchemeSpecificPart();
             Toast.makeText(context,  "卸载成功" +packageName, Toast.LENGTH_LONG).show();
         }
         if  (intent.getAction().equals(Intent.ACTION_PACKAGE_REPLACED)) {
             String packageName = intent.getData().getSchemeSpecificPart();
             Toast.makeText(context,  "替换成功" +packageName, Toast.LENGTH_LONG).show();
?
1
2
3
4
5
<span style= "white-space:pre" >      </span>doanloadApk.delete(); //从SD中删除刚刚下载的APK文件
         }
 
     }
}

好。APK自动升级就说道这里。


有时间,给大家说一下 模块的静默升级 的实现。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值