安卓應(yīng)用實(shí)現(xiàn)自動(dòng)更新比較簡(jiǎn)單,這里跟大家介紹下。
1. web接口
需要提供一個(gè)接口供客戶端查詢更新狀態(tài),并且在需要更新時(shí),告知客戶端新APK地址。
接口參數(shù)如下:
package 包名,因?yàn)橛袝r(shí)候會(huì)出現(xiàn)同一個(gè)應(yīng)用換包名打包的情況
version 版本號(hào),即android清單文件里面的versionCode
channel 渠道號(hào)
os 操作系統(tǒng),android/ios。ios 這里僅作預(yù)留。
之所以傳入這些字段,是要在與服務(wù)器端的包匹配時(shí),務(wù)必滿足:
package, channel, os 相等,并且服務(wù)器端的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. 數(shù)據(jù)庫(kù)設(shè)計(jì)
由于web端使用的是django,所以可以很方便的給出運(yùn)營(yíng)同學(xué)可以操作的后臺(tái)界面,如下:
注意紅框內(nèi)的元素,運(yùn)營(yíng)同學(xué)在上傳時(shí),是不允許修改的,而是由程序自動(dòng)解析APK文件得到后填入的。
具體的解析方法,我們稍后給出。
而對(duì)應(yīng)的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"版本號(hào)", blank=True, default=0, null=True)
channel = models.CharField(u"渠道", max_length=128, blank=True, default='')
status = models.IntegerField(u'更新狀態(tài)', default=config.PACKAGE_STATUS_NOT_UPDATE,
choices=config.PACKAGE_UPDATE_STATUS)
info = models.TextField(u'通知信息', blank=True, null=True)
os = models.CharField(u'操作系統(tǒng)', 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):
# 文件上傳成功后,文件名會(huì)加上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')
# 執(zhí)行
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
當(dāng)然,正如大家所看到的,我們需要依賴于 apktool.jar 這個(gè)文件,具體大家可以在網(wǎng)上下載。
電腦的性能和穩(wěn)定性在很大程度上依賴于其基本輸入輸出系統(tǒng)(......
閱讀很多使用win10系統(tǒng)的小伙伴電腦遇到了一個(gè)問題,就開機(jī)黑屏了......
閱讀顯示器顯示無信號(hào)的問題在電腦使用過程中并不罕見,這類情況......
閱讀許多用戶購(gòu)買完顯卡之后最為關(guān)心的就是售后服務(wù)了,因此許多......
閱讀idm下載器為大家提供了非常強(qiáng)大的操作功能,其中可以在idm下載......
閱讀安卓6.0怎么看電池用量 AndroidM每毫安電量查看方法 Android手機(jī)是如何耗電的?雖然我們可以查看總App耗電情況,卻無法獲知具體是如何耗電的。在最新安卓6.0第三預(yù)覽版中,Google加入了應(yīng)...
次閱讀
在vivo X5Max場(chǎng)景桌面中點(diǎn)擊物理【任務(wù)鍵】,選擇【經(jīng)典桌面】即可退出。(如下圖) 注 :更多精彩教程請(qǐng)關(guān)注 手機(jī)教程 欄目,手機(jī)數(shù)碼群:296605639歡迎你的加入...
次閱讀
1)打開三星S6的相機(jī),點(diǎn)擊【模式】。(如下圖) 2)進(jìn)入模式界面后,點(diǎn)擊【間隔拍照】。(如下圖) 3)點(diǎn)擊【照相機(jī)】按鈕,設(shè)備會(huì)以2秒為間隔拍攝4張照片。(如下圖) 4)拍攝完成后,設(shè)備會(huì)...
次閱讀
努比亞z17高配和低配的區(qū)別是什么?努比亞z17正式發(fā)布了,分為高配和低配版,下文介紹努比亞z17標(biāo)配和高配版對(duì)比,一起和小樂哥來了解下吧!...
次閱讀
1)打開vivo X5Max手機(jī)【設(shè)置】,點(diǎn)擊【智能體感】,點(diǎn)擊【Smart wake】。(如下圖) 1 / 2 1 2 下一頁 尾頁...
次閱讀
聯(lián)通美卡多少錢?大家是不是也想知道這個(gè)新套餐呢?那么聯(lián)通大小美卡套餐資費(fèi)是怎么算呢?下面綠茶小豆子為詳細(xì)介紹。...
次閱讀
有時(shí)候,你發(fā)現(xiàn)通知欄有一條消息,然后就去點(diǎn)擊它,那條通知消息竟然自動(dòng)變成軟件下載了,而且連停止按鈕都沒有,根本停不下來。還有一些App在桌面都不生成圖標(biāo),直接在后臺(tái)偽...
次閱讀
Comet是加州一家名為CometCore的公司所研發(fā)的一款防水手機(jī),而作為一款防水手機(jī),Comet有一個(gè)最大的亮點(diǎn),那就是它即使掉進(jìn)水里了也不會(huì)下沉,而是會(huì)浮在水面上,因此,手機(jī)的主人不...
次閱讀
安卓5.0系統(tǒng)怎么樣?相信很多用戶對(duì)于安卓5.0系統(tǒng)怎么樣還不太清楚,下面小編來跟大家分享一下android5.0系統(tǒng)使用評(píng)測(cè),感興趣的可以過來看一下。 在全新的Android 5.0中,一款新的系統(tǒng)...
次閱讀
華為路由A1暢享版多少錢?今天華為發(fā)布了兩款路由器,華為路由A1暢享版是其中之一,那么華為路由A1暢享版配置怎么樣呢?下面綠茶小豆子為大家詳細(xì)介紹。...
次閱讀
在今天的安卓手機(jī)使用教程中,小編將給大家分享的是安卓手機(jī)運(yùn)行Ping命令進(jìn)行手機(jī)測(cè)試的方法??赡芎芏嗑W(wǎng)友都不熟悉ping命令,下面,就一起來看看ping命令在安卓手機(jī)中的神奇作用...
次閱讀
樓主,你好。這些有些應(yīng)用是不支持的。具體做法,請(qǐng)參考下文: 1)打開你要浮窗的應(yīng)用,沿對(duì)角線方向拖動(dòng)屏幕的左上角或右上角。(如下圖) 2)點(diǎn)擊小白點(diǎn)。(如下圖) 3)點(diǎn)擊【浮窗】按...
次閱讀
顯示tim移動(dòng)在線是手機(jī)上使用了TIM版本的QQ登錄的賬號(hào),所以會(huì)顯示TIM在線。im是騰訊最新發(fā)布的一款輕量型QQ,主要是用來辦公使用的。...
次閱讀
華為平板m3青春版怎么樣?大家是不是也想知道這款新平板性能如何呢?那么下面綠茶小豆子為大家?guī)砣A為平板m3青春版評(píng)測(cè)!...
次閱讀
Android L是谷歌今年交出的答卷之一,除了采用新的設(shè)計(jì)語言,還橫跨Android Wear、TV等多個(gè)平臺(tái),并收緊了部分平臺(tái)的界面定制權(quán)限,可以了解到谷歌在移動(dòng)平臺(tái)上的一些戰(zhàn)略變化。當(dāng)然...
次閱讀