At this year’s I/O, Google unveiled the next version of Android, codename “M”. This release focuses on incremental improvements, new APIs and refining the user interface.
Having experience with both Android and iOS SDKs, I can draw some parallels between them, to the benefit of my friends and colleagues working on Apple platforms.
One of the aspects that was covered is the new permission system, which is clearly inspired by iOS. Gone is the “permission wall” shown when users tap “Install” in the Play Store. The system will ask users to either grant or deny access to privileged functionality on the spot.
Each application gets, as soon as it is installed, network access and is allowed to read and write files in its own container. Additional permissions are requested and, eventually, granted as soon as the application needs them, with the operating system in charge to present a confirmation prompt to the user. This is quite similar to how iOS application have been working since the dawn of the AppStore.
What’s interesting is that the underlying mechanism is still the old, broad, and granular set of permissions we’ve been accustomed to since the first version of Android. What’s changed is just the user experience and a couple of new APIs.
Developers, in fact, still have to declare all permissions they need in
these permissions are now clustered into “logical groups” to make them easier to understand for end
users. For example the old
WRITE_CALENDAR permissions are presented to the
user as a single prompt to access the whole calendar. From an API perspective, you are still
requesting access to
WRITE_CALENDAR (or both) but, once the user grants or denies
a permission coming from a logical group, all permissions in that group are either granted or denied
at the same time.
This is, again, strikingly similar to iOS. When I request access to the address book, I’m given both read and write access simultaneously. I don’t have to request them separately.
Power users will be disappointed to know that the settings screen will only allow to toggle groups, not individual permissions. As a first iteration, though, this is good enough and still a vast improvement over the “wall of permissions” users have endured until now.
Developers must opt-in to the new scheme by telling the system that they target “M” by changing a
couple of lines in their
build.gradle file in a manner quite similar to how the “Deployment
Target” configuration parameter works in iOS.
Opting in to the new scheme comes with a price: applications now must degrade gracefully in case the permission is being denied and they don’t have to crash when the permission is toggled from the settings screen at a later date. Developers also should ponder whether it’s better to ask for all permissions when the app is first launched 1 or wait until the permission is effectively needed.
Old applications that target a pre-M version of Android will get the old “wall of permissions” at install time but users will still be able to toggle each permission group after the application has been installed. The settings screen will, in this case, show a warning telling users that legacy applications might misbehave when something is turned off, since old applications assume that all permissions were granted them by the virtue they are installed and running on a device. Once a permission group is disabled, the system supplies fake data to the application in the form of e.g. an empty address book, unavailable location fixes, and so on. The system won’t raise security exceptions.
Also, whenever a permission is toggled from the settings page, the application process is killed. This frees developers from having to think about permissions changing while an application is performing a long-running operation.
From a developer standpoint the API is really simple: you check if you have a permission with
Context.checkSelfPermission() and prompt the user with
Activity.requestPermissions() and then
handle the response in the
onRequestPermissionsResult() method in your activities.
One difference with iOS is that developers can’t provide an explanation to be injected in the system UI. Developers either have to “double-prompt” 2 or show a justification prompt after the user has denied a particular permission, then ask again. This last method seems to be the preferred one. Beware though, after the first prompt users are shown a checkbox to hush all future requests. It is unclear whether all dialogs or only those coming from a specific permission group will be hidden.
Unlike iOS it is also possible to cluster multiple permission requests together. The system UI will include a progress indicator in the lower left corner displaying how many more dialogs will be shown.
In some cases permission alerts can be skipped altogether by firing a system intent, delegating the action to a component for which the user might already have granted all permissions, and this is really what most developers should attempt to do before taking matter to themselves and use privileged APIs.
The new permission model goes definitely in the right direction and I can’t wait to see devices with Android M hitting the market, bringing users a refined user experience alongside all other new features and improvements Android has to offer such as Doze and Android Pay.
Hangouts requests access to the microphone, contacts and SMS at launch because these are needed to provide essential functions in the application. Google Keep instead requests access to the microphone when you first tap the button to record a voice memo. ↩
Double-prompting is the practice of showing an application-managed prompt before the one handled by the system. ↩
When many people (with “many” being >= 2) work on a project it is important to lay down rules that all developers ought to follow lest everyone starts doing whatever the heck passes their mind.
The first, and probably most important rule, is to force everyone to write in a single, uniform, style so that code looks like it was written by a single person. Software developers spend most of their time reading each other’s code after all.
This is how “The Style Guide” is born.
The pinnacle of software engineering civilization is an endless stream of words written on a wiki somewhere, by someone who is no longer working at the company. A text nobody reads nor follows because, let’s be honest for a moment here, when I’m solving a problem I don’t know nor care about your whitespace rules. I just want to bang some code on the keyboard to fix the problem at hand and then call it a day. Fixing style problems and cleaning up code usually comes at a later phase, if at all.
Don’t forget the political problem of “why do I have to follow Bob’s advice on this? He’s an asshole, he doesn’t get programming. I’ll get the last word on this one.”, which is a surefire way to waste everybody’s time and money fighting office politics. So, bonus points if conventions come from outside, so that any complaint can be immediately choked to death with a generic “they (the language designers) want that, not my fault”.
The point is, writing a style guide just for your project or company is a waste of time, unless you want to exercise your technical writing chops, in private.
Design automated tools and community-wide style guides instead, so that all code in the world written in a particular programming language looks like it was authored by the same person.
Go, however, is the role model to follow here since, for the most part, doesn’t even have a lengthy style guide. It has automated tools to fix mechanical style violations and others to warn about code smells 1. Integrations with most editors are readily available for built-in and 3rd party tools alike for maximum productivity. From day one. All of this is possible because Go includes libraries to parse source code right into the standard library, which makes it really easy to work on the AST and manipulate source code (take that, C++ 2).
If you are designing a new programming language, or working on an emerging one, take care to ship version 1.0 with a complete style guide and tools to parse, manipulate, validate, and fix source code. Every minute we don’t have to spend bike-shedding and following tedious issues that can be automated is a minute we can spend writing awesome code in your programming language. It’s in your best interest to make us, the users, happy and productive.
As for me, I will refrain from using new programming languages that don’t provide many of the facilities that I’ve come to expect from Go, Python, Java, and C/C++ (to a lesser extent) 3.
Some of them are shipped with the compiler and all others can be easily installed with
go get. ↩
C++ is famously the most difficult programming language to parse, which explains why, until clang appeared, many IDEs (with the exception of Visual Studio) couldn’t offer decent auto-complete support. ↩
I’m talking to you, Rust. ↩
Earlier last year I went all-in to the Apple ecosystem after a 10 year-long relationship with Linux and a four-and-a-half one with Android.
One thing that struck me the most was how Apple is handling its developer community and how inefficient some processes appear on the outside.
Apple’s bug reporting tool suffers from one critical flaw: each ticket is private between me and Apple. Because of this, I don’t know if someone else encountered the problem I’m about to report.
Reports are confidential because they may contain sensitive data, like pieces of proprietary code.
All of this means that I often report bugs that will be closed as duplicates. Rumours say that Apple internally uses this “duplicates count” to prioritise issues that need to be fixed.
I usually spend about fifteen to thirty minutes on each issue I report to make sure it is reproducible with step by step instructions, screenshots or screen recordings. Then someone at Apple has to waste some more time closing the influx of duplicate bug reports.
The whole process is terribly inefficient.
Many bug reports don’t contain private information. I would welcome a checkbox that gives me the ability to make the bug report public and searchable.
Most of the time I’m not the first experiencing an issue. I would rather find the original bug report and participate to the conversation with Apple engineers. Also, a simple way to help with prioritisation would be a mechanism similar to “stars” on Google Code’s issue tracker.
Additionally, since I don’t get notifications when the original issue has changed state, each time a new product release comes out, I have to go through these steps:
- Check all bugs in “Open” and “Closed” categories and try to reproduce them in the latest release.
- If it is still present, then I add a comment like “Still present in iOS 8.2”. If it is fixed I add a comment like “Fixed in OS X 10.10.2” and then click the “Hide” button to move it to the “Hidden” category. Adding a comment is useful since it is shown in the bug list on the left.
Now multiply this process for each developer working with Apple products with enough time and patience to open bug reports. Think about all the wasted manpower at Apple to read incoming bug reports and mark them as duplicates.
- Add a checkbox to make bug reports public and searchable by other users.
- Add a vote system so that developers can help prioritise bug reports, in a manner similar to “stars” on Google Code.
- When I report an issue which is then closed as duplicate, send me notifications when the original bug report changes state.
Unified Developer Subscription
The Watch, along with Continuity and Handoff on iOS and OS X, contributes to create experiences spanning multiple devices.
We expect developers to create applications that work across multiple screen sizes and environments.
Developers, however, are still split between two camps: iOS/Watch and OS X, with separate subscriptions and developer portals.
Many iOS developers, myself included, would love to create products encompassing all of the Apple ecosystem but the thought of having to activate yet another yearly subscription is often off-putting.
Unifying both the iOS and OS X ecosystem under a single 99$/yr subscription would encourage the large pool of iOS developers to start developing applications for the Mac App Store, too, stopping the chronic lack of applications on that front.
Microsoft is doing it, with improved unification expected this year, and Google has always used a one-time $25 for Android and a one-time $5 fee on the Chrome Web Store.
There’s no excuse to still have a fragmented ecosystem.