Mark L. Murphy's Blog, page 74
June 16, 2012
Omnibus v0.8 Released
Version 0.8 of the omnibus edition of The Busy Coder’s Guide to Android Development, as re-envisioned as part of The Big Book Reboot, is available to most subscribers. Those who subscribed after around noon Eastern Time on June 16th will start getting the Omnibus with the next update. Right now, PDFs and APKs are available for everyone. EPUBs and Kindle/MOBI editions are rolling out now, and everyone should have theirs soon.
This release migrates over most of the remaining material from the other books. Some of these migrated chapters are complete. Some are riddled with “TBD” notations to myself. About 9 chapters are completely missing. However, the book is getting pretty close to completion, and is presently around 1,500 pages.
In addition to the migrated material, I added some completely new material:
A chapter on device administration APIs
A chapter on writing extensions for the SONY SmartWatch™ Android accessory
A section in the NFC chapter on Android Beam
One last(?) tutorial
Version 3.9 (to adopt the numbering from The Busy Coder’s Guide to Android Development) should be out (hopefully) around July 4th or 5th. This should complete the book; 4.0 will ship a few weeks later with bug fixes.
If you encounter problems with the Omnibus or have other Omnibus-related feedback, please contact me at omnibus /at\ commonsware.com.
June 8, 2012
Removing Rogue Menus (Or, Why Targeting 14 Might Be Necessary)
Those of you rocking Honeycomb or Ice Cream Sandwich devices that lack an off-screen MENU button have no doubt seen various apps that display the … overflow menu affordance, but nothing happens when you tap on it:
You will get that effect on apps that have their android:targetSdkVersion set to 10 or lower. The normal solution is to bump that to at least 11, in which case the affordance vanishes, except if the overflow area is needed, in which case it appears in the action bar.
However, not all devices behave this way. For example, the HTC One S has off-screen HOME, BACK, and RECENT buttons, but no off-screen MENU button. You would expect that a target of 11 would suffice to remove the on-screen overflow menu affordance… and you would be mistaken. Instead, a navigation area at the bottom of the screen will be solely such an affordance:
The solution is to raise the android:targetSdkVersion to 14 or higher. This eliminates the navigation area entirely when it is not needed on an HTC One S.
Bear in mind, though, that setting your target that high will also have other effects, notably causing your AsyncTasks to be serialized by default.
May 29, 2012
Omnibus v0.7 Released
Version 0.7 of the omnibus edition of The Busy Coder’s Guide to Android Development, as re-envisioned as part of The Big Book Reboot, is available to most subscribers. Those who subscribed after around noon Eastern Time on May 28th will start getting the Omnibus with the next update.
This release adds… well, not nearly as much as I would have wanted for that length of time, since the last update:
Six new tutorials
A largely rewritten chapter on AlarmManager
A mostly rewritten chapter on Notification, including using Notification.Builder and NotificationCompat.Builder
Pulling material on ordered and local broadcasts from The Busy Coder’s Guide to Advanced Android Development into the core chapters
Various bug fixes and minor tweaks
Here are the update plans from this point forward:
Version 0.8 should be out in 2-4 weeks, containing all remaining material from the other books, plus rewritten chapters on maps and testing, plus some brand-new material (e.g., device admin APIs)
Version 4.0 (to adopt the numbering from The Busy Coder’s Guide to Android Development) should be out two weeks after 0.8, with no modifications other than bug fixes
Monthly updates after that
The exception will be if Google releases an Android update in and around Google I|O (4.1, 5.0, Turbo System V, whatever). I may elect to try to weave in some of that coverage before christening Version 4.0.
If you encounter problems with the Omnibus or have other Omnibus-related feedback, please contact me at omnibus /at\ commonsware.com.
May 24, 2012
A Community-Driven Compatibility Library
An hour ago, I was taken to task by somebody, for correctly pointing out that CalendarContract is only available on API Level 14 and higher.
The commenter asked about “possible work arounds” and bitched about Google (I presume) not providing a compatibility library for the calendar API.
The Android Support package does provide a “compatibility library” for some newer APIs, but it is mostly in the form of backports. If you are supporting older devices, you can use the backport; once you are only supporting newer devices, you can drop the backport. However, because Calendar is an app, installed in firmware, it is not possible to create a backport that can be tossed into the Android Support package.
That does not mean that a compatibility library is impossible. In fact, it is eminently possible for anyone to create a documented and supported compatibility library for calendar access, if they have the itch to scratch.
Accessing the calendar has long been possible, via an undocumented and unsupported ContentProvider. However, accessing that ContentProvider has never been advisable, because it changes over time and might be modified on particular devices by OEMs.
A good community-drivren compatibility library for the calender might have the following characteristics:
It would support a superset of the classic undocumented API and the new CalendarContract API
It would have a “capabilities” API to determine, at runtime, what particular gross features are supported by the underlying calendar implementation, to handle differences between the old and new APIs, to handle places where device manufacturer changes break the old API, etc.
Akin to LocationManager and SensorManager, it would offer a single API to potentially multiple calendar backends, to handle both AOSP Calendar apps (old and new) and any OEM or third-party calendar apps that support some sort of API
It would provide implicit Intent action strings that would be remapped to the actual activity implementations, for common actions like viewing the calendar, viewing an entry, editing an entry, etc., where supported by the backend calendar implementation
It would have some semblance of documentation and support
It would have clearly described licensing (whether open source or commercial)
Nothing in that list represents something only Google could do. Anyone who wants to could spend the time creating such a library. Then, it would be incumbent on the library author to be the support point for that library, and the library author would need to deal with any device-specific idiosyncracies and the like. The broader Android ecosystem could use the library with a stronger degree of confidence than they would in using any prior iteration of the undocumented system API.
However, AFAIK, nobody has created this library for the calendar. I might, someday, though presently it is a very small itch compared to others on my 18,000-item to-do list. With luck, somebody else who has a larger itch will scratch this.
May 10, 2012
Long-Running Services and User Acceptance
There is a fairly extensive thread in progress on the android-developers Google Group, discussing the behavior of long-running services.
Unfortunately, the original poster on that thread drew incorrect conclusions from his market research. He found that there were other apps like the one he wanted to create, that used long-running services, and that those apps had decent ratings. His conclusion is that there is no problem with long-running services. Along the way, he ignores not only all the problems with his analysis (including low sample size and sampling bias), but also all the evidence that points to the contrary, such as the millions of users of so-called “task killers”.
However, he does have a point. Long-running services are not intrinsically user-hostile. The issue is not the service — the issue is the control over the service.
For example, let’s examine two apps that I always have installed on whatever phone I’m carrying at the time: United Airlines and Ambling BookPlayer Pro.
If I examine the Running tab of the Apps screen in Settings on my Galaxy Nexus, I see that both of these apps have “1 process and 1 service”. Yet, I am sincerely frustrated at United Airlines and worry not a whit about Ambling BookPlayer Pro.
Why? Control, and to a lesser extent, sensibility.
It is entirely possible that there is a reason why the United Airlines app would need a service. However, there is no obvious need for why it would need a service running all the damn time. I have not run the app in days. I have no control over whether this service is used, short of getting rid of it from Settings. I tend not to bother, but it frustrates me, and I can easily see other users attacking the United Airlines app with task killers to try to get rid of the service.
Contrast that with Ambling BookPlayer Pro. It too has a service running all the time. In fact, its process consumes almost twice as much RAM as does the United Airlines app, so in theory I should be twice as annoyed. But I am not.
Why?
I know why the service is there — it is waiting for headset plug events
I value the service being there, as I like being able to just plug my phone into my Prius and not necessarily have to fumble with the touchscreen to get the audiobook playing again
It is a foreground service, so I have an icon that I can get to where I can stop the service through the player’s UI
The only thing that it is missing is an obvious way to prevent the service from running in the first place, albeit at the cost of not handling headset plug events.
Ideally, you do not have an everlasting service in the first place, and use polling or other techniques. If, however, you have a technically justifiable reason for trying to have a service run constantly, ensure that the user knows why the service is there and give the user the ability to control the service behavior, including disabling the service outright at the cost of some functionality. Those items should help improve user acceptance of your everlasting service and reduce the percentage of bad reviews because of your service.
May 5, 2012
Omnibus v0.6 Released
Version 0.6 of the omnibus edition of The Busy Coder’s Guide to Android Development, as re-envisioned as part of The Big Book Reboot, is available to most subscribers. Those who subscribed after around 8am Eastern Time on May 4th will start getting the Omnibus with the next update.
This release adds ~200 pages, including a bunch of brand-new material:
Nine new tutorials
A largely rewritten chapter on Internet access
A partially rewritten chapter on Intents, filters, and broadcasts, incorporating some material originally found in The Busy Coder’s Guide to Advanced Android Development
A slightly revised chapter on services
A largely rewritten chapter on large-screen strategies and tactics
A largely rewritten chapter on backwards-compatibility strategies and tactics
This release tweaked the PDF format a bit, arranging for all chapters to begin on the right-hand page, to work better when printed.
The next update, 0.7, is expected to be out in about two weeks, with the rest of the new tutorials, plus a few more chapters.
If you encounter problems with the Omnibus or have other Omnibus-related feedback, please contact me at omnibus /at\ commonsware.com.
May 1, 2012
It's the User's Data, Dammit
One of the benefits of projects like SQLCipher for Android getting more attention is that developers are learning that protecting users’ data from poachers is easier than they might have thought.
One of the downsides of projects like SQLCipher for Android getting more attention is that developers start thinking they can do things that they cannot. Notably, in this case, some developers are trying to use SQLCipher for Android to prevent users from accessing data on the user’s own phone.
That’s just not possible.
Users who root their devices can get to any files they want. This includes the encrypted database and your APK file. Finding the encryption key in the APK file is not going to be all that difficult – obfuscation is good for shrouding your own code implementation but is not that good at hiding encryption keys or calls to third-party code like SQLCipher for Android. At best, your encryption adds another small hurdle to overcome, reducing the percentage of people who will bother, but it will not stop them all. And, of course, once your key is compromised, that key can be widely disseminated, and lots more people can get at the data.
If you put data on the user’s device, it is now the user’s data.
Depending on the data, you can take some steps to help steer users towards proper use of that data. Watermarking is a popular solution for media (MP3s, EPUBs, etc.) – it does not stop the user from copying the file, but if the copies get widely distributed, it becomes possible to track down who the original copier was. That information may be sufficient to help prevent future copying (e.g., termination of an account) and may be sufficient for legal action, if you so choose.
If, however, the user simply cannot be allowed to see the data, do not put it on the user’s device. Keep it on your servers, downloading it only as needed, and taking steps on your servers to prevent unauthorized access. That too may prove challenging, but at least you have complete control over the environment.
Using SQLCipher for Android to help protect the data of users who leave their Android tablets in airplane seat-back pockets is a wonderful thing, and I hope more developers do it. Using SQLCipher for Android to try to hide data from users amounts to “roll your own DRM”, and we all know how well DRM solutions work.
April 25, 2012
Omnibus v0.4 Released
Version 0.4 of the omnibus edition of The Busy Coder’s Guide to Android Development, as re-envisioned as part of The Big Book Reboot, is available to most subscribers. Those who subscribed after noon Eastern Time on April 15th will start getting the Omnibus with the next update.
This week, the Omnibus is now available in PDF form, along with EPUB and MOBI/KF8. There are a few changes in the PDF file from the style used for the classic books:
The page size is 8.5” x 11”, to make it easier for those who wish to print off chapters
There is no index, as this is intended for use in digital form, and free-text search is much better than the auto-generated index
The PDF generation is using a different tool than before, which may change how the rendering works on some PDF viewers
If you encounter problems with the PDF edition, please contact me at omnibus /at\ commonsware.com.
In terms of coverage, this update adds:
A slightly revamped chapter on the activity lifecycle
A completely rewritten chapter on introductory use of fragments
A brand new chapter on using ViewPager
A moderately revamped chapter on configuration changes
A restored copy of the “Where Do We Go From Here?” chapter
If all goes according to plan, Version 0.5 will ship in a week, with a few more updated chapters, plus another new file format.
If you encounter problems with the Omnibus or have other Omnibus-related feedback, please contact me at omnibus /at\ commonsware.com.
AsyncTask Threading Regression Confirmed
A long time ago, Romain Guy indicated that AsyncTask would eventually move to serialized operation, where only one task would execute at a time, rather than the behavior (starting with Android 1.6) of having tasks run in parallel.
While code to this effect appeared in the repo and JavaDocs, I could not reproduce the problem, and so I wasn’t sure what to make of it.
Today, I have been illuminated.
(and, no, I do not mean that I have been decorated by monks in gold leaf, because that would just be creepy)
If your android:targetSdkVersion is set to 13 or higher, and you are running on Android 4.x or higher, AsyncTask will use an Executor that executes only one task at a time. Otherwise, you get the older parallel execution behavior. It is possible that this behavior kicked in on some patchlevel release of 3.2, but current indications are that it did not.
You can opt into having your tasks continue to be executed in parallel by using executeOnExecutor() and AsyncTask.THREAD_POOL_EXECUTOR.
The thread where this analysis was done, including Dianne Hackborn’s rationale for the decision, can be found on the android-developers Google Group.
If you have been making heavy use of AsyncTask, you need to consider how this will be affecting your code, and decide which tasks you want serialized and which you really do want in parallel.
If your build target is set to API Level 11 or higher, and you want to specifically use parallel tasks, you will want to start stating that explicitly in your code, akin to:
if (Build.VERSION.SDK_INT>=Build.VERSION_CODES.HONEYCOMB) {
myTask.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
}
else {
myTask.execute();
}
(if you are still supporting Android 1.x, or if you refuse to set your build target to API Level 11+, the code is commensurately harder)
While this code is not necessary until you set your android:targetSdkVersion to 13 or higher, that sort of change is easy to miss – you might think bumping the target only affects some UI stuff and miss that it seriously affects your threading logic.
Many thanks to Ms. Hackborn for helping to clarify what is going on, and many thanks to Kostya Vasilyev for helping to get to the bottom of this.
Omnibus v0.5 Released
Version 0.5 of the omnibus edition of The Busy Coder’s Guide to Android Development, as re-envisioned as part of The Big Book Reboot, is available to most subscribers. Those who subscribed after around noon Eastern Time on April 22nd will start getting the Omnibus with the next update.
This release adds some new material:
A rewritten chapter on threads
A lightly updated chapter on permissions
A mostly-reworked chapter on local files and assets
A trimmed-down chapter on SharedPreferences
A reworked chapter on SQLite
Also, 0.5 introduces a new book format: APK. Here, by “APK”, I mean that the omnibus is available as an installable Android application, using its own digital book reader, EmPub, for Android 2.2 and higher.
There are several objectives with the EmPub initiative:
EPUB readers, on the whole, mangle the book, because they replace my CSS with their CSS. I want to make sure that there is an on-device option that always faithfully renders what I am trying to write.
EmPub will serve as the foundation for a new set of tutorials, building up a subset of EmPub capabilities (in a app called EmPubLite).
While EmPub is fairly basic at the present, I intend to add more capabilities over time, not only to make it more usable to you as a reader, but also to demonstrate Android capabilities in an app that is bigger than my typical focused examples. That being said, EmPub is not designed to have an infinite number of features.
EmPub is open source, so others might find use for it in its entirety, though that is not its principal aim by any stretch.
Right now, to get the APK onto an Android device, the easiest approach probably is to download the APK on your desktop or notebook, then install it on your device (e.g., via adb install). I will eventually add a QR code to allow you to get it onto the device a bit easier. Also, eventually, EmPub will optionally self-update, downloading new versions overnight and letting you then install them when you are ready. The book will not be on Google Play Store or any other market, though I may distribute a free sampler edition by those venues.
The EmPub usage model is fairly basic:
Swipe vertically to read within a chapter
Swipe horizontally to switch between adjacent chapters
Click any link to open it, and if it is an internal link, you should slide over to that chapter and section
Tap on the icon in the upper right to return to the table of contents, where you can click any link to visit any chapter
As with the PDF, KF8, and EPUB (for the few readers that support it), changebars work in EmPub to highlight what is new or changed within a chapter.
If you encounter bugs or have feature requests for EmPub, please file an issue.
If all goes according to plan, Version 0.6 will ship in about two weeks, with a few new chapters and a bunch of new tutorials, based on EmPub and EmPubLite.
If you encounter problems with the Omnibus or have other Omnibus-related feedback, please contact me at omnibus /at\ commonsware.com.


