Mark L. Murphy's Blog, page 54
November 24, 2014
Material Design: Strategic Considerations
There has been a lot of discussion regarding the adoption of Material Design aesthetics in Android apps. Newcomers to Android might conclude that Material Design must be The Most Important Thing in Android Development and therefore should be pursued immediately at all costs.
Not everybody shares this opinion
Hence, FWIW, here is my take on how you should be thinking about Material Design in the here and now. As usual, imagine a grain of salt approximately 30cm on a side, and take that grain of salt with my thoughts on the subject.
DO start considering the effects of Material Design upon your Android app. Theme.Material is the dominant theme on Android 5.0 devices, and it should remain the dominant theme on future Android versions, at least for a while. There will be hundreds of millions of these devices in use, eventually, and you will want your app to look like “it belongs” on those devices. On those devices, not only will Google’s apps be employing Theme.Material, but manufacturer-supplied apps should do so as well. While not everything on the device may necessarily adopt this theme, more than enough will that your app may stand out somewhat if your app does not and the user thinks that it should.
DON’T worry about this right away. Android 4.4 reached 30% of the Android device ecosystem after one year, and we have not seen that rate of adoption since Android 1.0. Odds are that it will be mid-2015 before Android 5.0 crosses the 10% threshold. As such, there just are not that many Android 5.0 devices out there, so worrying about those devices over the next several weeks is serious overkill.
DO plan on including Material Design impacts in your next UI refresh, and you should probably try to budget time for that refresh by the end of 2015 (by which time Android 5.0 might be 20-30% of the ecosystem).
DON’T blindly assume that you should be using a Material-ish look on all versions of Android. Your objective should be having an app that looks like it belongs on the device. Material-themed apps are highly unlikely to achieve majority status, let alone dominance, on pre-Android 5.0 releases. After all, device manufacturers are not going to be shipping Material-themed updates to built-in apps en masse, and there are plenty of apps out there that are still using pre-Holo themes. This is all on top of app that have no identifiable Android theme (e.g., most games). Certainly, there will be Material-themed apps running on Android 4.x devices, courtesy of Google and some other developers. But there will be enough Holo-themed apps that your app will not look out of place on Android 4.x any time soon, if ever. Hence, you have your choice of adopting Material Design across the board or not – user pressure is unlikely to be a major criterion any time soon.
DON’T fall victim to the “our app must look the same across all devices” mindset. Again, your app should look like it belongs on the device, which is why trying to ape an iOS look-and-feel on Android is rarely a good move. Most people do not have two Android devices, and only a small subset of those will have an Android 5.x device and an Android 4.x (or older) device. Hence, most of the people who will care about your app appearing identical on those devices will be in your meeting room discussing the issue. Few of your users will notice – they want an app that works, does what the user wants, and looks like it belongs on their device.
DO consider whether adopting Material Design across the board may offer engineering benefits. For example, if you have been heavily customizing widget colors in a Holo-based theme, the tinting options provided by appcompat-v7 may simplify your app a fair bit, reducing APK size, maintenance costs after the Material conversion, etc. Since your users are unlikely to be terribly concerned one way or the other, engineering considerations may help to “tip the scales” in one direction or another.
DON’T blindly assume that appcompat-v7 will result in a simpler app, or that it should be the basis for all new apps. While the original appcompat-v7 has now been around for 16 months or so, the new Material appcompat-v7 is very young, and hence it has bugs, such as requiring extra work to function on Android 4.2.2 Samsung devices. Not all of those bugs are Google’s fault (e.g., the Samsung device issue was really caused by a screwy decision on Samsung’s part), but that comes as cold comfort to developers trying to distribute appcompat-v7 apps. And, if you are comfortable with using themes based on Theme.Holo for pre-Android 5.0 devices, appcompat-v7 may be much more of an impediment than an advance. appcompat-v7 is a tool, not a religion – use it where it clearly adds value to you and your app.
DO start planning for Google’s next major theme overhaul. Google, of course, is portraying Material Design as being The One True UI Design. Google will probably get irritated when people like me point out that Theme.Material is the third major theme in the six-year production history of Android, and so assuming that Theme.Material is “the be-all and end-all” of themes is unrealistic. Whether the next-generation theme is a refinement on Material Design or a larger overhaul remains to be seen. But you should be taking into account that we may well wind up going through this same process in, say, early 2018. The more you can isolate the theme-related changes from the rest of your app, the more likely it is that you will be able to accommodate future theme changes with less work.
November 18, 2014
The Busy Coder's Guide to Android Development Version 6.2 Released
Subscribers now have access to the latest release of The Busy Coder’s Guide to Android Development, known as Version 6.2, in all formats. Just log into your Warescription page and download away, or set up an account and subscribe!
This update is smaller than I would have liked, and I apologize for that. It contains:
Some basic Android 5.0 coverage, including notes about various deprecations
Information on how Android 5.0 changes notifications, including heads-up and lockscreen notifications
A new chapter covering JobScheduler, the new Android 5.0 AlarmManager-with-more-brains system service
Added some limited material on batterystats and Battery Historian, the other developer-facing pieces of Project Volta beyond JobScheduler
Rewrote much of the chapter on service binding and remote services, including a fresh set of examples and coverage of Android 5.0’s restriction on the use of implicit Intents to bind to services
Updated the chapter on the Memory Analysis Tookit (MAT) to include how to use it from Android Studio
Rewrote parts of the first two tutorials to deal with changes introduced by Android Studio 0.8.14
There should be one more update to the book in 2014, probably in mid-December.
Android 5.0 Deprecation: splitActionBarWhenNarrow
UPDATE: If your app specifically uses Theme.Holo (or themes inheriting from it), splitActionBarWhenNarrow continues to work on Android 5.0. If you are using Theme.Material — whether explicitly or because you did not specify a theme — then splitActionBarWhenNarrow no longer works.
Gosh, it would be nice if deprecated features were actually documented as deprecated.
Alas, in the case of splitActionBarWhenNarrow, this capability was quietly dropped in Android 5.0, but the documentation does not mention this. This goes beyond standard deprecation (“we think that there is a better solution that we would like you to use, but we will support this for the foreseeable future”). This is out-and-out “dead-ification”: splitActionBarWhenNarrow no longer splits the action bar, on Android 5.0+.
Of course, splitActionBarWhenNarrow was never a guarantee, and certain devices and configurations would not split the action bar. For many apps, therefore, the only real impact will be with aesthetics, where now a bunch of action bar items wind up in the overflow in narrow scenarios, instead of being visible on the split action bar.
Where the problem becomes much greater is if you were more significantly relying upon action bar items being directly visible:
You used actionLayout or actionViewClass for items and do not have a suitable onOptionsItemSelected() handler for the scenario
You assumed that your action item with the ProgressBar or the like would always be visible, so users now no longer realize that some background operation is going on
You assumed that your actionLayout would always be inflated and therefore crash when it is not inflated
And so on
While the official answer appears to be to use a bottom-aligned Toolbar, getting a look equivalent to splitActionBarWhenNarrow appears to be tricky, and the Toolbar approach will not work prior to API Level 21 (unless you’re going the route of using appcompat_v7, which has its own issues).
Again, Google is welcome to change whatever it wants, whenever it wants in Android. It is Google’s platform. It would just be nice if Google would actually tell people when they deprecate this sort of thing.
November 14, 2014
Samsung/droidcon UK Presentations
I delivered presentations on memory management and Project Volta at the 2014 Samsung Developers Conference yesterday. The Project Volta presentation is one that I had originally delivered at droidcon UK 2014.
You can download the slides from both presentations. The droidcon UK 2014 video is reportedly available, but since Vimeo and I do not get along, I have no idea what it looks like. The Samsung conference sessions were recorded, but I do not know what their plans are with respect to publishing those videos.
October 17, 2014
Random Musings on the Lollipop SDK
With each Android release, Google issues an API differences report, outlining things that were added, changed, or removed in a new API level compared to the previous one. This time around, for Android 5.0 theirs is a diff against the “L” Developer Preview, which is mildly annoying. Ideally, the comparison would be with the last production release.
UPDATE: There is separate differences report for API Level 20 to 21 that is probably a better choice for most people. Hat tip to Mike Evans for pointing it out!
I always review this to see what’s different beyond the sorts of changes that get more disclosure, coverage in Google I|O presentations, etc.
A few months back, I reviewed interesting changes in the “L” Developer Preview. Some of that stuff has stuck around for the Lollipop release, and more stuff has shown up that seem worthy of mentioning.
Here is what I see of interest that is new to 5.0, over “L”, with deprecations marked in bold:
While a compacting garbage collector was one of the hoped-for outcomes from the release of a production-grade ART, it looks that that is still a work in progress. Hence, it is unclear how much ART will help with garbage collection.
Somebody is probably already writing malware to make use of the screen capture and screen sharing APIs. If my reading between the lines is accurate, any activity using FLAG_SECURE will not be captured, just as their thumbnails are not captured for the recent-tasks list. However, this is yet another reason to consider using FLAG_SECURE, either on your own or at user request via a setting.
Those malware authors not working on the screen capture stuff are probably working on the screen pinning stuff, where apps can prevent the user from leaving their apps. While this, like the screen capture stuff, requires users to agree via a pop-up dialog, way too many users are likely to just say “yeah, um, whatever” and get screwed. And, if the documentation is accurate (and it’s probably not), to escape, the user has to press and hold BACK and RECENTS… but RECENTS is hidden and therefore cannot be pressed. Joy.
Neither the screen capture/sharing stuff nor the screen pinning stuff require any permissions. Nor do they require the double-opt-in pattern we have seen with things like DeviceAdminReceiver, NotificationListenerService, etc. Instead, they just require tapping on a dialog to accept. As a result, users have no way of knowing, before installing an app, whether the app will try to do any of these things.
Google not only is offering a new Camera2 API, but they deprecated the original Camera API. I have no clue what I am going to do with my CWAC-Camera library…
The API overview says that “a new system-managed processing thread called RenderThread keeps animations smooth even when there are delays in the main UI thread”… with no other obvious documentation on the subject. It would be nice to know how this relates to our ways of checking for and fixing jank.
I’m going to need to run some tests to figure out WTF the setAlarmClock() method is on AlarmManager.
We now have a first-class PackageInstaller for installing apps. I am not completely clear on whether or not this is a good thing, as I do not see any discussion of security.
Sticky broadcasts are now deprecated. There is no indication if there will be future changes to existing system-sent sticky broadcasts, like ACTION_BATTERY_CHANGED, but it is something to keep an eye out for in future releases.
Here are items that I reported previously for the “L” Developer Preview that still seem to be applicable to Android 5.0 (with light prose fixups):
Action bar navigation, of all forms, is deprecated. This includes both action bar tabs and drop-down (“list”) navigation. It does not include the “custom view navigation” (e.g., browser address bar).
Part of the reason for this is that the action bar is being pulled out into something more readily manipulable by us developers. Activity has a setActionBar() method, taking a Toolbar parameter. Toolbar basically looks like a simplified action bar and can be placed in arbitrary spots elsewhere in your view hierarchy, in contrast with the locked-to-the-top action bar.
getRecentTasks() and getRunningTasks() on ActivityManager are now deprecated and will return a reduced result set on L and higher devices.
BatteryManager now gives us the ability to directly access battery information, without having to fuss with registering a null receiver for ACTION_BATTERY_CHANGED, albeit via a somewhat clunky getIntProperty()/getLongProperty() API. Presumably, this is with an eye towards making ACTION_BATTERY_CHANGED be non-sticky, given the sticky broadcast deprecation mentioned above.
bindService() now requires an explicit Intent, if your targetSdkVersion is set to 21 or higher.
We now have getExternalMediaDirs(), which is a bit like getExternalFileDirs(), but represent directories that will be scanned by the MediaStore.
A boatload of new stuff has been added to DevicePolicyManager for those of you using the device admin APIs.
FragmentBreadCrumbs is now deprecated, for the six of you who were using that class. :-)
There is a new LauncherApps class that helps simplify finding the relevant launchable activities. This is tied into the new managed profiles system.
MediaStore has been augmented with MediaStore.Audio.Radio. It is largely undocumented, and so it is unclear if this is referring to streaming radio stations, classic broadcast radio (e.g., FM), or something else.
The TOP_LEVEL_* patterns in Patterns are now deprecated, presumably reflecting the fact that the number of top-level domains is expanding rapidly.
Android now has some amount of tracking of “power save mode”, with an isPowerSaveMode() on PowerManager and an ACTION_POWER_SAVE_MODE_CHANGED broadcast. Whether this is for OEM-specific modes or for some new common power save framework in Android, I cannot say.
In what might be a first, something was “undeprecated”, specifically INSTALL_NON_MARKET_APPS on Settings.Secure, as it was moved back there from Settings.Global.
WebSettings now lets you control mixed-content mode, referring to whether WebView should load insecure content from a secure origin.
October 14, 2014
The Busy Coder's Guide to Android Development Version 6.1 Released
Subscribers now have access to the latest release of The Busy Coder’s Guide to Android Development, known as Version 6.1, in all formats. Just log into your Warescription page and download away, or set up an account and subscribe!
This update:
Adds material to the advanced notifications chapter on how notifications work with Android Wear devices, including how to lightly customize your notifications to add more Wear-friendly features
Adds two chapters covering the Storage Access Framework, for how apps can consume and publish documents on Android 4.4+
Adds a new advanced databases chapter, including a section on how to work with full-text indexing and searching (FTS) on SQLite
Adds some material on WebView security issues
Updates the “Fused Location Provider” chapter to replace the deprecated LocationClient with the current (yet stubbornly undocumented) new API
Various bug fixes and miscellaneous improvements
In addition, all the samples were upgraded to use Gradle for Android 0.13 and add the stub Gradle wrapper files, enough to allow for easy import into Android Studio. However, always check the gradle-wrapper.properties file before importing anything into Android Studio, as there is always the chance that somebody has published material linking you to a hacked Gradle installation.
The exact timing of the next update is a bit indeterminate, as is typical around likely Google announcement times. Most likely, the next update will not be until early December, though I may try to rush out an update before then if the next production version of Android ships soonish.
If you are not a subscriber, you may wish to learn what the Warescription has to offer. The book, plus a year’s updates and other Warescription benefits, costs $45 (credit card/debit card/PayPal) or its equivalent in Bitcoin.
September 29, 2014
Predictions of Play Store Fallout
The recent changes to the Play Store terms of service, requiring physical addresses and imposing a service-level agreement (SLA) on support questions are not terribly surprising moves. Google is basically trying to get developers of paid/in-app purchasing (IAP) apps to “raise their game” and provide better support to buyers.
That being said, I’m not sure that Google thought this all the way through. This has the whole “frog/boiling water” trope written all over it: while developers had been putting up with more and more hassle from Google, this particular change appears to be enough to get some developers to jump.
Tactically, the Play Store might well shrink in size over the next 60 days, as developers pull apps from the store, or Google kicks them out for failing to abide by the revised terms. If I’m Apple, I’m hoping that some independent service reports such an event, then using my press contacts to make sure the tech media trumpets how Android developers are leaving in droves.
Strategically, though, I expect to see several things arise in the coming years:
More emphasis on agents: There should be a rise in firms that will serve as agents for app developers. These agents would license apps from developers and sell those apps on the Play Store and elsewhere, in exchange for a cut of the proceeds. These agents, in turn, would provide the physical point-of-presence and front-line SLA handling, delegating any “real” support questions to the developers.
Formation of developer cooperatives: Some agents will likely be scum, if for no other reason than middlemen tend to run the gamut from sensational to scum in other places. Hence, I expect one or more developer cooperatives to form, to help ensure that there is at least one non-scum middleman. These would be registered as businesses or non-profits and would serve as an agent for their members, filling the middleman role while being a bit more transparent and friendly to the membership. Cooperatives with significant traction in specific countries might offer additional member benefits akin to what you might get from other forms of associations, such as group health insurance in the US, with an eye towards helping individual and small business developers. It is possible that existing groups, like the App Developers Alliance, might morph into this role.
Rise in interest in other distribution channels: Individual developers frequently skip other distribution channels (Amazon AppStore for Android, BlackBerry World, direct distribution, etc.) as they are a bit of a headache. Agents will be more interested in those channels, as they are “force multipliers” for their catalog of licensed apps. This in turn should spur development of Play Services replacement frameworks, better instructions for writing apps that can be deployed in multiple channels at once, and so on.
Greater consolidation of developer power: Agents, whether they are independent firms or are developer cooperatives, will wield more power than will the individual developers they represent, just due to sheer mass. Whether that concentration of power will be sufficient to cause Google to start behaving more transparently will depend largely upon…
Legal action: From the EU competition commission to class action suits, I expect Google’s legal team to be busy. Other markets may sue to break the “most-favored-nation” status that the Play Store has on Android devices, attempting to drive Google to create an “app installer” API that developers could support and users could opt into to allow apps to have Play Store-like ability to install and upgrade apps. Greater transparency around apps being kicked out of the Play Store, better support channels from Google to developers, and the like will also be part and parcel of what legal action might try to improve.
Now, my skills at predicting the future are modest at best, which is why I write Android books and do not tell fortunes. However, these seem like probable responses to the recent Play Store moves.
September 26, 2014
Upcoming Conference Presentations: Samsung Developer Conference
I have one more event scheduled for this fall: the Samsung Developer Conference. I will be delivering a couple of presentations there, on optimizing memory and power usage within your apps. These presentations should be on November 14th, though the exact schedule has not yet been announced.
I don’t speak at many vendor-specific events. Where I do, I make sure that I speak on general Android development topics (albeit ones of relevance to developers targeting that vendor’s specific environment). My presentations at the Samsung DevCon are valid for all Android devices, not just the Samsung line.
Also note that I don’t accept speaker fees or other significant compensation for speaking at events. At most, I might ask for the event to pick up the cost of a hotel or flight, but not always, and in particular I am not receiving any expense reimbursement from Samsung for speaking at their event. I am simply serving as a freelance Android developer evangelist, to help Android developers be efficient and effective in their app development.
September 3, 2014
The Busy Coder's Guide to Android Development Version 6.0 Released
Subscribers now have access to the latest release of The Busy Coder’s Guide to Android Development, known as Version 6.0, in all formats. Just log into your Warescription page and download away, or set up an account and subscribe!
This largely completes the Big Book Pivot of 2014, adding Android Studio coverage to all of the core chapters (including the tutorials) and some of the trails.
Along the way, this includes:
Adding build.gradle files for all projects
De-Sherlocking all projects, except those that are specifically demonstrating ActionBarSherlock
Removing the chapter on IntelliJ IDEA and replacing it with material more specific to Android Studio
This book update also:
Adds a chapter on the manifest merger process, with particular emphasis on Gradle for Android and how manifests from different sourcesets plus libraries combine to create the generated manifest for the app itself
Adds a number of small improvements to the core chapters, as part of a more thorough review of that material
Tweaks the tutorials, partly to deal with Android Studio issues, and other minor changes to improve the instructions
Various errata fixes
Updates should now return to their normal every-four-to-six-weeks cycle, emphasizing new APIs, tools, and the like. I am planning on three updates yet in 2014, with Version 6.1 due out in early October.
If you are not a subscriber, you may wish to learn what the Warescription has to offer. The book, plus a year’s updates and other Warescription benefits, costs $45 (credit card/debit card/PayPal) or its equivalent in Bitcoin.
August 27, 2014
Defending Against "Camera Peeking" Attacks
Yesterday, I blogged about a research paper describing various attacks. In yesterday’s post, I covered defending against another activity popping up and masquerading one of your critical activities.
Another attack outlined by the paper is easier for an attacker to use… but is also easier to defend against. The paper’s authors refer to it as the “camera peeking” attack.
A camera, as identified by an instance of android.hardware.Camera, can only be used by one app at a time. The attack is simple:
monitor for when an app that might use the camera for something important comes to the foreground
at that point, start watching for the Camera object to become unavailable
once the Camera is unavailable, then available again, grab the Camera and take a picture, in hopes that the camera is still pointing at the confidential information
The example cited by the paper’s authors is to watch for a banking app taking a photo of a check, to try to take another photo of the check to send to those who might use the information for various types of fraud.
Polling for camera availability is slow, simply because the primary way to see if the camera is available is to open() it, and that takes hundreds of milliseconds. The paper’s specific technique helped to minimize the polling, by knowing when the right activity was in the foreground and therefore the camera was probably already in use. Then, it would be a matter of polling until the camera is available again and taking a picture. Even without the paper’s specific attack techniques, this general attack is possible, and it would not surprise me if there are more efficient ways to see if the camera is in use.
On the other hand, the defense is simple: if your app is taking pictures, and those pictures may be of sensitive documents, ask the user to point the camera somewhere else before you release the Camera object. So long as you have exclusive control over the camera, nothing else can use it, including any attackers.
A sophisticated implementation of this might use image-recognition techniques to see, based upon preview frames plus the taken picture, if the camera is pointing somewhere else. For example, a banking app offering check-scanning might determine if the dominant color in the camera field significantly changes, as that would suggest that the camera is no longer pointed at a check, since checks are typically fairly monochromatic.
Or, just ask the user to point the camera somewhere else, then release the Camera object after some random number of seconds.
General-purpose camera apps might offer an “enhanced security” mode that does this sort of thing, but having that on by default might annoy the user trying to take pictures at the zoo, or at a sporting event. However, document-scanning apps might want to have this mode on by default, and check-scanning apps might simply always use this mode.



