An example scheme to realize the Automatic Update function of Android app

Source: Internet
Author: User
Tags uuid

Android applications to achieve Automatic Updates is relatively simple, here with you introduce.

1. Web Interface

An interface needs to be provided for the client to query for update status and to notify the client of a new APK address when an update is required.

The interface parameters are as follows:

Package package name because there are times when the same application package name is packaged
Version number, which is the Versioncode in the Android manifest file
Channel channel number
OS operating system, Android/ios. iOS is reserved here only.



The reason for passing in these fields is to meet the server-side package:

Package, channel, OS equals, and server-side version is larger than the client incoming version

The code is as follows:

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 ').
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. Database Design

Because the web side is using Django, it is easy to give the operation of the students can operate the background interface, as follows:



Note that the elements of the red box, operators in the upload, is not allowed to modify, but by the program automatically parse apk file after filling in.

The specific analytic method, which we will give later.

and the corresponding models code is as follows:

Class Package (models. Model):
FILE = models. Filefield (U ' files ', upload_to=config. Package_upload_path)
Package = models. Charfield (U ' package name ', max_length=255, Blank=true, default= ')
Version = Models. Integerfield (U "version number", Blank=true, Default=0, Null=true)
Channel = models. Charfield (U "Channel", max_length=128, Blank=true, default= ')
Status = Models. Integerfield (U ' update status ', Default=config. Package_status_not_update,
Choices=config. Package_update_status)
info = models. TextField (u ' notification info ', blank=true, Null=true)
OS = models. Charfield (U ' os ', 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):
# After the file is uploaded successfully, the filename will be added to the Package_upload_path 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 "File"

3. apk File Resolution

def parse_apk_info (Apk_path, tmp_dir= '/tmp '):
"""
Get package name, version, channel:
{' Version ': ', ' Channel ': ' Cn_main ', ' package ': ' Com.fff.xxx '}
:p Aram 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%s '% (Jar_path, Abs_apk_path, Dst_dir)

If Isinstance (cmd, Unicode):
cmd = Cmd.encode (' UTF8 ')

# Execute
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

Of course, as you can see, we need to rely on the apktool.jar of this document, which we are able to download online.

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.