| 一般的实现安卓应用都会提供自动更新的功能
,让用户方便使用最新的安卓案版本,现在我们来讲讲如何实现安卓应用自动更新的动更功能实例方案 ,方便大家学习
。新功 安卓应用实现自动更新比较简单,例方这里跟大家介绍下 。源码下载实现 1. web接口 需要提供一个接口供客户端查询更新状态 ,安卓案并且在需要更新时 ,动更告知客户端新APK地址。新功 接口参数如下: package 包名 ,例方因为有时候会出现同一个应用换包名打包的实现情况 version 版本号,即android清单文件里面的安卓案versionCode channel 渠道号 os 操作系统,android/ios 。香港云服务器动更ios 这里仅作预留 。新功 之所以传入这些字段 ,例方是要在与服务器端的包匹配时,务必满足: package, channel, os 相等,并且服务器端的version 大于 客户端传入的version 代码如下: os = request.GET.get(os) pkg_name = request.GET.get(package) channel = request.GET.get(channel) version = request.GET.get(version) if not os or not pkg_name or not channel or not version: return jsonify(**ret_dict) pkg = Package.objects.filter( os=os, package=pkg_name, channel=channel, status__gt=config.PACKAGE_STATUS_NOT_UPDATE ).order_by(-version).first if pkg and int(version) pkg.version: ret_dict[pkg_status] = str(pkg.status) ret_dict[pkg_url] = config.WEB_HOST + pkg.file.url ret_dict[update_prompt] = pkg.info return jsonify(**ret_dict) 2. 数据库设计 由于web端使用的免费模板是django,所以可以很方便的给出运营同学可以操作的后台界面 ,如下: ![]() 注意红框内的元素,运营同学在上传时 ,是服务器租用不允许修改的 ,而是由程序自动解析APK文件得到后填入的。 具体的解析方法 ,我们稍后给出 。 而对应的源码库models代码如下: class Package(models.Model): file = models.FileField(u文件, upload_to=config.PACKAGE_UPLOAD_PATH) package = models.CharField(u包名, max_length=255, blank=True, default=) version = models.IntegerField(u"版本号", blank=True, default=0, null=True) channel = models.CharField(u"渠道", max_length=128, blank=True, default=) status = models.IntegerField(u更新状态, default=config.PACKAGE_STATUS_NOT_UPDATE, choices=config.PACKAGE_UPDATE_STATUS) info = models.TextField(u通知信息, blank=True, null=True) os = models.CharField(u操作系统, max_length=64, default=config.PACKAGE_CLIENT_UNKNOW, choices=config.PACKAGE_CLIENT_OS, blank=True, null=True) def __unicode__(self): _,name = os.path.split(self.file.name) return name class Meta: unique_together = (package, version, channel, os) def save(self, * args, ** kwargs): # 文件上传成功后,文件名会加上PACKAGE_UPLOAD_PATH路径 path,_ = os.path.split(self.file.name) if not path: if self.file.name.endswith(.apk): self.os = config.PACKAGE_CLIENT_ANDROID path = os.path.join(/tmp, uuid.uuid4.hex + self.file.name) # logger.error(path: %s, path) with open(path, wb+) as destination: for chunk in self.file.chunks: destination.write(chunk) info = parse_apk_info(path) os.remove(path) self.package = info.get(package, ) self.version = info.get(version, 0) self.channel = info.get(channel, ) elif self.file.name.endswith(ipa): self.os = config.PACKAGE_CLIENT_IOS super(self.__class__, self).save(*args, ** kwargs) def display_filename(self): _,name = os.path.split(self.file.name) return name display_filename.short_description = u"文件" 3. APK文件解析 def parse_apk_info(apk_path, tmp_dir=/tmp): """ 获取包名 、版本、渠道: { version: 17, channel: CN_MAIN, package: ‘com.fff.xxx} :param apk_path: :return: """ from bs4 import BeautifulSoup import os import shutil import uuid abs_apk_path = os.path.abspath(apk_path) dst_dir = os.path.join(tmp_dir, uuid.uuid4.hex) jar_path = os.path.abspath(os.path.join(os.path.dirname(__file__), apktool.jar)) cmd = java -jar %s d %s %s % (jar_path, abs_apk_path, dst_dir) if isinstance(cmd, unicode): cmd = cmd.encode(utf8) # 执行 os.system(cmd) manifest_path = os.path.join(dst_dir, AndroidManifest.xml) result = dict with open(manifest_path, r) as f: soup = BeautifulSoup(f.read) result.update( version=soup.manifest.attrs.get(android:versioncode), package=soup.manifest.attrs.get(package), ) channel_soup = soup.find(meta-data, attrs={ android:name: UMENG_CHANNEL}) if channel_soup: result[channel] = channel_soup.attrs[android:value] shutil.rmtree(dst_dir) return result 当然,正如大家所看到的,我们需要依赖于 apktool.jar 这个文件 ,具体大家可以在网上下载。 亿华云 |
揭秘苹果耳机6s音质的绝佳表现(聆听细节世界,感受耳边的音乐奇迹)金立S5(金立S5的游戏性能如何?一起来看看吧!)温莎资本(揭秘温莎资本的成功秘诀与发展战略)X270在双核CPU中的性能表现(探索X270在双核CPU中的优势和应用场景)从Win10升级到Win7(如何将笔记本电脑系统由Win10改为Win7)探索SonyVaioVPCEA28EC的功能与性能(一款值得关注的笔记本电脑选择)iPhone7防抖技术(探索iPhone7防抖技术的出色表现和关键特性)小辣椒JDPlus全方位解读,值得购买吗?(便宜好用的小辣椒JDPlus手机,性价比之王!)SKG抽油烟机质量评测(全面分析SKG抽油烟机的性能与可靠性)揭开华强北高仿苹果7的真相(高仿苹果7是否值得购买?一探真伪背后的故事)b2b信息平台源码库企业服务器香港物理机网站建设亿华云云服务器