I am using Titanium which is a cross-platform development Tool. Titanium uses it own building script to create the apk.
I have a Titanium application that uses a native module : a Java library that makes VOIP calls. The Java application works, and when I create a Titanium application with an empty module, it works.
But I have a build problem using a module based on the VOIP module inside the Titanium application : some Resources are missing in the apk.
First the build system merges some Resources from our Titanium application and some native android modules and put them in a directory build. I have for exemple : build/android/res/values/strings.xml file where all keys and values seems ok and valid xml.
Then the build calls aapt and create the apk using also the Titanium Resources for library widgets (ex: strings for notifications). And in this apk, the build/android/res/values/strings.xml is missing. It doesn't exists. The application starts, the VOIP service starts, and then it's crashes as soon that a required missing Resource is called.
I can prove with aapt list or unzipping the apk that strings.xml is missing.
Looking deep in the titanium javascript build file, I see this command is executed :
aapt "package" "-f" "-m" "-J" "/Users/nicorama/ti-voip/build/android/gen"
"-M" "/Users/nicorama/ti-voip/project/build/android/AndroidManifest.xml"
"-S" "/project/build/android/res"
"-S" "/var/folders/6f/twxz46614h7_q/res"
"-S" "/var/folders/6f/twxz46614h7_q/res" ....
The /var/folders/... are files for Titanium widgets. Compilation of the apk fails if I remove them.
I have executed this command outside the build, adding -v for verbose mode and saving result into a log.txt. I'm searching in this file for strings.xml and I find :
Found 18 custom asset files in /Users/nicorama/ti-voip/build/android/bin/assets
Configurations:
(default)
v11
v14
....
Src: () /var/folders/6f/twxz46614h7_q/res/values/ids.xml
values/strings.xml
Src: () /var/folders/6f/twxz46614h7_q/res/values/strings.xml
Src: (af) /var/folders/6f/twxz46614h7_q/res/values-af/strings.xml
Src: (am) /var/folders/6f/twxz46614h7_q/res/values-am/strings.xml
...
But nothing about my /Users/nicorama/ti-voip/build/android/res/values/strings.xml folder which is first in the appt command.
I do have all references needed for images or other xml files thought :
(new resource id hidden from /Users/nicorama/ti-voip/build/android/res/layout/hidden.xml)
(new resource id launcher from /Users/nicorama/ti-voip/build/android/res/layout/launcher.xml)
Any idea where and why this strings.xml has disappeared ?
aapt will merge all strings.xml "values" into resources.arsc, which is why you do not see the file strings.xml in the apk. I double checked this with few of my apks, i do not see the strings.xml inside the apk.
If you would like to see the string values that were packaged with your 'apk', run the below command it will dump all string values.
aapt.exe d strings myapp.apk
Verify some of the string values you defined in your app, are listed in the above string dump. If not, try passing in absolute path to the "res" folder "/Users/nicorama/ti-voip/project/build/android/res" at the beginning:
aapt "package" "-f" "-m" "-J" "/Users/nicorama/ti-voip/build/android/gen"
"-M" "/Users/nicorama/ti-voip/project/build/android/AndroidManifest.xml"
"-S" "/Users/nicorama/ti-voip/project/build/android/res"
"-S" "/var/folders/6f/twxz46614h7_q/res"
"-S" "/var/folders/6f/twxz46614h7_q/res" ....
the new apk should have the xml values, test again with
aapt.exe d strings myapp.apk
to make sure your strings.xml values are in the above string dump.
Related
We're upgrading to Delphi 11.1 from 10.4.
We have a few scripts which build and deploy Android projects. They assemble an msbuild command that looked like this:
msbuild someproject.dproj /v:q /p:Platform=Android /t:Build;Deploy /p:Config=Release /p:BT_BuildType=AppStore
With 11.1, this throws an error message:
C:\Program Files (x86)\Embarcadero\Studio\22.0\bin\CodeGear.Common.Targets(940,7): error MSB4036: The "XmlPeek" task was not found. Check the following: 1.) The name of the task in the project file is the same as the name of the task class. 2.) The task class is "public" and implements the Microsoft.Build.Framework.ITask interface. 3.) The task is correctly declared with <UsingTask> in the project file, or in the *.tasks files located in the "C:\Windows\Microsoft.NET\Framework\v2.0.50727" directory. [someproject.dproj]
Now, C:\Program Files (x86)\Embarcadero\Studio\22.0\bin\rsvars.bat, which is used by all of our build scripts, explicitly sets the .NET framework as below:
#SET FrameworkDir=C:\Windows\Microsoft.NET\Framework\v4.0.30319
#SET FrameworkVersion=v4.5
After some research, I hit on the idea of adding a toolsversion parameter to the msbuild command as below, and this worked:
msbuild someproject.dproj /v:q /p:Platform=Android /t:Build;Deploy /p:Config=Release /p:BT_BuildType=AppStore /toolsversion:4.0
This is all well and good, but I would prefer not to hard-code the toolsversion number in the script(s).
Is there a way I can programmatically obtain the correct value of the toolsversion that Delphi itself is using when it generates builds, etc.?
I assume that just finding the highest .NET version installed will not suffice (and even then, one has to "translate" that to a toolsversion). It has to marry up with whatever Delphi is doing (e.g., in the CodeGear.Common.Targets file referenced in the original error message).
This is a bug in Delphi 11.1 that has at least 3 bug reports: RSP-37855, RSP-38466, and RSP-38467.
You can add /tv:4.0 to your MSBuild command line, or modify the first line in the .dproj file to:
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="4.0" DefaultTargets="Build">
Assuming that rsvars.bat has been run,
FOR %%v IN ("%frameworkdir%") DO SET "toolsversion=%%~nv"
ECHO msbuild ...blah... /toolsversion:%toolsversion:~1%
The variable frameworkdir will be set by rsvars.bat. The for command parses its value (eg. C:\Windows\Microsoft.NET\Framework\v4.0.30319 as though it is a filename, and picks v4.0 as the "filename" (~n modifier [filename] of the metavariable %%v)
Then use the value assigned to toolsversion, starting at character 1 (where the first character is "character 0")
--- Given more info in comment
FOR %%v IN ("%frameworkdir%") DO ECHO %%~nxv|FINDSTR /R ".*\..*\.">nul&IF ERRORLEVEL 1 (SET "toolsversion=%%~nxv") ELSE SET "toolsversion=%%~nv"
Oh ye of little faith :)
When compiling a cordova application every single file in my /www folder gets copied to the assets/www folder(android) but I'd like to customize what files are copied. I use several pseudo languages like CoffeeScript, Jade or Stylus which are auto-compiled by my IDE and they shouldn't be shipped into the final application.
With the help of this article, I found that you can create/edit the platform/android/ant.properties, and add the following line to it:
aapt.ignore.assets=!*.map:!thumbs.db:!.git:.*:*~
With this line, any file or directory that matches one of these patterns will not be included in the .apk file:
*.map
thumbs.db
.git
.*
*~
I found that editing the platforms/android/build.xml won't work because it's overwritten each time the build is invoked; also, creating a build.xml file in the root of the project didn't work.
The rules for this property are the following, taken from $ANDROID_HOME/tools/ant/build.xml:
<!-- 'aapt.ignore.assets' is the list of file patterns to ignore under /res and /assets.
Default is "!.svn:!.git:.*:<dir>_*:!CVS:!thumbs.db:!picasa.ini:!*.scc:*~"
Overall patterns syntax is:
[!][<dir>|<file>][*suffix-match|prefix-match*|full-match]:more:patterns...
- The first character flag ! avoids printing a warning.
- Pattern can have the flag "<dir>" to match only directories
or "<file>" to match only files. Default is to match both.
- Match is not case-sensitive.
-->
<property name="aapt.ignore.assets" value="" />
Hidden (.*) folder & files will be ignored by default
All hidden files and folders will be ignored while build for example .git/ & .gitignore
To hide : Rename the folder by a . (dot) prepended to the folder/file name.
Use Terminal in Linux/Mac to rename the folder.
mv dev .dev
Use cmd in Windows
ren dev .dev
I do not know any way how to filter files for cordova, but I can describe you approach that we use in our projects.
We are using gruntjs with phonegap plugin. We configure it to use prebuilt folder (which contains only necessary files and folders) and it:
creates cordova/phonegap project
adds plugins,platforms
builds native applicaiton
launches native application on emulator
Main thing in this approach is that cordova/phonegap project (directory with .cordova, platforms and www folders) is just a build artefact.
Here is relevant part of our Gruntfile.js as an example:
phonegap : {
config : {
root : './out/dist',
config : {
template : './config.tpl.xml',
data: {
id: pkg.id,
version: pkg.version,
name: pkg.name,
author : pkg.author
}
},
path : 'out/phonegap',
plugins : [
// PHONEGAP OFFICIAL PLUGINS
'org.apache.cordova.globalization',
'org.apache.cordova.network-information',
'org.apache.cordova.splashscreen',
//THIRD-PARTY PLUGINS
'de.appplant.cordova.plugin.local-notification'
],
platforms : [
'android'
],
maxBuffer : 200, // You may need to raise this for iOS.
verbose : false,
releases : 'out/releases',
releaseName : function() {
return pkg.name + '-v' + pkg.version;
},
// Android-only integer version to increase with each release.
// See http://developer.android.com/tools/publishing/versioning.html
versionCode : function() {
return 1;
}
}
}
Note, out/dist is generated by previous build step and contains concatenated and minified version of code.
I've created a custom script to ignore files/folders which works not just for android:
Add this to your config.xml:
<ignore entries="lang,foo/bar,ignore/asdf.html" />
And you need two more files located in hooks/before_build and hooks/after_build folders.
I highly recommend cordova-plugin-exclude-files. You simply specify files to exclude as pattern attributes of exclude-files tags in your config.xml file.
For example, to exclude all .scss files:
<exclude-files pattern="**/*.scss" />
And to exclude all files with the string "ios-only" on the Android platform only:
<platform name="android">
<exclude-files pattern="ios-only" /> </platform>
This is what I'm doing. I've moved the src files for the app that was in www folder to another folder created in root - web-app. Next, the following script was added in package.json :
This surely needs to be refined, but am working with it as makeshift arrangement.
Good Luck...
I have small problem with displaying cyrillic app name on PlayBook and BB10 simulator. Looks like it's incorrectly encoded from russian.
Problem appeared after updating bb eclipse plugin from version 1.3 to 1.5, with plugin v.1.3 it worked just ok.
I'll appreciate any help or ideas.
Here is screenshot from bb10 simulator:
I found workaround myself.
When I got problems with encodding with bb eclipse plugin, I decided to do the same thing with comandline tools.
After tools setup (sing keys, debug tokens, etc), I've tried to repackage my apk file with this command (source apk file was in apk/ folder and destination for bar file was bar/ folder)
./apk2bar apk/ -d bbplaybookdebugtoken.bar -t bar/ -a "zasadnyy" -cg
When I've got .bar file, I've installed it with command:
/batchbar-deploy bar/ 192.168.1.35 mysecretpass
Unfortunatelly result was unsuccsessful, app name was incorrectly encoded again. After first fail I've read documentation a bit more and tried to use this approach: http://developer.blackberry.com/android/documentation/creating_a_custom_manifest_file_2016828_11.htm...
When I unzipped bar file and opened MANIFEST.MS - I've found this line:
Application-Name: –ì–µ—Ä–æ–∏
According to documentation solution should be quite strainforward:
1. Rename MANIFEST.MS to <you apk name>.mf
2. Update incorrect properties, in my case I've changed line from above to "Application-Name: Герои"
3. Put edited manifest file in the same folder as <your apk name>.apk and rerun apk2bar tool with **-m** parameter, e.g.:
./apk2bar apk/ -d bbplaybookdebugtoken.bar -t bar/ -a "zasadnyy" -m -cg
Repackage, deploy, run and ..... and again FAIL. Application name was "–ì–µ—Ä–æ–∏".
After second fail, I decided to make dirty hack, I've edited MANIFEST.MF directly in repackaged bar file (Unzip -> edit manifest -> zip -> change file extension to .bar).
Deploy updated .bar file to playbook and .... YEAH, we've got cyrilic app name!
Conclusion and FIX:
Looks like in 1.5 release if apk2bar tool manifest encoding is misconfigured (in ver. 1.3 it worked just ok)
In oder to FIX issue: Unzip unsigned bar file -> edit manifest -> zip -> change file extension back to .bar
I had the same problem I believe, but the symptoms have been different. I was not even able to install the app on my test device and explicitly running blackberry-signer -verify confronted me with the Invalid signature file digest for Manifest. error.
The MANIFEST.MF file seems to be properly encoded in utf-8 by the apk2bar tool, but the following signing process seems to read this using the platform's default encoding. I added the following java parameter to the blackberry-signer.bat as well as the apk2bar.bat batch file scripts of the command line tools to make it work properly:
-Dfile-encoding=utf-8
(This is for version 1.5.2 of the tools)
I am trying to port an existing C++ app to android using JNI. However, after generating the Build.xml file from the AndroidManifest.xml and attempting to build with it, I get the following (relevant) output:
[aapt] Generating resource IDs...
[aapt] invalid resource directory name: /{Project Directory}/res/audio
[aapt] invalid resource directory name: /{Project Directory}/res/img
BUILD FAILED
/{Android SDK Dir}/tools/ant/build.xml:560: The following error occurred while executing this line:
/{Android SDK Dir}/tools/ant/build.xml:589: null returned: 1
These are existing directories in a directory already named "res" by coincidence, not meant to have a semantic meaning for Java. If I remove those from res/ then it builds just fine. So my question is-- what is the best way to organize this (or tell ant to ignore unrecognized directories)? Res is already a very large directory structure with mainly .png .mp3 and text files.
If renaming them is out of the question for whatever reason, you could override -package-resources in the build.xml and customize aapt, specifying a new location for res/ along with various other options to handle issues that might come up (Then aapt would be the part to research).
You can inspect android-sdk/tools/ant/build.xml for what that target already does, but essentially you would simply paste in the following to your own build.xml
<target name="-package-resources">
<echo>Packaging resources</echo>
<aapt executable="${aapt}"
command="package"
verbose="${verbose}"
versioncode="${version.code}"
manifest="AndroidManifest.xml"
assets="${asset.absolute.dir}"
androidjar="${android.jar}"
apkfolder="${out.absolute.dir}"
resourcefilename="${resource.package.file.name}"
projectLibrariesResName="${project.libraries.res}"
projectLibrariesPackageName="${project.libraries.package}"
resourcefilter="${aapt.resource.filter}">
<res path="${resource.absolute.dir}"/>
</aapt>
</target>
and customize to your needs.
Also notice that it pulls the res path from resource.absolute.dir, so if thats all you really need to do, then you could set that in ant.properties or whatever the default properties file is in the sdk tools are that you're using. Just inspect the build.xml to see or add a new loadproperties line pointing to your own. IIRC, resource.absolute.dir gets set based on resource.dir, so you might have to try each but in the properties file you would just set
resource.dir=new/path/to/res
audio goes in {Project Directory}/res/raw and images go in {Project Directory}/res/drawable
This page may be of some use to you:
http://developer.android.com/guide/topics/resources/index.html
Hi all
I am trying to develop an android extension for air, but I have a problem with resources.
According to this : Official adobe doc - FREContext
and this Extending AIR by Oliver Goldman
We simply have to add the resources we need in the res file of the Native part, then they are added inside the .ane file and passed to the final apk. In order to access them though we have to use getResourceId( "drawable.background_image" ) instead of R.drawable.background_image
But when I generate my extension, the res file is actually not even included anywhere inside the .ane file and also not inside the final apk. And I have found not a single extension on the net using resources (not even in the adobe samples)
For this test I simply use the basic Hello world Vibrate test, but I added a new png in the drawable folder.
As you can see while unziping the .ane file, then going to META-INF/ANE/Android-ARM
the res file is absent.
As a result, the program crashes when I try to access my resource FREContext.getResourceId("drawable.ppy_accessory_manage.png")
Has anyone managed to make resources work with ANE in android? Is there something I should change in my command line while compiling the ane?
Thanks :-)
PS, here is my batch to compile the ANE :
set adt_directory=C:\Program Files\Adobe\Adobe Flash Builder 4.6\sdks\4.6.0\bin
set root_directory=C:\Users\hugo\Adobe Flash Builder 4.6
set library_directory=%root_directory%\HelloANELibrary
set native_directory=%root_directory%\HelloANENative
set signing_options= -storetype pkcs12 -keystore "C:\Users\hugo\Adobe Flash Builder 4.6\certificat.p12"
set dest_ANE=HelloANE.ane
set extension_XML=%library_directory%\src\extension.xml
set library_SWC=%library_directory%\bin\HelloANELibrary.swc
"%adt_directory%"/adt -package %signing_options% -target ane "%dest_ANE%" "%extension_XML%" -swc "%library_SWC%" -platform Android-ARM -C "%native_directory%" library.swf HelloANENative.jar
You just have to add after "-platform Android-ARM" the following: -C "%native_directory%" res
With your res folder in %native_directory% !
But the best way is to create a %target_native_directory%, put everything you need inside, and use:
-C "%target_native_directory%" .