I'm evaluating different ways to build and market an Android app using the freemium model. I would like to restrict the functionality of the app in one or more ways to encourage purchases of the premium version.
Are there proven, secure coding techniques for limiting functionality such as:
1) maximum number of uses per day,
2) maximum number of calls to a key method per day (or other time period),
3) app is disabled after a period of usage (e.g. 1 month) and cannot be circumvented through simple uninstall/re-install.
-> One thought is to hash a value that is stored somewhere in app or supporting files (e.g. resource, manifest) that tracks usage and cannot be simply overwritten to circumvent restrictions.
-> A more complex approach would be registering the install at a web service and then have the web service enable/disable operation based on tracking data, however, if the web-service goes down, this could disable this function (e.g. default to operational would allow the app to run if the service is not available).
Number 1 and 2 can be easily done, but can be circumvented if the user changes the system time on the device (hello Candy Crush). To prevent that you'd need to register to receive ACTION_TIME_CHANGED and perhaps ACTION_TIMEZONE_CHANGED and figure out how to react accordingly. Alternatively, you could obtain time from an external source, but that would increase the network needs of your app.
When an app is uninstalled, all of its internal files are deleted, so the first part of number 3 won't work. You could put the that flag file in external storage, but a minimally savvy user could easily find and delete it, unless you were crafty with the name and or permissions. But that's not really playing fair since the file would exist long after a user decided they didn't want your app anymore. The only reliable way to handle number 3 and have it survive reinstalls is to do as you suggested and use some sort of web based registration process.
A far better approach is probably to use Google Play Licensing. It allows try-before-you-buy and other approaches.
Related
I would like to check the user activity an app is tracking. The Audible app specifically.
e.g. does it log every tap? Does it log how long each session is etc.
Thank you.
This is not possible, no. Computers are not capable of this sort of sophisticated reasoning about a program's possible behaviors (see, for example, the Halting Problem, which shows that an algorithm can't even determine if a given program will finish running). Only a human reverse-engineering the software by hand could possibly make this determination, which would be a very time-consuming process for an app of even moderate complexity.
Before i ask my question i will first explain some background information.
Our company is developing an app for iOS and Android. Our customers can decide to use our app (branded) or integrate our functionality into their app. As our app has some complex algorithms and communication protocols on-board. For this reason we want to provide a kind of SDK for our costumers who wants to integrate instead of using our app.
As we use BLE, NFC and GPS, we decided to make our own apps native. The issue is that many of our customers already have an app which will be a hybrid app in the most cases. So "just" making an SDK for all platforms is almost impossible, not only to build but even more to maintain.
Another important thing to keep in mind is that we want avoid that our customers need to understand our complete communication process, even stronger we won't give our algorithms or communication protocols to others because this is what makes our app/product unique at this moment.
So now the concrete question. Is it possible to provide our functionality as a kind of API so other apps can use the functionality of our app like a kind of API? This means that our app needs to be installed also on the end users smartphone but they don't need to use it individually. The idea is that the app of our customer communicates with our app like an API, our app does the communication with our hardware and gives back the result to the app of our customer. Note that user of the app should not see our app in foreground. (I have the idea from some games who requires "Play Games")
I know there is a way to exchange data between apps (Inter-App Communication) but can this also be used like kind of API?
Obviously this answer relates to Android only. (You may want to ask a separate question for IOS)
At its most basic, a Content Provider is used to exchange data. However, nothing prevents code being run in the provider host to extract that data.
For example, You can host a Content Provider in your app which when called with specific parameters, performs a number of your complex functions and returns a simple table of data (MatrixCursor) or even just a simple True/False response within that cursor.
You could further simplify the usage of this by creating an Android Library that your customers could import into their own project to make it more friendly and API like by adding methods and functions to the library that then delegated their calls to the Content Provider or even to a Broadcast receiver in your main app which could then respond with its own broadcast.
You could even make use of invisible Activities. i.e Call an activity in your app that has no UI.
Even more preferable would be to create your callable code as a self contained library that your customers could use which would negate the need to talk to separate apps completely.
In my understanding, you need other apps to invoke a particular functionality, say call a web API or open an activity and write something or open a popup dialog and do something.
In android: Yeh, it is possible by BroadcastReciever. you only have to listen to the particular action and perform the functionality.
So the task is, you only have to supply the action.
I have an app which provides in-app purchase to unlock few features. Based on which features are purchased, the app might need to switch layouts. So, the main activity on start makes this check by calling getPurchases(). Since this call is over network so I need to show a loading dialog until I get a response. I can then store this info in memory for the rest of the session.
However, my worry is bad user experience. Every time the app starts the user will be greeted with the loading dialog, which seems bad. Furthermore, if at that moment if the internet is down then the user could be stuck at loading for a really long time (until that times out), and then the app will behave as if he did not make any purchases.
Alternatively I can choose to store the purchase history as flags in Android sqllite DB. So, the app will fetch the details from Google Billing API if that is not already in DB. If the flags are set then the app will skip this check. However, my worry is that users with rooted phones might then be able to simply turn on these flags.
How are fellow developers handling this?
I'm following the android developer training for in-app billing, it doesn't seem like you're following the same documentation, because there doesn't appear to be a getPurchases() method. Nonetheless, you are right to be concerned that network calls have a negative impact on the user experience and this can be avoided by threading. There's no need to right the code yourself, just following the android documentation and take a look at the sample code <<android-sdk>>/extras/google/play_billing/samples/TrivialDrive/src/com/example/android/trivialdrivesample, which will be available once you have installed the necessary packages.
As for your concerns about rooted phones, I suspect they cannot be economically justified, that is, the cost to defend your app will probably be greater than any expected loses due to rooted phones.
I am currently working on an Android project that monitors what applications a user is running and cross-checks the corresponding processes with a whitelist stored internally on the device.
In order to make this work, I need to know what the default or system processes for the device are so I can add them to the whitelist. That being said, I have a few questions I was hoping you might be able to answer:
Is there a way to differentiate between a default/system process that MUST be running, and a process that belongs to an app on the device?
Are there different default/system processes depending on what phone/version of android the user is running?
If so, are those process names available somewhere for developer use? Or is there some other way to obtain them?
If I need to elaborate more please let me know, thanks for the help.
Let's say that you try ActivityManager and getRunningAppProcesses(). Iterate over that array of RunningAppProcessInfo objects and find those with importance of IMPORTANCE_FOREGROUND. If the docs are correct (haven't tried this), there should only be one process that is IMPORTANCE_FOREGROUND -- the one that is truly in the UI foreground.
(services can call a startForeground() method to get foreground priority, but I am guessing they have IMPORTANCE_PERCEPTIBLE)
You could then examine the pkgList of that foreground process and compare that against your whitelist.
However, this breaks down if:
Something pops up asynchronously (alarm clock app, incoming phone call, etc.)
An app that is logically in your whitelist has changes that affect its package name (e.g., developer released a "pro" app that a student paid for, and the whitelist only has the free app)
if the device has multiple visible items (e.g., Samsung's multi-window capabilities), if all visible apps are not IMPORTANCE_FOREGROUND
This at least gets rid of the problem of pure background stuff that the student cannot control, including your "default/system processes".
However, it requires you to continuously poll, which will be a serious detriment to battery life. That, plus the privacy implications, means to me that this app should, at best, only be used for exams, and should be something that the student can install shortly before the exam and remove shortly after the exam.
Well I think my team and I have come up with the best solution so far. After reading the Android Docs, we found that by using ActivityManager.getRunningServices() we can use the constant FLAG_SYSTEM_PROCESS to determine what processes are core system processes. Then all we would do is cross-check that with the total list of running processes to differentiate between them.
So I have read the LVL docs backward and forward, and have it working with my app. I have seen the questions about the response being cached. But it still leaves me wondering, based on some of the wording in the LVL docs, does Google want us to call the license checker every time the app is initialized? Is that the safest way to implement this? Using the ServerManagedPolicy like Google suggests, do we just call the license check, and either run our app or do whatever we choose if they fail? One of my small concerns is the use of network data. They drill into us the need to be cautious of using resources without informing the user, and it seems to me this is a use of network data without letting the user know.
To add to this, is anyone experiencing any type of delay to their app due to this code? Due to the nature of my app, opening it and then waiting every time for an ok to come through the network would definitely distract from its use. Should I cache the response myself, or am I way over thinking this?
You answered your own question; if you feel that calling the service every time you start would be disruptive (which it would, e.g. the user is out of coverage), then don't do it.
Google make no recommendations about how often to use the licensing service; it's down to how paranoid you as the application developer are about piracy, balanced with how much you feel constantly checking would annoy the user.
Ok, fair, only check it once in a while.. But where can you "safely" store the information, that you should check it once a day only?
Eg, the first time you start the app, you will check it. Result of LVL is valid: so you store the date of the last successful check. But where to store it? Using SharedPreferences ? Is this safe? Because if you have root access on your device you could access the preference and change the valid date (to either way in the future, an yes, ofcourse you can check that in the code :-))
PS. Sorry, could not make a comment :(
Call it every time you start the app. The LVL library, as shipped by Google, will cache the response and use it the next time the user starts the app, thus not requiring a network connection if they restart the application within the cache valid time-frame.
What you likely want to do is change the amount of time the cache is valid. By default, google ships with a fairly low cache-valid time, which resulted in some upset users who were outside of a network when the cache had expired.
Concerning LVL: Although the SDK provides a sample implementation, Google themselves, clearly recommend against using it "as-is".
http://www.google.com/events/io/2011/sessions/evading-pirates-and-stopping-vampires-using-license-verification-library-in-app-billing-and-app-engine.html
After watching that, I believe, LVL is not an option for apps sold for 1-2$. Furthermore, a failed LVL check (if no network is available) will piss off legitimate users.
while it is true, that you can implement some kind of caching LVL responses, it will always boild down to the question, in how far you want to protect against piracy at the expense of legitimate users?
And: developer time is limited, so maybe it is more worthwhile to put efforts in improving an app, instead off wasting to much time trying to cut down illegal usage.