Two Key Things to Check Before Publishing Your Android App
Let’s say you’ve recently launched your Android app, Face-tagram. It’s a social network devoted solely to selfies, and it’s quickly gaining popularity.
One day, the project manager walks in and says, “Great job with Face-tagram, but we need another app for our advertisers to add stickers to peoples faces.” You say, “That’s a weird idea, but ok,” and get to work. Shortly after the PM walks away, you begin to research ways of sharing information between the new advertiser app and the customer-facing app, so that users can share OAuth/accounts between both apps on the device.
Your stomach starts to sink, and you feel lightheaded (you should probably go for a walk honestly), as you find out that you actually can’t do this because you forgot to add just one little thing to the manifest before releasing Face-tagram, and will need to spend a lot of time coming up with a hacky workaround solution.
Unfortunately, there are a few things you just can’t change or add to your Android app after it’s been released. This post is about two of the most common ones that developers overlook, and why checking now, before you launch, might save lots of headaches, time, and 💰 down the road.
Do you have a sharedUserId?
A sharedUserId is for sharing data, processes, and other things such as access to AccountManager between two or more applications. This might seem like something that’s kind of useless for most applications, but it’s actually very common and odds are if your app is moderately successful you’re likely to want to use it at some point. For example, some companies will end up building more than one app for their product(s), and need to share OAuth authentication and/or user information between them using AccountManager: there’s Facebook with Messenger, or Flow Tasks with Flow Chat, to name a couple.
If your app doesn’t have a sharedUserId you have a lot to lose. Not adding one to your app before launching to Google Play (or any other distribution channel) will make it impossible to add one at any point in the future through an update, since adding after an initial install will make your applications data (under /data/data/<package_name>/) inaccessible. The comments on this issue highlight just how frustrating this can be. You should also ideally have a sharedUserLabel as well which isn’t necessary, but I mention it because it nicely labels your processes.
Note: sharedUserId is defined in the Manifest of each app, and in order for it to work between both the id‘s must be the same.
So, why does trying to add this through an update break your app? In a nutshell, when you add a sharedUserId to your application it changes the UID associated with your package name on the device (same goes for removing one), which in turn causes application data to be inaccessible. This is why you can’t add it in an update, but can add it initially. Of course, you could update your app through Google Play, but all of your users would have to manually uninstall & re-install the app for data to be accessible again. Fun!
To prevent any issues in the future you should definitely add one to your app before launching—just in case. If not for you, then for any developers who might work on expanding the app down the road. There are some nuances to this though: just like an app’s package name it must be unique to your application, it should also ideally be formatted to match package name conventions so that you’ll be able to extend it to different variants (you can do this simply using strings, and Gradle flavors). Annnnd this brings us to the next topic…
Do you have a smart package name?
I see package names all the time that have failed the apps they represent: names that are too long, names that are too complex, names that aren’t consistent with Java conventions. Package names like com.emailaddress.appname or com.appname.developername aren’t ideal for development for a few reasons. It’s high-time someone ranted about this a bit, so here we go!
Finding the 🔑🔑🔑 to package name success 👌:
- Start with your developer name, company URL, or company name (like if Uber’s URL was uberrides.com you’d probably want to just use “uber”), prefixed with your TLD (don’t use your email address! I’m guilty of this). For example, with Flow, we use com.getflow as a base, Wikipedia uses org.wikipedia, and Medium (which has a great package name) uses com.medium as its base.
- Next, append one word that describes your app. If you’re building a music streaming service, something like listen, music, or play might work. For example the streaming service SoundHound could be com.soundhound.listen… their actual package name right now is com.melodis.midomiMusicIdentifier.freemium. Spotify, on the other hand has a great package name: com.spotify.music.
- You will probably grow as a company, and support other platforms. Google Play Music uses com.google.android.music. Delimiting platform before your app’s descriptive name can be a good idea.
- Consider that you’ll have internal beta testing, as well as multiple debug and release variants. Most software companies will have at least staging variants on both their API’s and applications for internal use. Try to make sure that your package names apply these prefixes and suffixes in a logical way. For example, an internal testing release variant could be formatted like com.companyname.descriptivename.staging. To give you a real world example: with Flow Tasks, we use com.getflow.tasks.staging.
- For an app where you want to be able to have both production and debug builds on your device at the same time, you could do something with a sneaky debug variant prefix like debug.com.companyname.descriptivename. This would make it so you don’t have to constantly uninstall and reinstall just to run your release builds on the same device. Breaking java package conventions just for debug builds isn’t a huge deal all things considered. You could of course just tack .debug on to the end, but that could be less obvious in the logcat, either approach is valid — it’s up to your personal preference.
Of course, you can’t change package names if you’ve inherited an app, but when you’re close to publishing it’s worth it to plan out some solid naming conventions so they can stand the test of time 🕓.
Thanks for reading! Hopefully this post sheds some light on why these things are important and how they can make a huge difference over the lifetime of your app.