检测APK版本有更新,手动升级安装

直接上代码了,此处不难理解。有什么问题可以留言。


从服务器获取xml解析并进行比对版本号

class CheckVersionTask implements Runnable{ 
        public void run() {  
            try {  
                //从资源文件获取服务器 地址   
                String update_url = ServerBiz.getServer(HomeActivity.this, "update_url");
                //包装成url的对象   
                URL url = new URL(update_url);  
                HttpURLConnection conn =  (HttpURLConnection) url.openConnection();   (此处报错,输出conn.getResponseCode()看看!)
                conn.setConnectTimeout(5000);  
                InputStream is =conn.getInputStream();   
                
                //获得更新文件的信息
                UpdateInfo info =  DownLoadManager.getUpdateInfo(is); 
                if(info.getVersion().equals(getVersionName())){  
                    Log.i("liyongjun","版本号相同无需升级");  
                }else{  
                    Log.i("liyongjun","版本号不同 ,提示用户升级 ");  
                    Intent intent = new Intent("com.ccfrom.cclive.ACTION.ApkUpdate");
                    intent.putExtra("updatemsg", info.getDescription());
                    intent.putExtra("filepath",info.getUrl());
                    sendBroadcast(intent);
                }  
            } catch (Exception e) {  
                // 待处理   
                Message msg = new Message();  
                msg.what = GET_UNDATAINFO_ERROR;  
                handler.sendMessage(msg);  
                e.printStackTrace();  
            }   
        }  
    }  

获取package的版本号,配置在manifest中的

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

注册此接收器:

class ApkUpdateReciver extends BroadcastReceiver {
        public void onReceive(Context paramContext, Intent paramIntent) {
            String str1 = paramIntent.getAction();
            if (str1.equals("com.ccfrom.cclive.ACTION.ApkUpdate")) {
                String updatemsg = paramIntent.getStringExtra("updatemsg");
                String filepath = paramIntent.getStringExtra("filepath");
                HomeActivity.this.createUpdateDialog(updatemsg, filepath).show();
                HomeActivity.this.removeStickyBroadcast(paramIntent);
            }
        }
    }

创建提示框,是否更新版本

public AlertDialog createUpdateDialog(String updatemsg, final String filepath) {
         AlertDialog.Builder builer = new Builder(this) ;  
            builer.setTitle("版本升级"); 
            builer.setMessage(updatemsg); 
            builer.setPositiveButton("确定", new OnClickListener() { 
                public void onClick(DialogInterface dialog, int which) { 
                        downLoadApk(filepath); 
                    }    
                }); 
                builer.setNegativeButton("取消", new OnClickListener() { 
                    public void onClick(DialogInterface dialog, int which) { 
                        Log.e("HomeActivity", "Enter Main..");
                    } 
                }); 
               
        return builer.create();
    }

从服务器中下载apk

 protected void downLoadApk(final String filePath) { 
        pd = new  ProgressDialog(this); 
        pd.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL); 
        pd.setMessage("正在下载更新"); 
        pd.show(); 
        new Thread(){ 
            @Override 
            public void run() { 
                try { 
                    File file = DownLoadManager.getFileFromServer(filePath, pd); 
                    sleep(3000);                     
                    installApk(file); 
                    pd.dismiss(); //结束掉进度条对话框 
                } catch (Exception e) { 
                    e.printStackTrace(); 
                    Message msg = new Message(); 
                    msg.what = DOWN_ERROR; 
                    handler.sendMessage(msg); 
                } 
            }}.start(); 
    }  

安装已下载的apk,并结束当前应用

 protected void installApk(File file) { 
        Intent intent = new Intent(); 
        //执行动作 
        intent.setAction(Intent.ACTION_VIEW); 
        //执行的数据类型 
        intent.setDataAndType(Uri.fromFile(file), "application/vnd.android.package-archive"); 
        startActivity(intent); 
    }  

以下贴上前面需要使用到的类方法:

ServerBiz.java

private static ServerInfo parserServerXml(String paramString) {
        ServerInfo mServerInfo = null;
        if (paramString != null) {
            mServerInfo = new ServerInfo();
            try {
                DocumentBuilderFactory domfac = DocumentBuilderFactory
                        .newInstance();
                DocumentBuilder dombuilder = domfac.newDocumentBuilder();
                Document doc;
                Element root;
                NodeList maps;
                URL url = new URL(paramString);
                doc = dombuilder.parse(url.openStream());
                root = doc.getDocumentElement();
                maps = root.getChildNodes();

                for (Node node = maps.item(1).getFirstChild(); node != null; node = node
                        .getNextSibling()) {
                    if (node.getNodeType() == Node.ELEMENT_NODE) {
                        Log.e("liyongjun","name = " + node.getNodeName());
                        if (node.getNodeName().equals("hosturl"))
                            mServerInfo.hosturl = node.getTextContent();
                        else if (node.getNodeName().equals("liveurl"))
                            mServerInfo.liveurl = node.getTextContent();
                        else if (node.getNodeName().equals("mv_url"))
                            mServerInfo.mv_url = node.getTextContent();
                        else if (node.getNodeName().equals("news_url"))
                            mServerInfo.news_url = node.getTextContent();
                        else if (node.getNodeName().equals("playurl"))
                            mServerInfo.playurl = node.getTextContent();
                        else if (node.getNodeName().equals("tvback_url"))
                            mServerInfo.tvback_url = node.getTextContent();
                        else if (node.getNodeName().equals("tvepg_url"))
                            mServerInfo.tvepg_url = node.getTextContent();
                        else if (node.getNodeName().equals("update_url"))
                            mServerInfo.update_url = node.getTextContent();
                       
                    }
                }

            } catch (Exception e) {

                e.printStackTrace();
            }

        }
        return mServerInfo;
    }

   private static void saveServerInfo(Context paramContext,
            ServerInfo paramServerInfo) {
        SharedPreferences.Editor localEditor = paramContext
                .getSharedPreferences("server_preferences",
                        paramContext.MODE_PRIVATE).edit();
        localEditor.putString("hosturl", paramServerInfo.hosturl);
        localEditor.putString("liveurl", paramServerInfo.liveurl);
        localEditor.putString("mv_url", paramServerInfo.mv_url);
        localEditor.putString("news_url", paramServerInfo.news_url);
        localEditor.putString("playurl", paramServerInfo.playurl);
        localEditor.putString("tvback_url", paramServerInfo.tvback_url);
        localEditor.putString("tvepg_url", paramServerInfo.tvepg_url);
        localEditor.putString("update_url", paramServerInfo.update_url);
        localEditor.commit();
    }

    public static String getServer(Context paramContext, String paramString) {
        return paramContext.getSharedPreferences("server_preferences",
                paramContext.MODE_PRIVATE).getString(paramString, null);
    }

UpdateInfo.java

    private String version; 
    private String url; 
    private String description;
   
    public String getVersion() {
        return version;
    }
    public void setVersion(String version) {
        this.version = version;
    }
    public String getUrl() {
        return url;
    }
    public void setUrl(String url) {
        this.url = url;
    }
    public String getDescription() {
        return description;
    }
    public void setDescription(String description) {
        this.description = description;
    }  

update.xml 此文件放于服务器指定位置,用来比较当前版本的版本号

<?xml version="1.0" encoding="utf-8"?>
<info> 
    <version>2.0</version> 
    <url>http://ccfrom.qtcms.cn/files/CcLive.apk</url> 
    <description>检测到最新版本,请及时更新!</description> 
</info>



框架内部支持中/英文(其他语言只需要在对应的string.xml中取相同的名字即可)内部对话框背景图片、按钮支持自定义了查看版本中的Log只需要过滤AppUpdate开头的Tag重点: 如果没有设置downloadPath则默认为getExternalCacheDir()目录,同时不会申请[存储]权限!目录编译问题效果图功能介绍DownloadManagerUpdateConfiguration使用步骤Demo下载体验版本更新记录结语编译问题因为适配了Android O的通知栏,所以依赖的v7包版本比较高appcompat-v7:26.1.0使用的gradle版本为gradle-4.1-all,所以建议使用Android Studio 3.0及以上的版本打开此项目效果图     功能介绍 支持断点下载 支持后台下载 支持自定义下载过程 支持 设备 >= Android M 动态权限的申请 支持通知栏进度条展示(或者自定义显示进度) 支持Android N 支持Android O 支持中/英文双语 支持自定内置对话框的样式 使用HttpURLConnection下载,未集成其他第三方框架更加详细的文档参阅此处《AppUpdate API文档》DownloadManager:配置文档初始化使用DownloadManager.getInstance(this)属性描述默认值是否必须设置context上下文nulltrueapkUrlapk的下载地址nulltrueapkNameapk下载好的名字nulltruedownloadPathapk下载的位置getExternalCacheDir()falseshowNewerToast是否提示用户 "当前已是最新版本"falsefalsesmallIcon通知栏的图标(资源id)-1trueconfiguration这个库的额外配置nullfalseapkVersionCode更新apk的versionCode (如果设置了那么库中将会进行版本判断下面的属性也就需要设置了)1falseapkVersionName更新apk的versionNamenullfalseapkDescription更新描述nullfalseapkSize新版本安装包大小(单位M)nullfalseauthorities兼容Android N uri授权应用包名falseUpdateConfiguration:配置文档属性描述默认值notifyId通知栏消息id1011notificationChannel适配Android O的渠道通知详情查阅源码httpManager设置自己的下载过程nullbreakpointDownload是否需要支持断点下载trueenableLog是否需要日志输出trueonDownloadListener下载过程的回调nulljumpInstallPage下载完成是否自动弹出安装页面trueshowNotification是否显示通知栏进度(后台下载提示)trueforcedUpgrade是否强制升级falseonButtonClickListener按钮点击事件回调nulldialogImage对话框背景图片资源(图片规范参考demo)-1dialogButtonColor对话框按钮的颜色-1dialogButtonTextColor对话框按钮的文字颜色-1所有版本:点击查看使用步骤第一步: app/build.gradle进行依赖implementation 'com.azhon:appupdate:1.7.3'第二步:创建DownloadManager,更多用法请查看这里示例代码DownloadManager manager = DownloadManager.getInstance(this); manager.setApkName("appupdate.apk")         .setApkUrl("https://raw.githubusercontent.com/azhon/AppUpdate/master/apk/appupdate.apk")         .setSmallIcon(R.mipmap.ic_launcher)         //可设置,可不设置         .setConfiguration(configuration)         .download();第三步:兼容Android N 及以上版本,在你应用的Manifest.xml添加如下代码<--! android:authorities="${applicationId}"  这个值必须与DownloadManager中的authorities一致(不设置则为应用包名)--> <provider     android:name="android.support.v4.content.FileProvider"     android:authorities="${applicationId}"     android:exported="false"     android:grantUriPermissions="true">     <meta-data         android:name="android.support.FILE_PROVIDER_PATHS"         android:resource="@xml/file_paths_public" /> </provider>第四步:资源文件res/xml/file_paths_public.xml内容<?xml version="1.0" encoding="utf-8"?> <paths>     <external-path         name="app_update_external"         path="/" />     <external-cache-path         name="app_update_cache"         path="/" /> </paths>兼容Android O及以上版本,需要设置NotificationChannel(通知渠道);库中已经写好可以前往查阅NotificationUtil.java温馨提示:升级对话框中的内容是可以上下滑动的哦!如果需要实现自己一套下载过程,只需要继承BaseHttpDownloadManager 并使用listener更新进度public class MyDownload extends BaseHttpDownloadManager {}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值