安卓應(yīng)用實現(xiàn)自動更新比較簡單,這里跟大家介紹下。
1. web接口
需要提供一個接口供客戶端查詢更新狀態(tài),并且在需要更新時,告知客戶端新APK地址。
接口參數(shù)如下:
package 包名,因為有時候會出現(xiàn)同一個應(yīng)用換包名打包的情況
version 版本號,即android清單文件里面的versionCode
channel 渠道號
os 操作系統(tǒng),android/ios。ios 這里僅作預(yù)留。
之所以傳入這些字段,是要在與服務(wù)器端的包匹配時,務(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ù)庫設(shè)計
由于web端使用的是django,所以可以很方便的給出運營同學(xué)可以操作的后臺界面,如下:
注意紅框內(nèi)的元素,運營同學(xué)在上傳時,是不允許修改的,而是由程序自動解析APK文件得到后填入的。
具體的解析方法,我們稍后給出。
而對應(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"版本號", 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):
# 文件上傳成功后,文件名會加上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
當然,正如大家所看到的,我們需要依賴于 apktool.jar 這個文件,具體大家可以在網(wǎng)上下載。
找到桌面上的設(shè)置按鈕或下滑通知欄右上方的設(shè)置按鈕。進入設(shè)......
閱讀soul的聊天記錄刪除后是無法恢復(fù)的,由于soul的聊天記錄都會保......
閱讀花唄收款二維碼可以商家服務(wù)頁面選項中找到,但是先需要開通......
閱讀微信刪除的賬單是不可以恢復(fù)的,當刪除賬單的時候,會提示刪......
閱讀顯示tim移動在線是手機上使用了TIM版本的QQ登錄的賬號,所以會......
閱讀安卓6.0彩蛋是什么?安卓6.0彩蛋怎么獲得?谷歌在每一代安卓系統(tǒng)里面都會隱藏一個小彩蛋,呼出方式就是在狂點幾下系統(tǒng)版本號,然后就會出現(xiàn)一代號形象為主題的畫面。而這次的安卓...
次閱讀
安卓5.0什么時候推送?大家可以通過下文來了解android安卓5.0推送時間的消息,安卓Android5.0將在什么時候能夠推送到手機上呢?大家可以通過下文來了解詳細內(nèi)容哦。 雖然Android 5.0要花較長...
次閱讀
安卓手機如何查看已連接的Wifi密碼?...
次閱讀
首先我們需要下載騰訊手機管家并安裝到手機上。 安裝好騰訊手機管家后,我們打開騰訊手機管家并選擇隱私保護。 在隱私保護中我們可以看到立即開啟,點選此按鈕。 然后就是設(shè)置...
次閱讀
1)1、進入三星S5的【設(shè)定】,點擊【通話】;(如下圖) 2)勾選【通話通知彈出窗口】后有來電就會以懸浮窗口的形式顯示了;(如下圖) 3)點擊懸浮窗口右上角的【放大標志】可以恢復(fù)正常的...
次閱讀
1)打開【手機支付寶】,進入首頁點擊左上角的【頭像】進入個人資料。(如下圖) 2)點擊【設(shè)置】一項,跳轉(zhuǎn)后再選擇【隱私】。(如下圖) 3)點擊【不讓他(她)看我的真實姓名】,接著點...
次閱讀
支付寶境外流量包好用嗎?可能很多用戶對于支付寶中的境外流量包還不清楚,那么支付寶境外流量包在香港好用嗎?下文小樂哥給大家介紹一下!...
次閱讀
1)為了不使流量白白浪費,我們先拉下下拉菜單,點擊相關(guān)按鍵,關(guān)閉數(shù)據(jù)連接。 2)接著我們在提示下載的通知位置長按,如圖,出現(xiàn)【應(yīng)用程序信息】按鍵點擊。 3)點擊【應(yīng)用程序信...
次閱讀
1)進入設(shè)置界面點擊【手勢體感】,再點擊【亮屏手勢】。(如下圖) 2)在亮屏手勢界面開啟【三指截屏】右邊開關(guān)即可。(如下圖)...
次閱讀
大量Android 5.0用戶稱自己設(shè)備的耗電速度過快。原版Lollipop當中的確存在Wi-Fi引發(fā)的耗電問題,但谷歌已經(jīng)在Android 5.0.1當中進行了修復(fù)。Android 5.0本該提升設(shè)備的續(xù)航,因此如果你的設(shè)備...
次閱讀
1)首先,進入手機設(shè)置,然后在設(shè)置菜單里找到并點擊進入日期與時間。 2)在這里,你可以看見自動確定日期和時間和自動確定市區(qū),把這兩個選項都打上勾,以后系統(tǒng)在有網(wǎng)的情況下...
次閱讀
問: 安卓手機 充電很慢怎么辦? 答:首先要檢查的就是數(shù)據(jù)線的問題,有些數(shù)據(jù)線用的久了接口會出現(xiàn)問題,安卓系統(tǒng)手機的數(shù)據(jù)線基本都是通用的,換一根其他的數(shù)據(jù)線試試,如果不...
次閱讀
1)進入三星A7的相機界面,點擊【模式】,選擇【動畫GIF】。(如下圖) 2)點擊【確定】,長按【拍攝按鈕】。(如下圖) 3)連續(xù)拍攝20張照片,拍完后查看效果,滿意就點擊右上角【保存】即...
次閱讀
首先下載第三方的recovery,如果你已經(jīng)刷入可以忽略。 然后放到c:/adb目錄中,如果沒有需要自己建立 下載Supersu 2.0,然后將下載的Supersu 2.0文件放入到Nexus5根目錄中 刷入recovery,將手機...
次閱讀
中國移動和手機多少錢?中國移動和品牌新款手機亮相工信部,型號為M823,還不知道該機售價的朋友,可以來看看中國移動和手機價格介紹了解下! 中國移動和手機配有5.5英寸屏幕;分辨...
次閱讀