I have an app which requires its database to be replaced entirely whenever changes are made to the source data. I would like to have this update functionality built into the app, so that the app itself does not need to be updated (ie. re: Play Store), only the database file within it. I am considering hosting/updating the database file (I'm using SQLite) on GitHub for direct download via my application.
The information in the database is not sensitive so I am not worried about security. Additionally, these updates would happen relatively infrequently on a client's device -- 1 to 2 times a year at most.
Bearing in mind I'd like to keep this as free and simple as possible - is this an advisable approach?
Some free applications can often be upgraded to paid premium versions. Is there a known packaging pattern so that the paid app replaces the free apps, and therefore gets all data the free may have stored ?
I understand that since app is identified by its unique fully qualified name this is impossible for an app to see data from another, but I kinda recall already seeing this. Or does it mean that I have to consider the two apps as completely distinct, and foresee an export/import feature mechanism ?
(this question is not related to the actual development of those two flavours, which can be achieved in many ways, but rather to the way app should be packaged)
Is there a known packaging pattern so that the paid app replaces the free apps, and therefore gets all data the free may have stored ?
No, the package names must be unique. Thus, one app does not "replace" another app and gets its data.
Or does it mean that I have to consider the two apps as completely distinct, and foresee an export/import feature mechanism ?
Yes, two apps are distinct. However, they can still exchange data.
These are common methods:
Publish one (free) app which contains all functionality but only has the free functionality enabled by default. Publish an additional (paid) app which serves as an unlocker. Your free app can check if the unlocker is installed and enabled the paid functionality accordingly. It is recommended to check the package signature of the unlocker app, e.g., as described in the answers here.
Similar to above but use in-app purchases in the free app instead of an additional unlocker app.
Publish both a free and paid app as self-contained apps. You can implement a ContentProvider to transfer data from the free to the paid app. Of course you can implement other export/import methods as well. However, using a ContentProvider with permissions makes it easy to automatically and securely copy the data, e.g., when the paid app is started for the first time.
We are developing an android app and we want to make two versions, pro and free. The problem is that our apps use a database which we want to be available for both apps.Is it possible?
I mean, the client downloads the free app, and he uses it. Then he decides to buy the pro version, would it be posible to pass the data from free version to pro version?
Thanks
Two different apps wont be sandboxed from each other and can use the same database provided that they are signed with the same private key and have the same sharedUserId. No need to store the database on a shared folder which might cause breach of sensitive data.
Add:
android:sharedUserId="com.yourprogram"
inside manifest tag in your manifest files and sign both apks with same key. For details:
http://developer.android.com/guide/topics/manifest/manifest-element.html
you can use a content provider if you want
http://developer.android.com/guide/topics/providers/content-providers.html
We have an application, that can itself be downloaded for free, but works with paid, licensed data. Some users buy particular version of the data while others buy right to use latest data for some period of time. Now as the application evolves, it eventually stops supporting data older than some date. So obviously users who have those data licensed, but no license for newer data don't want to upgrade. But if we publish new version on the market, they would see it and if they upgrade, they will have trouble downgrading back to version that actually works for them.
So can we somehow instruct the market application not to offer upgrades for particular user or some hack to achieve that end?
We currently use mechanism completely independent on the market to sell and check licenses for the data, but could consider different mechanism (like the android in-app billing support or something) if it could help solving the problem.
The way I see it, you have two options to "disable" upgrades:
Use a different signing key - this will prevent installation without removal of the previous app, but upgrade notifications will still appear (I think)
Use a different package name - this will prevent upgrades since it is a completely separate app so far as the market is concerned, and also has the side-effect that old versions are still available for those users who are licensed for that data version.
The second option may be a better match since you can roll out upgrades if necessary for bug-fixes, but can also ensure that wholly new versions are not detected as an upgrade.
EDIT:
Totally agree that the above options are cumbersome and don't really solve the issue as-is.
As you mentioned however, you could use in-app billing, but given the nature of your requirements, you'd have to use unmanaged purchases which means you'll need some infrastructure to manage authorising purchases and preventing people from buying the same license too many times.
I'm guessing you've already got much of that infrastructure in place to handle distribution of the data though.
Can the data not contain a "format version" number at the start of the file?
Then you can program the app to read version 1 files, a new app needs more fields on the data source, so you create version 2 data, which adds extra fields, version 1 app see's the data needs a newer app, so tells the user to upgrade.
Version 2 app should know how to read version 1 files and version 2 files (perhaps create a reader Interface and implement loaders for the different versions of files.)
You'll have to handle the missing data in v1 / old files in the loader in the v2 app. The loading of older files is the nicest way for the customer as the app shouldn't just stop working after an upgrade.
If you keep a copy of each format's data you can quickly run tests to check the new version's loader can load each file correctly, plus if the app has a bug in there you won't have to fix several app versions, just the current one.
Ok.. I saw one of the posters suggest you have a way to read the old data.
First that's likely the best option but as you say your apps a mess.
You should invest some time in migrating your data reading/writing to an abstraction layer. The pain your having on a (likely less than 4 year old project) is only going to get worse.
Okay.. so here's how I've dealt with it in long lived apps..
Create a migration path.. Create a new class call Migrate.
In it have several functions to convert the version of the file from n to n-1
convert_1_to_2(fileName){check the version and upgrade data.)
convert_2_to_3(fileName)...
I suspect you have your old code, and you could write a method to convert one bit of data to the next..
When you add new features to the data, then you create a new convert.. No knowledge of the earlier ones would be needed, and everything would be nice and self contained.
You could even have sub migrations, so part way along the dev cycle, you could have convert_3a_to_3b.
Now... you could archive the original version of the data in case the user wants to go back.
If the data is accessed remotely, you could have the app include the version, or some hash of itself, when requesting it. And then filter the data provided based upon that information.
If you already have in-app purchasing and the infrastructure to support it, just poll for new data when the app is upgraded. If the user has purchased the license for current data, provide it. Otherwise just continue using the existing data.
I came up with an option that market will contain an installer that will download and install another .apk containing the core of the application locally.
We already have an installer dialog in the application for downloading the data and user has to enter it when using the application for the first time, so it can be made responsible for the application core too.
You can not definitely prevent users to download the new version of a app they already have. You can either register a new app or check the version and user data programatically.
I have nearly completed my application and about to upload it into Android Appstore. I need to divide demo and paid versions - one is free with limited capabilities, another one - paid with full functionality. The question is: how to implement it - the only idea which I have in my mind is following:
Upload 2 independent applications placed on different packages. But in this case there's one obstacle: let say user installed demo application packaged as my.foo.demo then user decided to buy full version which will be installed in package my.foo.paid. In this case I need to provide user with ability to transfer user files/data/preferences from package my.foo.demo to my.foo.paid. Wow, but it's not very simple task (keeping in mind Android's security model)
Probably there's another approach? Any ideas?
The easiest way would be to upload two independent APKs. There is a way to have a user download a free version, and then download a "key" application that unlocks the paid functionality. That can lead to lots of user confusion since sometimes they will download the "key" application and not the base application. So if you can upload two different versions, that will eliminate that hassle (but means you have to maintain two versions).
So now to answer your question about sharing the data. The simplest way would be to have a content provider for your data and just export that to the paid version. Alternatively, you can look into the sharedUserId attribute in the application's manifest. This will allow you to run in the same process and access the same files.