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.
Related
I want to be able to recover from crash/closing the app or just device being disconnected.
Currently when I detect that the network is out for my Android device I save the Call created with RetroFit2 in a stack (to process later). If the user were to close the app or restart the device I lose the possibility to save these calls anywhere...
My question is the following, how can I save a RetroFit Call or an OkHttp3 Request?
None of them is serializable or nor can I convert them to strings from what I could see looking at the code.
Use android priority jobqueue by Yigit Boyar (one of the google android guys). It'll serailize your jobs, detect network changes (and respond accordingly) and persist even through device reboots (let alone app crashes). Plus a ton of other features. Just take a look. It is not exactly what you requested but it's a better solution. It's Magic.
Starting with v2, Job Queue can be integrated with JobScheduler or GCMNetworkManager. This integration allows Job Queue to wake up the aplication based on the criterias of the Jobs it has. You can see the deatails on the related wiki page. The Scheduler API is flexible such that you can implement a custom version of it if your target market does not have Google Play Services.
Try it and you'll be glad you did, as I've been. It filled the huge gap in my code that I spent weeks hacking together with spit, ducktape and faith.
I am writing app to monitor data usage by other installed applications. By far, I managed to get data usage through mobile and wlan interface. It will be pretty useful if I could track GPS usage per application (or UID). I dont know how it will be presented (time on "fix", number of requests?).
I can't find anywhere how to get that data. Does android save logs from GPS somewhere I can read them?
As #CommonsWare indicated in the comments, there mostly shouldn't be a way to access that information for application privacy reasons.
However, a question similar to this was asked on another stack exchange website and the solution was to try using an application called Spare Parts.
I am unfamiliar with the application, but I suspect you will be unable to access this information programatically. If all you would like to do is to see this information, this should do nicely. If your intent is to create some logic based on GPS usage, you may run into a little more trouble.
Basically, there is a Google way, which suggests using Service for long running operations (which I use at the time). On the other hand, there are a lot of examples in community by honored developers, which avoid using Service and at most incorporate Fragment's setRetainInstance(boolean retain).
While Google has declared that a lot of bad stuff might happen if we don't use a Service, I still feel anxious because there are, it seems, so many projects leaving Service aside.
Can you consolidate the Google's case or provide suggestions for abandoning Service?
P.S. I'm developing "classic" rest-client applications.
P.S.S. I forgot to mention that Service is used in pair with ContentProvider(for cachging purposes, guard against system app forceshutdowns).
Thanks.
If the network request is very likely to take under a second, or if you don't mind it if your process terminates before the request completes, using simple threading from the UI layer is fine, IMHO.
But once the user leaves your app (HOME, responds to an incoming call, etc.), the lifetime of your process is limited, and it could be very short if you do not have a service to tell the OS that you're still doing important work for the user.
So, if the network request is more in the 1-15 second range, and you'd like to feel fairly confident that the work will run to completion, use an IntentService or something along those lines.
If the network request is likely to be longer than that, such as a large download, now you have to worry about the device going to sleep and such. My WakefulIntentService was designed for this sort of scenario, where it will keep the device awake long enough to get the work done, then let the device go back asleep.
Some developers use services for all significant network I/O, skipping them only for truly ephemeral stuff like thumbnail images to populate a ListView or RecyclerView. So long as the service is only running when it is actively delivering value to the user, this is perfectly fine.
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'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.