Two Part Question:
How do I do this for a mostly offline app (high level)?
Is it against policy or an expected / common practice?
The app in question, does not specifically require internet / store access to run. It is a free app, but requires in-app purchases to be useful.
Reasoning:
Basically, I do not want users on a version of the app that is too far out of date (say more than 2 or 3 versions, date dependent or both). The reasons are: The app will have regular reference material updates. I am also concerned that if security exploits are discovered, I have the ability to force the versions with a known exploit out of service. Is this a common practice to enforce version control on a mostly offline app and what is the high level model for doing this? Is it even an acceptable practice for Google Play Apps or is it on the fringe of Google's policies?
This is reasonably common practice, and not against policy. It is less common with mostly offline apps. It is most common games with a significant server component, as it is a hard maintenance burden to keep a server up to date so it works with all previous versions of the app. It does irritate users, especially ones who are often offline, and don't like the time or cost to download updates, so you may get more uninstalls.
As far as your first question, in a mostly offline app there are two good designs
The first design is time/date based. If you know your app has release cycles of a new version roughly every month say, have the app stop working after 3 months. This puts a ceiling on how old the app can be. This is easiest to code, and works best for completely offline users.
The second option is:
Make your app phone home to a server to check the required version whenever it is online.
Make the app check how long it has been since it has phoned home, and refuse to work after a certain length of time has elapsed (say a week)
For even better user experience, display to the user how long they have before they need to go online (Similar to Spotify offline mode, if you have ever used that)
This second option lets the user know exactly what is going on. In the case of a really bad security flaw, it also allows you to force an update more quickly. It is slightly harder to code, but not that difficult.
You can have an API which will check the app current version and if it's older than the latest version on the store you can enable a force update dialog asking the user to download the latest release from the store. This usually happens on the splash screen when the user opens the app.
Related
Some background: over 10 years ago, I published a few apps to the Play Store (or, Android Store as IIRC it was called at the time). They were used to help navigate the London Underground. These were live for about a year or two until their functionality was superceded by modern alternatives (basically, when Google added its transit layer to Maps). I unpublished them at that time (circa 2012) and basically forgot about them completely.
Fast forward 10 years, Google are now asking me to fill out a bunch of data safety and privacy forms. I have done so in the hope that they stop nagging me, however one of the sections I have to fill out relates to "Sensitive permissions / APIs" - specifically, fine location access. At the time, one of the apps requested the user's location (possibly in the background; I don't recall) and used it to locally render a dot on a Map activity to show where they were, and also to work out where their nearest station was. This data was never sent off-device. This was obviously targeting a very old version of Android (latest it ran on was probably ICS or Jelly Bean).
It appears that I can just state in the form that the app targets a version older than Pie and doesn't meet the location requirements, but would that then trigger a requirement that I need to provide a new APK with a fix? I'm not even sure if I still have the original source code.
Does any of this even matter if I never intend to make the apps available again (or, based on this experience, ever publish anything else to the Play Store)?
Ideally, I'd like to delete both apps entirely, but from what I gather Google have intentionally made this impossible.
You probably can ignore these, as long as they don't state that it will suspend your account. Choose the option that you need to declare those data collection, and simply declare everything.
I was just wondering the same when try to update from PlayStore.
Generally, say for Windows, when it is updated, downloads the files and patches them. From size perspective, these are significantly small compared to its setup which is around 3.5 GB.
So why its not applicable for ANDROID apps? E.g. any update to WhatsApp is almost equivalent to its original setup file (~18 MB).
Although Play Store calls them updates, you actually download the whole Android app again. In a way, it's still an update because you do actually upgrade to a newer apk version but not quite the way you would've liked. It's taxing on your bandwidth but it's easy.
However, your app's settings (shared preferences) and data (SQLite databases or custom files) survive this update/install process which won't be the case if you manually uninstall & install the app's new version again.
In cases where the app's database schema has evolved between the two versions, Android notifies the app on startup that it wasn't a fresh install by calling a life cycle method onUpgrade() where the app has a chance to upgrade its data left over by the previous version.
When you compare this with Windows, both the OS and the update server are from Microsoft and they must have worked together to figure out what needs to be pushed (.dll, .ini, .sys etc.), update bundle's format/compression and security implications (some sort of encryption to prevent malware injection by any one intercepting the traffic).
No such standard update mechanism has been made available by Google for the Play Store see update and I believe so is the case with every other app store. Obviously, the developers can't roll out one on their own since the updates are handled by Google both at the device and server side.
But, the developers are certainly not unhappy about it. It's much more convenient to test the new apk, see it working and uploading the same rather than fiddling with what changes to push and breaking the app if you miss something. The bandwidth is cheap anyway.
I've just recently discovered that at Google I/O 2012 Google announced that they were working on a Smart Updates technology using some delta encoding algorithm. The idea was to compute the DIFF between two APKs (sort of like we do for text between two source code files), create a patch on the server-side and only send that over the wire.
This feature went live on Play Store later that year as reported by AndroidPolice and TechCrunch.
Developers, Google said at I/O, won’t have to do anything to enable
this feature and according to the folks over at Android Police, this
feature quietly went live late last night or early this morning.
You can see it in action in this video. Notice how the apps start installing once the progress bar hits just 40-50%. This is absolutely brilliant because not only this saves Google terabytes of bandwidth, its pure server-side approach means developers don't have to fiddle with anything. Perhaps, that's the reason it finds no mention on the android developers site and so takes time to get discovered.
With that said, my personal experience seems to coincide with yours. I see most of my app updates download almost the whole of the app. Maybe it's because I don't download very frequently. It's not unusual for me to skip several minor revisions and perhaps the app changes far too much to derive any size benefits out of the patch generated.
There is nothing like an "update" for an Android app. It is always a full app. It is called update, because it is a new version of the app currently installed in a device.
But when it is an "update" the whole app is not fully downloaded. For many years the Google Play downloads just parts of the app and patches the currently installed app with the difference. So in the case of 20MiB the Google Play can download just few megabytes to reconsctruct the new version in a phone. Google calls is Smart App Updates or something like that.
Is there an elegant way to handle end-of-life scenarios for an app on Google Play?
Suppose I have an app ("A"), and this app is being superseded by a suite ("S") that has all the functionality of that old app. In other words, S will absorb A. I think it makes sense, from a business point of view, to:
Prevent new sales of A, directing all new sales to S.
Keep supporting A with updates and fixes.
I want to know if it's technically possible. Please disregard SDK requirements and user experience and other OT issues, as I'm not considering with that yet (besides, with this I can always gift old customers in case I want to).
Right now, the only way I see to achieve this is to set the price of A so high that users won't buy it. That way I can keep providing updates without increasing its user base (and thus time spent on support etc.).
One very simple approach would be to simply upgrade your old app to have the new functionality of your suite app, and then rename and re-price the "old" app (which is now your suite) to reflect its new status (e.g., add the word "suite" onto the name). So far as Google Play is concerned, it will still be the same app, only "better." You will keep all the credibility gained from installs of the old app (by essentially upgrading the old app). Your old users will be happy because (as you've described it) they will have all of the old app's functionality, plus some additional functionality.
When I say "upgrade," that doesn't mean that you have to start with the old app's code base; you can just create an entirely new project and APK, so long as you use the same package name and upload it to the old app's location on the Google Play store, and so long as functionally it covers all of the bases expected by your existing user base.
Based on your description, I really can't see the down side of this. It may be that by conceiving of this feature superset as a new product rather than as an update you've created a problem that need not exist.
Currently, Google provides no such functionality. Your best route would be to add functionality to app A that allows it to update using your own private servers, then unpublish the app from the market. It really is quite that Google provides extremely limited functionality in the Dev Console. Instead of taxes, they should've added app coupons and private app listings. Oh Google, "driving sales" as always.
I have seen so many threads on creating a time bound trial versions for an android apps but none of them seems to fulfill my purpose.
Few days back i Launched the paid version of my app and now I want to come up with trial version which i dont want to be crippled from any side. So i want to have a time bound limitation on the trial version. I have created a different Package name for the same. Earlier I was using LVL and now also I am using the same except that i created new license library and changed the
setValidityTimestamp(extras.get("VT"));
to
setValidityTimestamp(String.valueOf(System.currentTimeMillis() + (5* MILLIS_PER_MINUTE))); in ServerManagedPolicy.
so that i can test if trial version works for 5 mins and then give me the license error. I published it on the app store , downloaded it and then found that it was still working beyond 5 mins. Now i have unpublished it. Can someone help me in creating the better time bound application which a user can run for a week (say). Besides he should not be able to uninstall and re-install it and then again use it permanently. I know if i can write the info to some external file but again the file can be deleted from sd card and application can be made accesible to the user free for lifetime.
Regards
Pankaj
Within the current capabilities of LVL, and the degree of user control over your average handset, there is currently NO way to do this without a server-side component. Once your app is uninstalled all traces (except, as you pointed out, files you may write to the SD card, which are user-visible) are removed, so the only way to check for an uninstall/re-install is to generate a consistent, device-specific identifier and check with a server component that will either reject this as a re-install or accept it as a new time trial. Even this can possibly be spoofed by a dedicated customer (depending on the server-side component behavior), so you would need to engineer your software so that your server-side component is a necessary part of the process (i.e. it isn't just a license check, it is actually part of the application's functionality).
If you come up with something that works I'd love to hear about it, but I'd say you're out of luck.
#Femi is right, you need a server side component to make always work. What I tend to do is publish only a free version, and teh user buys the full version as in-app-purchase. The IAP server is your server side check if the use purchased the upgrade or not. You can store a pref on first use to know when the user started using the app. If users uninstall and install again your app, they get a new trail period, but this is annoying, and few will do it to save a few bucks. If you add a message in the app where you ask user nicely to upgrade, or have ads that are removed once you upgrade, it is a good enough solution.
Is there any reason to forward lock a free app? If the user copies the app from the phone, is it protected in any way from decompilation, etc?
By "forward lock" I'm assuming you mean "prevent a user from forwarding the app to another person", and by "free" I'm assuming you mean "available for zero money". If that is the case, then yes, there are reasons to do so. First and foremost, this will ensure that the app is only available from a single source and that users don't have to worry about whether the app is genuine or a tampered version. It is not unheard of for someone to take a freely available app, add their own ads or malicious code, and re-distribute the app as if it was the original version. Unsuspecting users end up running adware/malware without knowing it. This also (unfairly) gives the original app a bad reputation. Therefore, many free apps prevent forwarding/copying for the sole reason of ensuring authenticity.
Also, just because an app does not cost anything doesn't mean that there aren't trademarked/copyrighted materials (or other types of protected intellectual property) inside it that aren't legally copy-able. Being able to easily copy or dis-assemble the app could open the creator to legal issues (especially if they licensed some of their content from a third party), so a free app isn't necessarily able to be taken apart. That being said, binary code is always viewable in a hex editor, and anything can be dis-assembled if you have the time and patience...
No, because the implementation that the Android Market offers is multiply broken:
It does not stop piracy, as people with rooted phones can still go in and grab the APKs, as they do all the time (and, AFAIK, it does nothing to stop decompilation)
Using Android Market copy protection has a tendency to keep your app out of the Market on occasion, such as when new devices are being rolled out
If you want copy protection, that's your call, but use something other than the one supplied by the Android Market.
While consumers bypassing the marketplace and copying a free app will obviously not directly affect profits, keeping track of the number of people using your app can be very important in terms of building the reputation both of the app itself and of your company / you as an indie developer.
If your app communicates with a server or central database as part of its natural functionality, then usage tracking can be implemented through that channel. But if not, then download information on the marketplace is the next best way to get a rough estimate of its popularity.
As for security, I'm not aware of any way forward locking directly makes your app more secure, preventing illicit copying could certainly serve to discourage untoward manipulation of the package files.
No, but it isn't particularly protected either way - it's possible to copy all the data off most android phones regardless of what the application developer would prefer, and once you have the bytes you can disassemble to your hearts' content. (Whether any of that is likely to happen to your particular application is an entirely different question).
There are other reasons to lock it - more accurate counting of userbase, etc. - but they're generally not worth the impact to the overall user experience. If your app phones home occasionally to count installed handsets, that's a much better plan than trying to enforce some way to trust the Marketplace count.
There's no way to protect anything from decompilation. Except if there's no platform that can run it.
But you can make it harder, with obfuscation and stuff.
But fo a free app it is probably not worth the effort.