Wednesday, August 17, 2011

Alternatives to the BOOT_COMPLETED broadcast

The normal way to start an Application or Service is to implement a Broadcast Receiver that listens for the "boot completed" broadcast. This approach will only work for Applications that are not installed on the SD card, because "boot completed" is broadcasted before the SD card is mounted, therefore the Application can never receive the broadcast, see also: http://developer.android.com/guide/appendix/install-location.html#ShouldNot. But it is generally a bad idea to force the installation on internal phone memory as it is restricted. It is more likely for a user to keep an Application installed if it uses as little as possible internal memory.
There is an alternative that can be used in many cases. The USER_PRESENT intent is broadcast when a user is present after the device wakes up, e.g. the user unlocks the screen. With this intent it is possible to start a service that is installed on the SD card.






Wednesday, August 3, 2011

Localization of Help Files

My application is using an html file in the asset folder as a help page. Unfortunately there is no direct support from the Android system to load assets based on locale. An easy and elegant workaround is to use a R.String value for the file name:

String helpFile = getString(R.string.help_html);
String url = "file:///android_asset/" + helpFile;

Then create html files for all the supported languages and name them, e.g., de_help.htm, es_help.html. Create the appropriate language folders in res, e.g., values-de, values-es and create string.xml files with the appropriate entries for the help files,e.g.:

<string name="help_html">de_help.html</string>

At this point you probably also want to translate the rest of the strings in your application.

Friday, July 29, 2011

Sharing Objects between Activities in Android

It can be difficult and cumbersome sometimes to share arbitrary objects between Activities in Android. For primitives the best way is usually to use SharedPreferences or Intent.putExtra. 
However it is not possible to pass directly an arbitray object to an activity. A simple and effective way is to use static fields on an Application object:


public class MyApplication extends Application {

   public static MyObject myObject;

   @Override
   public void onCreate() {
      super.onCreate();      
      //initialize myObject here, if needed
   }
}


To access myObject from any Activity in the application simply with MyApplication.myObject. This approach allows clear and simple way to exchange data beween Activites.
You could also use a static hashmap, and pass the key around to access the required object.
For interprocess communication more work is required, either a ContentProvider should be used or AIDL, but the purpose of this pattern is to avoid all the boilerplate code associated with it.

Sunday, July 10, 2011

How to find available locales in Andoid

In Java the usual approach to find the available Locales on a System is to use:

Locale.getAvailableLocales()

This will return a pretty large number of Locales. Another approach is to use the AssetManager:

Activity.getAssets().getLocales()

This will return the Locales that the AssetManager contains data for, which is typucally a lot less than what Locale.getAvailableLocales()
returns. It probably makes more sense only to use these Locales in an Applications.

Wednesday, July 6, 2011

Show Soft Keyboard for Text Entry

This snippet can be used to force the display of the soft keyboard

InpuptMethodManager im = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
im.toggleSoftInput(InputMethodManager.SHOW_FORCED, 0);

However it is better to check first if the device has a hardkeyboard, in that case you might not want to show the soft keyboard.

boolean hasHardKeyboard = false;
Configuration config = getResources().getConfiguration();
if (config.keyboard != Configuration.KEYBOARD_NOKEYS) {
hasHardKeyboard = true;
}

Friday, July 1, 2011

Browsing the SQLite database in Android

An easy way to browse your android application database is to use the Questoid SQLite Browser for eclipse. The easiest way to install it is through the eclipse marketplace (Help > Eclipse Marketplace).

To browse the SQLite Database of an Application go to the file explorer in the DDMS perspective and look for the database file under data/data/applicationpackage/databases, select it and click on the database icon in the file browser.

Monday, June 20, 2011

Using SharedPreferences in Android Properly

The use of SharedPreferences outside of an Activity Class can become very tedious. This is because PreferenceManager.getDefaultSharedPreferences(Context context) requires a context object. In order to simplify things an easy solution is to use the Application object like this.


public class MyApplication extends Application {

   public static SharedPreferences settings;

   @Override
   public void onCreate() {
      super.onCreate();
      settings=PreferenceManager.
            getDefaultSharedPreferences(this);
   }
}

This code will work because the Application object is created before all other activities, hence the initialization is guaranteed. Now the SharedPreferences can be simply statically accessed via MyApplication.settings.