The Android NDK can get really powerful, but one of the few drawbacks is that the
Android.mk configuration file must list the source files. And if your project contains too many files, it can get quite difficult to maintain. Here's a little tip to list the files in a JNI source trees that is more readable, and more maintainable.
Here's your default
LOCAL_PATH := $(call my-dir)
LOCAL_MODULE := hello-jni
LOCAL_SRC_FILES := hello-jni.c foo/spam.c foo/eggs.c foo/bacon.c bar/banana.c
Assuming you have folders foo and bar inside your jni folders, each with many source files, here's how you can list all your sources. First create a
sources.mk file in each subfolder, with the following code in it :
LOCAL_SRC_FILES += foo/spam.c foo/eggs.c foo/bacon.c
Then modify the
Android.mk file that resides in your jni folder like this ;
LOCAL_PATH := $(call my-dir)
LOCAL_MODULE := hello-jni
LOCAL_SRC_FILES := hello-jni.c
Those who have used the adb tool might have stumbled upon the following message :
$ adb logcat
- waiting for device -
error: more than one device and emulator
In such case, you need to find, then specify the device's serial like this :
$ adb devices -l
List of devices attached
XXX900AKC2 device usb:3-1.3 product:falcon model:XT1032 device:falcon_umts
XXXBDAD913017009 device usb:1-1 product:yakju model:Nexus device:maguro
$ adb logcat -s XXXBDAD913017009
Here I used the logcat command but it's the same thing when you want to install an apk or pull a file from a device.
I've just discovered that if you don't specify a serial, adb will look for an environment variable named ANDROID_SERIAL to know which device to use. If you're often using several devices in USB, you can just add the following aliases to your .bashrc file.
# ANDROID DEVICES SERIAL NUMBERS
alias adb-use-galaxy-nexus='export ANDROID_SERIAL=XXXBDAD913017009'
alias adb-use-moto-g='export ANDROID_SERIAL=XXX900AKC2'
alias reset-android-serial='unset ANDROID_SERIAL'
When using the adb logcat command, you can also set in the ANDROID_LOG_TAGS environment variable a list of tag/severity filter, like in the following example.
# suppresses all log messages except those with the tag "ActivityManager", at priority "Info" or above, and all log messages with tag "MyApp", with priority "Debug" or above
export ANDROID_LOG_TAGS="ActivityManager:I MyApp:D *:S"
These tips are fully compatible with the PidCat tool I talked about earlier.
Sometimes, you might want an activity to be available only under specific conditions. But you may want to completely disable it at runtime when some conditions are met. For instance based on the time, or the user geolocation.
This could also let one have different activities based on the user's configuration
You can do so simply by using the PackageManager. In the following example, I disable an activity and enable another one.
PackageManager pm = getPackageManager();
pm.setComponentEnabledSetting(new ComponentName(this, ActivityC.class),
pm.setComponentEnabledSetting(new ComponentName(this, ActivityA.class),
The manifest declares the two activities with the same intent filter, namely the home screen shortcut. But using the previous code, I'm able to get a single one of them in the launcher menu at any given time.
In one of my application, I want to perform an action when the user has been idle for more than n minutes.
While searching the web I found those two callbacks in the Activity class : onUserInteraction() and onUserLeaveHint , both available since Cupcake.
The first one is simply called whenever an interaction is consumed by the activity : touch, key event, trackball event. The second is called just before onPause() when the user leaves your Activity on purpose. For example by pressing the home button, launching another activity from the notification bar. It won't be called when an Activity generated by the system comes in the foreground (an incoming phone call for instance).
And there are a lot more callbacks in an Activity that one can override. So, after some extensive logging and reading through AOSP sources, here's a new and more complete Activity lifecycle graph, with all the callbacks one may find usefull. I also included the callbacks sent to an Activity's fragments.
Feel free to add any remark to make this diagram as accurate as possible.
A couple of days ago, a question popped on StackOverflow, asking how to link a log line in LogCat to the source code, just like it happens when you Log an exception.
The first answers where to add a fake Exception. Naturally, there will be the line you want, but also a lot of noise in your LogCat.
Then someone proposed a method to simulated an exception Log, without the whole stacktrace (see the answer here).
The solution works fine, but can be quite verbose. With a little bit of try and error, I found out that the most important part is the "at (file.java:42)". It doesn't matter where it is in the message. You can even have mor than one, it only takes into account the last one.
So I worked out a LogLink class to use this systme anywhere and seamlessly. Here's an example of how it works :
// can be one of INSERT_FIRST, INSERT_LAST or INSERT_NONE
// default value is INSERT_LAST, and you can call it only once
// also exist as v, d, w, e and wtf
LogUtils.i("MyClass", "A message");
The previous code will output the following output
MyClass A message at (MyClass.java:42)
You can see and download the LogUtils class here