WAKE_LOCK or not

One of the most frequent pieces of feedback on Sudoku is that users don’t want the screen to dim when they’re playing. I noticed a few similar apps requiring the WAKE_LOCK permission, but there is a simpler, less dangerous solution.

View has a neat keepScreenOn attribute. Set this attribute in an XML style and the screen will no longer dim when that View is visible. No permission required.

Cleaner screenshots

App screenshots on Google Play often display the system nav bar and have distracting notifications in the status bar. Here are a couple of tricks for making cleaner screenshots – no Photoshop required.

Lose the system nav bar

Create a custom emulator device from the Device Definitions tab in AVD manager. Configure the device with one of the supported screenshot resolutions (such as 720×1280) and change the Buttons toggle to Hardware.

Full health

The emulator status bar will be empty but it displays the battery as discharging by default. Telling the emulator that it has full battery is just a couple of commands (5554 is the default emulator port).

Consistent times

Set the same time between screenshots for maximum consistency. You can even try to reflect the current app version number in the time, if you’re feeling super nerdy: adb shell date -s 20130411.130000


Cleaner screenshot

Secret codes

Android has a neat place to hide debug screens. You can register a receiver for SECRET_CODE broadcasts sent via the dialler. This can be a good place to put feature switches or diagnostic info.

Some of these are built into the platform. Try dialling: *#*#4636#*#*.

With these snippets, dialling *#*#1111#*#* will launch the SecretActivity. FLAG_ACTIVITY_NEW_TASK is required because we don’t have an Activity context for the startActivity() call.

Note: The use of the secret code is clearly visible in the AndroidManifest.xml, so it’s a bad idea to put anything sensitive behind this in a release build.

Email auto-complete 2

A couple of questions came up from the email auto-complete snippet.

Can you auto-complete all emails rather than just Google ones?

Yes. This version checks that account names are email addresses with a regular expression and puts them in a set to avoid duplicates. If you’re targeting API level 8 or above, there is even an email pattern in the Android framework. (You could also reverse the email check and use this code to auto-complete usernames.)

Thanks to Akshay Dashrath, Nick Butcher and Christopher Orr for suggesting those revisions.

Will users complain about the GET_ACCOUNTS permission?

Yes. A few probably will, but for the majority users who pay attention to permissions, it will come down to whether or not they trust your app with their accounts. If you add this permission just to improve your login screen UX then it’s something to consider. However, there are many other reasons to request the GET_ACCOUNTS permission, such as storing tokens in the account manager or using Google Cloud Messaging.

Notification thumbnails

NotificationCompat is a neat way to take advantage of the rich notification features introduced in Honeycomb and JellyBean without worrying about older platform versions. The thumbnail image is expected as a Bitmap, though, so there is a bit of code to write if you want to fetch these images from a server or resize them to fill the available space.

ImageLoader provides a utility for downloading Bitmaps in this scenario (it’s synchronous, you need to handle threading yourself):

Bitmap thumbnail = new DirectLoader().download(url)

If your thumbnail isn’t exactly the right size, here’s a helper class that I threw together to scale and crop a Bitmap to the dimensions expected by the notification tray.

Bitmap scaled = new NotificationThumbnailHelper(context).scaleBitmap(thumbnail)

Email auto-complete

So your login screen has an email address field? It’s easy to save your users some typing by auto-completing email addresses from Android’s account manager.

Firstly, ask for the GET_ACCOUNTS permission in AndroidManifest.xml:
<uses-permission android:name="android.permission.GET_ACCOUNTS" />

This snippet queries the account manager for Google accounts (almost every user has at least one) and puts those email addresses in an ArrayAdapter.

The only thing left to do is change the EditText to an AutoCompleteTextView and call setAdapter(getEmailAddressAdapter(context)) on that View.

You might also consider simply setting the text of the email field when there is a single email address in the account manager.