add meta-data support, external android libraries support, and custom java files to include in the APK.

This commit is contained in:
Mathieu Virbel 2013-11-02 18:04:28 +01:00
parent 4730dd3f0a
commit 5a720e24c9
3 changed files with 102 additions and 4 deletions

View file

@ -90,7 +90,9 @@ class Buildozer(object):
self.build_id = None self.build_id = None
self.config_profile = '' self.config_profile = ''
self.config = SafeConfigParser(allow_no_value=True) self.config = SafeConfigParser(allow_no_value=True)
self.config.optionxform = lambda value: value
self.config.getlist = self._get_config_list self.config.getlist = self._get_config_list
self.config.getlistvalues = self._get_config_list_values
self.config.getdefault = self._get_config_default self.config.getdefault = self._get_config_default
self.config.getbooldefault = self._get_config_bool self.config.getbooldefault = self._get_config_bool
@ -473,6 +475,19 @@ class Buildozer(object):
raise Exception('Unhandled extraction for type {0}'.format(archive)) raise Exception('Unhandled extraction for type {0}'.format(archive))
def file_copytree(self, src, dest):
print 'copy {} to {}'.format(src, dest)
if os.path.isdir(src):
if not os.path.isdir(dest):
os.makedirs(dest)
files = os.listdir(src)
for f in files:
self.file_copytree(
os.path.join(src, f),
os.path.join(dest, f))
else:
copyfile(src, dest)
def clean_platform(self): def clean_platform(self):
self.info('Clean the platform build directory') self.info('Clean the platform build directory')
if not exists(self.platform_dir): if not exists(self.platform_dir):
@ -891,8 +906,11 @@ class Buildozer(object):
def _get_config_list_values(self, *args, **kwargs):
kwargs['with_values'] = True
return self._get_config_list(*args, **kwargs)
def _get_config_list(self, section, token, default=None): def _get_config_list(self, section, token, default=None, with_values=False):
# monkey-patch method for ConfigParser # monkey-patch method for ConfigParser
# get a key as a list of string, seperated from the comma # get a key as a list of string, seperated from the comma
@ -900,6 +918,10 @@ class Buildozer(object):
l_section = '{}:{}'.format(section, token) l_section = '{}:{}'.format(section, token)
if self.config.has_section(l_section): if self.config.has_section(l_section):
values = self.config.options(l_section) values = self.config.options(l_section)
if with_values:
return ['{}={}'.format(key, self.config.get(l_section, key)) for
key in values]
else:
return [x.strip() for x in values] return [x.strip() for x in values]
values = self.config.getdefault(section, token, '') values = self.config.getdefault(section, token, '')

View file

@ -84,6 +84,10 @@ fullscreen = 1
# OUYA-ODK/libs/*.jar # OUYA-ODK/libs/*.jar
#android.add_jars = foo.jar,bar.jar,path/to/more/*.jar #android.add_jars = foo.jar,bar.jar,path/to/more/*.jar
# (list) List of Java files to add to the android project (can be java or a
# directory containing the files)
#android.add_src =
# (str) python-for-android branch to use, if not master, useful to try # (str) python-for-android branch to use, if not master, useful to try
# not yet merged features. # not yet merged features.
#android.branch = master #android.branch = master
@ -105,6 +109,13 @@ fullscreen = 1
# Don't forget to add the WAKE_LOCK permission if you set this to True # Don't forget to add the WAKE_LOCK permission if you set this to True
#android.wakelock = False #android.wakelock = False
# (list) Android application meta-data to set (key=value format)
#android.meta_data =
# (list) Android library project to add (will be added in the
# project.properties automatically.)
#android.library_references =
# #
# iOS specific # iOS specific
# #

View file

@ -22,7 +22,7 @@ from sys import platform, executable
from buildozer import BuildozerException from buildozer import BuildozerException
from buildozer.target import Target from buildozer.target import Target
from os import environ from os import environ
from os.path import join, realpath, expanduser, basename from os.path import join, realpath, expanduser, basename, relpath
from shutil import copyfile from shutil import copyfile
from glob import glob from glob import glob
@ -401,6 +401,13 @@ class TargetAndroid(Target):
'Failed to find libs_armeabi files: {}'.format( 'Failed to find libs_armeabi files: {}'.format(
pattern)) pattern))
# update the project.properties libraries references
self._update_libraries_references(dist_dir)
# add src files
self._add_java_src(dist_dir)
# build the app
build_cmd = ( build_cmd = (
'{python} build.py --name {name}' '{python} build.py --name {name}'
' --version {version}' ' --version {version}'
@ -425,12 +432,18 @@ class TargetAndroid(Target):
'android.permissions', []) 'android.permissions', [])
for permission in permissions: for permission in permissions:
# force the latest component to be uppercase # force the latest component to be uppercase
print 'initial permission is', permission
permission = permission.split('.') permission = permission.split('.')
permission[-1] = permission[-1].upper() permission[-1] = permission[-1].upper()
permission = '.'.join(permission) permission = '.'.join(permission)
build_cmd += ' --permission {}'.format(permission) build_cmd += ' --permission {}'.format(permission)
# meta-data
meta_datas = config.getlistvalues('app', 'android.meta_data', [])
for meta in meta_datas:
key, value = meta.split('=', 1)
meta = '{}={}'.format(key.strip(), value.strip())
build_cmd += ' --meta-data "{}"'.format(meta)
# add extra Java jar files # add extra Java jar files
add_jars = config.getlist('app', 'android.add_jars', []) add_jars = config.getlist('app', 'android.add_jars', [])
for pattern in add_jars: for pattern in add_jars:
@ -512,6 +525,58 @@ class TargetAndroid(Target):
self.buildozer.state['android:latestapk'] = apk self.buildozer.state['android:latestapk'] = apk
self.buildozer.state['android:latestmode'] = self.build_mode self.buildozer.state['android:latestmode'] = self.build_mode
def _update_libraries_references(self, dist_dir):
# ensure the project.properties exist
project_fn = join(dist_dir, 'project.properties')
if not self.buildozer.file_exists(project_fn):
content = ['target=android-{}\n'.format(self.android_api)]
else:
with open(project_fn) as fd:
content = fd.readlines()
# extract library reference
references = []
for line in content[:]:
if not line.startswith('android.library.reference.'):
continue
content.remove(line)
# convert our references to relative path
app_references = self.buildozer.config.getlist(
'app', 'android.library_references', [])
source_dir = realpath(self.buildozer.config.getdefault('app', 'source.dir', '.'))
for cref in app_references:
# get the full path of the current reference
ref = realpath(join(source_dir, cref))
if not self.buildozer.file_exists(ref):
self.buildozer.error('Invalid library reference (path not found): {}'.format(cref))
exit(1)
# get a relative path from the project file
ref = relpath(ref, dist_dir)
# ensure the reference exists
references.append(ref)
# recreate the project.properties
with open(project_fn, 'wb') as fd:
for line in content:
fd.write(line)
for index, ref in enumerate(references):
fd.write('android.library.reference.{}={}\n'.format(
index + 1, ref))
self.buildozer.debug('project.properties updated')
def _add_java_src(self, dist_dir):
print '_add_java_src()'
java_src = self.buildozer.config.getlist('app', 'android.add_src', [])
src_dir = join(dist_dir, 'src')
for pattern in java_src:
for fn in glob(expanduser(pattern.strip())):
print 'match file', fn
last_component = basename(fn)
self.buildozer.file_copytree(fn, join(src_dir, last_component))
@property @property
def serials(self): def serials(self):
if hasattr(self, '_serials'): if hasattr(self, '_serials'):