Hello and thanks in advance for your response.
I have my licensed app uploaded to the Play Store. I can test and get expected results with all of the static test license responses (Licensed, Not Licensed, etc). So far so good.
But if my test device has no internet connection, the license check ALWAYS fails. This is not how I understand the ServerManaged policy to work. If an install is found to have been licensed sometime in the recent past, the policy is supposed to cache information in a shared prefs file and use it if there is no internet connection.
So I temporarily commented-out the obfuscation of the data in the prefs file that the license system creates. When I look at the data, I see that the retry count and other stuff is set to zero. This is not what I expect. With data like this, it is behaving for me as if I were using a Strict policy (and I am not).
I am presuming that this is an artifact of using the test response system and that "real" users will get actual data in their obfuscated shared prefs that permits them to operate in the absence of an internet connection.
So I have tried setting the server response to "Respond Normally". When I do this, I ALWAYS get a NOT LICENSED response. And I guess this makes some sense because I have not purchased the app and downloaded it.
So how can I, as the developer, experience exactly what my end-users experience? I want to be able to test how this all works without an internet connection, for example. I cannot seem to figure out how to do this? I guess I could purchase my own app but I am not sure that will even work since the test device is logged into the test account. And it makes no sense for a developer to have to purchase their own app.
Thanks for any suggestions.
I think I found a possible solution to your problem.
What I have done:
first, I created a google group for alpha/beta testers of my app (after uploading the app, of course). Then, I ivited myself in this google group and accept the invitation. After this, I inserted my gmail developer account in the list of the users for the license test and set the server response to "RESPOND_NORMALLY".
In this way, the response of the server will be always "LICENSED" for my account, and the validity time will not expire in 2 minutes. It's as I had bought the app!
The only limitation to this trick is that you have to upload your app in a beta or alpha slot of your google developer console but, after this, you can also get a "LICENSED" answer using a debug app uploaded on your device using the usual Eclipse IDE! You don't have to wait for the generation of the link to download the test app (that is very slow to generate... Up to 24 hours!).
I too have experienced this frustration. I too want to have the same experience as my customers. As soon as I set 'Respond Normally' I always see the 'NOT LICENSED' response -- which seems VERY SUBOPTIMAL. I BELIEVE what Google needs to added is a setting of **'RESPOND_NORMALLY_AND_LICENSED'**. That would do what's needed.
The heart of the difficulty: if I leave my app as 'LICENSED' that works fine when I have an internet connection, then after 2 minutes with no connection, my app stops working as licensed (since the cache is set on the Google Play Server to 2 minutes). Thus if I want to use my own app day-in and day-out, I need to produce an app with licensing disabled --- something my customers never see. That's a VERY bad idea.
We all learned a long time ago: "You must eat your own 'dog food' as a developer."
I have reported this as a 'Developer Console' Bug, but it is perhaps instead of a 'Bug,' a very strong suggestion--and it would be seemingly be simple to implement.
As a work around, I have now added code in ServerManagedPolicy.processServerResponse() to simply add two months of time the licensed time and call setValidityTimestamp(). I hope this helps someone else. Now I am content ---
Related
We run a web application with a Java Script- and an Android front end. We use Google IDs with OAuth for authentication. Everything worked find until today authenticaiton suddenly stopped working. There was no new software version deployed or any operational changes. Now, when a user tries to log on via the browser application, Google issues
401. That’s an error.
Error: disabled_client
The OAuth client was disabled.
Request Details
scope=openid profile email
response_type=code
redirect_uri=https://***.net/signin-google
state=***
client_id=******.apps.googleusercontent.com
That’s all we know.
When logging in via Android App, authentication fails too, GoogleAuthUtil.getToken raises an unspecific exception.
I couldn't find much information when googling for this error message. Some say, one should try to change the application name in the consent screen. This didn't help in my case.
In developer console I noticed, that I cannot create a new Client ID for this project. I always get a technical error ("Server Error Whoops! Our Bad.") with a tracking number. Seems to be related.
I have a total of 7 Client IDs registered for this project and 3 public API access keys.
Is it possible, that Google explicitly disabled our project? That's how it actually feels. For what reason? I didn't get any notification. Our product is an application for access control, nothing special or illegal here.
Any ideas? This is a production environment, so for us the problem is absolutely severe.
Thanks for any help!
In the meantime we found out, that our Android App was removed from the Play Store and we got following notification:
This is a notification that your application, <...>, with package ID <...>, has been removed from the Google Play Store.
REASON FOR REMOVAL: Violation of the Personal and Confidential Information provision of the Content Policy.Please refer to the policy help article for more information.
We don't allow unauthorized publishing or disclosure of people's private and confidential information, such as credit card numbers, government identification numbers, driver's and other license numbers, non-public contacts, or any other information that is not publicly accessible.
We are very careful about the data inside our application and we take privacy and security extremely seriously as the hole app is about security and our customer's trust is absolutely essential. However, we recently introduced a feature that periodically sends the LogCat output to our servers for debugging reasons. Our app is in an early preview state which we make clear in the app description. It's used by a very limited number of people as it can only be used with a special piece of hardware we provide. The LogCat output only contains data from the app itself, no confident data of any kind. We published a couple of related apps and not all have the feature even included but all were suspended. However, we guess that this feature is the reason for removing.
Edit
In the meantime we wrote an appeal via the form provided on Google Play. The ban was removed from Google Play and the related Google OAuth Client shortly after.
We were informed, that our App collects names of running tasks and sends them to our servers, which is not the case. However, we used the crittercism library and the crittercism docs suggest to require the "GET_TASKS" permission, what we did. I don't think, that Crittercism is considered as dangerous as it's used by lots of applications. But maybe the combination of a Logging Service on the one hand and the GET_TASKS permission on the other hand, although not dangerous in our case, triggered some automatic rules at Google.
To fix this we simply removed Crittercism and all related permission requirements as it wasn't very useful for us anyways.
Is there any way, to check on server if this is my application sending data or it's someone's who decompiled my app? Note that both my and fake apps may be downloaded by user from Google Play. I have only one idea - in Google Play you cant post two applications with the same package names, so maybe I can send package name to server or something like this.
It can't be done without some help from OS - because an app would not know whether it was modified (the modification check itself can be hacked).
The ways I'd go would be the following:
Excercise the options Google Play Store gives you - license check and app encryption
Add some auth data to the application itself and verify it on the server (some encryption key). The data should change with each version
Accept only 2-5 last versions (for people who haven't yet updated)
This way, any pirated version will be valid for only a week or so... And for someone wanting to use the app constantly it will be easier to buy it, than re-download it every 1-2 weeks.
It won't protect you completely, but will make thievery time-consuming and hardly worth it given the option to buy the app. Enough to convince the users who would have bought the app to buy it. Those who pirate things out of principle can not be converted in any case...
there are some points which can make your code and application more safer.
use proguard(see on android devlopment site) it offuscates(other words makes it messy at compile time) your code.
secondly you could use encryption and decryption send some secret key encrypted
I have an app that uses in-app purchasses. I have integrated all the code from the Dungeons example except for the UI components. I have submitted my draft apk, activated it, created my in-app purchases, all of which are managed, and published them.
I am successfully able to purchase my in-app items and unlock the corresponding content without issue. The problem I am running into is that whenever I call to restore transactions, I get back the error code RESULT_SERVICE_UNAVAILABLE. I know that the result code means that the app can't access the store, but that makes no sense seeing as I can purchase items just fine.
I am running on an HTC Nexus One with Android v2.3.6 and Google Play v3.5.16. I am connecting over WiFi because there is no data plan for the device. The apk installed is exactly the same as the draft apk submitted. I am installing the apk via adb -d install command.
Any suggestions of what might cause this or where to look would be greatly appreciated.
Thanks
if you find similar message in the log:
05-30 09:28:23.760: E/Volley(4636): [13] BasicNetwork.performRequest: Unexpected response code 429 for https://android.clients.google.com/vending/api/ApiRequest
it can mean that you've send too much RESTORE_TRANSACTIONS request in certain amount of time. Google has clearly some throttling on request. It happened to me during testing in-app billing, approx. 20-30 restore transactions request went ok, and then - exactly the same problem - service unavailable response.
Check logcat output, maybe there are some warnings there. Other than that, not 100% sure that RESTORE_TRANSACTIONS works with unpublished apps and test accounts. Maybe 'service unavailable' simply means 'not supported' in this case?
I had this same problem, and it turned out that the password on the primary gmail account on the device was wrong. So when I checked if billing was supported, I got RESULT_OK, but for restore purchases, I got RESULT_SERVICE_UNAVAILABLE.
Go into your gmail or any google apps and refresh. Double check that the account password is correct and try again.
This problem also shows up in logcat as
NotifyingErrorListener.onErrorResponse: Server error on InAppPurchaseInformationRequest: com.android.AuthFailureError: User needs to (re)enter credentials
This does mean that you've done too many RESTORE_TRANSACTIONS and the service won't be available for X number of days unfortunately, as I hit the same issue.
BUT... It is device specific, so if you start testing again on another device or factory reset your device, you should be able to avoid it.
So, I've setup the Android LVL with my application to check for licensing. This seems to work great with the Test Accounts. The problem is, if I turn the phones internet connection off and try to run the app, the licensing check will fail and tell me it's NOT licensed!
One thing is, why does it tell me the application is NOT licensed and more importantly, how can I have the application 'remember' if it is licensed or not.
Apparently the answer to this is that the license is not cached when testing, but is when on the market. I created a small app to test this and it works!
Sorry but, I too confirm that airplane mode results in a failure to rely on any cache. Theoretically, if the app was online and pinged the license server right before going offline, then it might work. However, if the phone is offline for any significant amount of time, there is no caching mechanism. Just look at the code. I filed a bug against android :
http://code.google.com/p/android/issues/detail?id=12978
Because my users of Shout n' Snap shoutnsnap.com are ALREADY confirming this stupid behavior.
I've made a workaround using a 2 part challenge on the client side. EG:
IF LICENSED:
PERSIST random key as LK
PERSIST obfuscated random key as OLK
ELSE:
if (deobfuscate(OLK) == LK)
GRANT ACCESS
ELSE:
GET LOST
Code is here: http://code.google.com/p/androidbest/
I've been asked for some review copies of an Android app I've written, which is great, but I'm not willing to give out the full app to just anyone. I want to make a time-limited version (which works for about two weeks, then gives up the ghost).
What is the easiest way to do this? I haven't tested this myself, but I think that in theory if one built the app using a keystore which expires in two weeks might work. Is that correct, or do I have to put a line of code in the app which shuts it down if you attempt to boot it after a set date?
The keystore is not checked after the application is installed; only at installation time is the date verified.
You would have to put in your own time limit code, I imagine. Though if you want to be really paranoid, you could consider that the user could alter their device's clock.
Alternatively, you could do an online check (against time on your server), or make each APK that you hand out have an individual token embedded which gets validated against your server.
I have a simplest suggestion, what if the reviewer buys the application, and you refund the payment?
I just thought of a cool way to do this.
You make a Beta version of your app, and you can define the group of testers, you just need the email address of that person, or a G+ community they can request access to, and then you add them to the Beta program.
easiest way is to hardcode an end date and no longer run after that. it can be circumvented if users change their system time, but that is kind of a hassle to go through.
otherwise, you can have your app check the license periodically by connecting to your server over http, but that requires more work.
This sounds like a great idea. You'd probably want to make the app phone home and verify with a server that a certain amount of time has elapsed. Users can always delete your preferences file on the phone or uninstall and reinstall the app to get around on-phone restrictions.
I believe the keystore approach may also work, but I'm not sure exactly how they work in Android.
Please make this an open source project when you finish - I think this would be useful to a lot of people!
You could use TelephonyManager.getDeviceId() and create a build of your application that would only ever run on the reviewer's phone.
You could either hard code this into the application or have the phone check against your server where you'd store permissions for each Device ID. With the latter case you could have your application display the Device ID when it can't find a license; the reviewer tells you this and then you enter this in your DB.
As per Google: "If you plan to publish your application(s) on Android Market, the key you use to sign the application(s) must have a validity period ending after 22 October 2033. The Market server enforces this requirement to ensure that users can seamlessly upgrade Market applications when new versions are available"
What we did with our developer challenge II entry was when we hit the expiration date any new data we processed was replaced by an expiration warning. So the application functioned with existing data but not with any new data the user entered after the expiration. Since our app processed text messages, setting back the clock was an unrealistic long-term solution for the user to overcome the expiration.
Depending on the type of application your are giving to reviewers, you may have another options.
You code it like a lot of shareware and only let the application run so many times. The code for this would be very easy to implement. Sure the reviewer could delete the data, but not very easily. I don't think they would go through that much trouble for maybe a couple dollars.