Is it possible to tell Eclipse to use some extra arguments for aapt (-0 in specific)?
I have been looking for past couple of hours and the best hack I came up with was to create a wrapper for the aapt tool to inject the argument to the command line. The trouble with this approach is that whenever I should lose that wrapper, then I'll be quietly introducing a bug into my application.
I don't think it is possible without some sort of wrapper script as you mention.
Alternatively, you could use an Android ant script to build the release version of your application, as that lets you easily override the command line parameters used. It also helps you build things independently of the Eclipse plugin which is useful should you get into continuous integration.
Hopefully you wouldn't be quietly introducing a bug anyway due to at least smoke testing your app before release.
Thank you Christopher for your answer. Here is the aapt wrapper script I built in python for my purposes in case anyone needs it:
#!/usr/bin/env python
KEY=r'name-of-your-directory'
DIR='/../../path/to/your/include/res/'
import os
import re
import sys
mydir = os.path.dirname(os.path.realpath(__file__))
real_aapt = "%s/%s" % (mydir,"aapt-real")
#args = sys.argv[1:]
args = sys.argv
found=False
nextisdir=False
newargs=[]
for arg in args:
if re.search(KEY,arg):
found=True
if nextisdir:
nextisdir=False
newargs.append("--auto-add-overlay")
newargs.append("-S")
newargs.append(arg+DIR)
if found and arg == '-S':
nextisdir=True
os.execv(real_aapt,args+newargs)
Related
I want write simple application in Python for Android using kivy. Sadly when I start example code I see only splash screen and few second later application finish work. There is a huge problem with debugging because adb on Linux Mint does not detect my device.
Can someone look at my code and tell my why?
To build application I use buildozer. You can also see create_env script to check all dependencies are there.
Best regards.
Draqun
EDIT:
I started debugging my application. Conclusion:
buildozer + python3 + kivy is a bad idea
if I use kivy.uix.button.Button when text attribute is str than I got exception "AttributeError: 'str' object has no attribute 'decode'"
if I use kivy.uix.button.Button when text attribute is bytes than I got exception "ValueError: Button.text accept only str"
It looks like loop with no solution. Some idea when I should report it?
Exception is in .buildozer/android/platform/build/build/python-installs/pad/android/init.py" file so it does not look like kivy and/or buildozer exception.
I've used python-for android tool and faced with the same errors. But in my case, app didn't run at all - crashed from splash screen. Finally, I've found a solution. You can try the same way.
So my pipeline was python3 + python-for-android (p4a tool, python-for-android, from master branch) + kivy (1.10.1)
There is a file "_android.pyx" for android building recipe (full list of avaliable p4a recipes you can see by command p4a recipes). This file is, possibly, used by Buildozer, and exactly used by P4A during APK building procedure. You need to fix it.
You may find it's location in Ubuntu (for example) via:
sudo updatedb
locate _android.pyx
It's path should be something like:
~/.local/lib/python3.6/site-packages/pythonforandroid/recipes/android/src/android/_android.pyx
There should be a string:
python_act = autoclass(JAVA_NAMESPACE.decode('utf-8') + u'.PythonActivity')
so you should change it - something like this:
python_act = autoclass(str(JAVA_NAMESPACE) + u'.PythonActivity'),
or just use some hardcode:
python_act = autoclass("org/kivy/android/PythonActivity")
Or there might be the other decode() usage in sources.
The reason: differences between Python2 and Python3 - the decode() method is usable on the equivalent binary data type in either Python 2 or 3, but it can’t be used by the textual data type consistently between Python 2 and 3 because str in Python 3 doesn’t have the method decode function has different realisation in Python3. More details are here:
pyporting features
issues p4a's github
Hope, it will help you somehow.
I am working on a library that is supported on many platforms including Android. This library is unit tested with the Google Test infrastructure. I am currently using Visual Studio 2015's cross platform features to build, deploy and debug. The test suite is getting considerably large and it takes a while to run the whole thing. With the Google Test infrastructure, it is possible to pass a command line argument to filter out the tests to be ran (--gtest_filter...). For platforms such as Windows, PS4 and XboxOne, this is easy to achieve inside Visual Studio by setting it in Project Properties -->Configuration Properties --> Debugging --> Command Arguments. However for the cross-platform developpment projects and package (AndroidProj), this Debugger property doesn't seem to exist. Here'a snapshot of Android Native-Activity Project Properties.
I am aware that the Visual GDB extension offers a similar feature to the one I am looking for as shown here, but this is not a viable option as I would like to avoid paying for the extension license.
How can I provide command line arguments to the Android Debugger the same way I can do it for the Local Windows Debugger for example?
A colleague of mine found the answer not too long after I posted this question. Here's how we solved our issue.
In VS2015, in the property pages of the Android cross-platform Package/App project (Androidproj), more precisely in the Debugging tab, there is the Launch Activity field. This field can be used to pass command line intent arguments. When you launch the debugger after installing the package, it will execute the following command:
adb.exe am start -D -n com.YourPackageName/TheContentOfLaunchActivityField.
In the Launch Activity field by default the launcher activity is specified (android.app.NativeActivity), but you can provide further intent arguments. A list of them can be found in this documentation: https://developer.android.com/studio/command-line/adb.html#IntentSpec.
In our situation, we needed to provide string data to our app (e.g.: --gtest_filter=...), so we used the intent argument -e extra_key extra_value.
Inside our main function we can retrieve the values of the extras using the following piece of code and some parsing (not shown). It uses the JNI (Java Native Interface).
JNIEnv* env = NULL;
state->activity->vm->AttachCurrentThread(&env, 0);
Private::JNIObjRef nativeActivityObject(env, state->activity->clazz);
jclass nativeActivityClass = env->GetObjectClass(nativeActivityObject.Get());
jmethodID getIntentID = env->GetMethodID(nativeActivityClass, "getIntent", "()Landroid/content/Intent;");
Private::JNIObjRef intentObject(env, env->CallObjectMethod(nativeActivityObject.Get(), getIntentID));
jclass intentClass = env->FindClass("android/content/Intent");
jmethodID getExtrasID = env->GetMethodID(intentClass, "getExtras", "()Landroid/os/Bundle;");
Private::JNIObjRef extrasObject(env, env->CallObjectMethod(intentObject.Get(), getExtrasID));
I'm trying to call a Python script from Tasker using SL4A on my Android (4.4) phone. I'm using the Run SL4A Script task for this. As a test exercise, I want to pass a string from Tasker and use it (for now just print it) in Python.
According to the link below, this can be done by setting the 'Pass Variables' field in the Run SL4A Script task and picking it up with the Android getIntent method in Python. (https://groups.google.com/forum/#!topic/taskerpro/mQIv1PBu3PU)
Here's my Python script:
import android
droid = android.Android
params = droid.getIntent().result[u'extras']
print params[0]
However when I run the task I get the following error in SL4A:
AttributeError: type object 'Android' has no attribute 'getIntent'
Anyone know why I get this and how to solve it? I can't find any reference to it elsewhere.
I don't know about calling from Tasker, but the Python script runs fine stand-alone on SL4A Release 6 and Python interpreter Py4A Release 5.
If you don't have everything installed yet, here are some some slides I recently presented at an Android developers meetup.
I think you are simply missing the parentheses in your Android imports.
I use:
import android
droid = android.Android()
you can also try:
from android import Android
droid = Android()
this makes Android an object in python properly and you should be able to call the getIntent and other functions properly.
and to save time testing if the android module is functional I also add:
def toast(x):
x = str(x)
droid.makeToast(x)
then you can pass variables to the newly defined toast(x) function.
Hope I've helped!
My android app does some http requests to my server. However sometimes I am debugging the new api code that runs on my development machine. I would like to be able to pass something (like an environment variable) so in my code, if it's present I would be able to use that as the hostname for the api requests from the android emulator.
So I'm looking for a way to pass something like:
API_SERVER=http://10.0.2.2/myapp/
and in my code I would use it somehow, for example:
final static String API_SERVER_REAL = "http://example.com/";
final String apiServerOverride = System.getenv("API_SERVER");
final String API_SERVER = (null != apiServerOverride && !apiServerOverride.isEmpty() ? apiServerOverride : API_SERVER_REAL);
I know this thread is quite old, but in my opinion none of provided answers actually solves the problem. Flavors are ill-suited for parametrizing your build with things like API URLs, and even worse for things like API keys etc.
Firstly, build.gradle which defines flavors is part of project source, therefore it must not contain such information in order to be safely committed into source control systems.
Secondly, a need may arise to test different flavors against different API endpoints/keys. What if you just want to hit some debug http server you just created to solve a bug? Would you create a flavor for that? Probably not... Flavors are good for things like "free flavor" and "premium flavor".
This problem is easily solved using gradles -P flag. You can access gradle properties that are passed this way as regular variables inside your gradle.build, and you can vary it's behavior accordingly.
If you want to push this flags further into your application you can use Scott's solution that was posted here, combined with the provided flag.
The build command would then probably look like:
$ gradle build -Papiroot=http://www.example.com
And in your build.gradle you would define the writeValue task like this:
task writeValue(type:Exec) {
commandLine '/usr/local/bin/adb', 'shell', "echo 'API_SERVER=${apiroot}' > /data/data/values.properties"
}
FYI the -P flag can be easily configured in Android Studio by navigating from the menu:
Run -> Run/Debug Configurations -> Defaults -> Gradle -> Script Parameters
Probably the simplest thing is to write the data you want to pass to a file on the device in /data/data; your Android app can read the device trivially (perhaps make it a .properties file and use java.util.Properties to read it in). To write it out, use this kind of task in your build.gradle file (and use the correct path to the adb command for your setup):
task writeValue(type:Exec) {
commandLine '/usr/local/bin/adb', 'shell', 'echo \'API_SERVER=http://10.0.2.2/myapp/\' > /data/data/values.properties'
}
There's documentation on Gradle exec tasks at http://www.gradle.org/docs/current/dsl/org.gradle.api.tasks.Exec.html
You can execute this task manually from Android Studio by using the Gradle tasks view:
Due to a bug in Android Studio, you cannot pass vm or script parameters from a gradle configuration. The issue is here.
As a workaround in Linux envs (probably Mac too), you can create a bash configuration where you will be able to add all desired parameters.
I suggest using productFlavors. Each flavor can contain environment specific settings. I simply have a class called 'Environment' which contains all the public static final Strings that I need and each product flavor includes an different version of this class with the values set for the environment.
I just can't find the help.py file in order to create the API reference for the monkeyrunner. The command described at the Android references
monkeyrunner <format> help.py <outfile> does not work when i call monkeyrunner html help.py /path/to/place/the/doc.html.
It's quite obvious that the help.py file is not found and the monkeyrunner also tells me "Can't open specified script file". But a locate on my system doesn't bring me a help.py file that has anything to do with monkeyrunner or Android.
So my question is: Where did they hide the help.py file for creating the API reference?
I cannot find it either. But one can assume that it is simply calling MonkeyRunner.help() with the passed in arguments. If you just want to get something quick use this script I created also named help.py:
#!/usr/bin/env python
# Imports the monkeyrunner modules used by this program
from com.android.monkeyrunner import MonkeyRunner, MonkeyDevice
text = MonkeyRunner.help("html");
f = open('help.html', 'w')
f.write(text);
f.close();
Run it just like any other monkeyrunner script:
$ monkeyrunner help.py
After I have all codes in my machine (i.e, repo sync), it is at mydroid/sdk/monkeyrunner/scripts along with other three:
help.py monkey_playback.py monkey_recorder.py mr_pydoc.py
This is brilliant answer https://stackoverflow.com/a/4470513/551383 but if you really want this file is in android source i.e. http://androidxref.com/4.2_r1/xref/sdk/monkeyrunner/scripts/help.py
http://androidxref.com/source/xref/sdk/monkeyrunner/scripts/help.py
I believe the documentation on the website starts from that script, but I'm pretty sure somebody edits it a bit afterwards as well.
There's an error in monkeyrunner's help documentation (monkeyrunner Built-in Help), you should use parameters in another order:
monkeyrunner help.py <format> <outfile>
And don't forget about specifying a full path to the script, if you're running it outside of the monkeyrunner.bat directory (android monkeyrunner scripts).
If you don't have Repo Sync, described by users above, you can find the sources (including help.py), for example, here: monkeyrunner scripts.
I opened an issue at Google Code (Issue 26259: monkeyrunner Built-in Help Description Error) and I hope that they'll fix it soon.