I'm developing a game for Android using the Google Play Services for creating a turnbased match.
At first everything was fine I load the turnbased matches for the signed in user using
Games.TurnBasedMultiplayer.loadMatchesByStatus(getApiClient(),
new int[]{TurnBasedMatch.MATCH_TURN_STATUS_MY_TURN,
TurnBasedMatch.MATCH_TURN_STATUS_THEIR_TURN,
TurnBasedMatch.MATCH_TURN_STATUS_INVITED,
TurnBasedMatch.MATCH_TURN_STATUS_COMPLETE})
.setResultCallback(this);
It always loaded all matches that are any of the given states. But since last weekend the callback is called but there are no matches, as I'm not participating in any match (Status response is OK). I deleted the cache of Google Play Services on my phone and rebooted the device. At that moment all the matches were shown again until the next time I opened the app. Again all matches were missing.
Once I start a new match the match keeps showing up with the above method (refreshing the list) until I close the app. At the next launch that match is also gone.
I have to say the game is not published yet but in a test phase on the Google Play Developer Console. I found the same issue on an emulator. It ran fine for days but suddenly got the same problem as my real device (with a later build so it is not that a single change of code causes this).
Did anyone else notice this behaviour or has an idea on how to resolve it?
Might it be related to having multiple apps connected to one game? I had two apps signed with debug certificates connected and this afternoon added one for a signed apk. When I used the signed apk it worked again until I deployed a new test app (debug signed). After switching back to the signed apk the bug is still around.
As nobody seems to know the answer let me rephrase the question. Should I cache TurnBasedMatches myself on the device? I just deleted the play services cache again and reopened my app. Result? A list of hundreds of games (since I have to start a new game every time while testing...)
My code to handle the loadMatchesResult
#Override
public void onResult(TurnBasedMultiplayer.LoadMatchesResult loadMatchesResult)
{
showToast("GotMatches status: " + loadMatchesResult.getStatus().getStatusCode());
//add matches to listview (only caching matchId, no references to turnbasedmatch)
loadMatchesResult.getMatches().getMyTurnMatches().close();
loadMatchesResult.getMatches().getInvitations().close();
loadMatchesResult.getMatches().getTheirTurnMatches().close();
loadMatchesResult.getMatches().getCompletedMatches().close();
loadMatchesResult.release();
}
Found another interest point.. it starts to look like the issue occurs when deploying a new apk to the device... Once I deploy a new apk (either by install alpha version from google play or directly debug version from Android Studio) the matches are gone. When I don't change the apk I can reboot my phone/close the app and it works fine...
Issue also occurs if I update the app through the play store... There should be more people having this problem!
Gotten from https://developer.android.com/reference/com/google/android/gms/common/api/PendingResult.html#setResultCallback(com.google.android.gms.common.api.ResultCallback)
After the result has been retrieved using await() or delivered to the result callback, it is an error to attempt to retrieve the result again. It is the responsibility of the caller or callback receiver to release any resources associated with the returned result. Some result types may implement Releasable, in which case release() should be used to free the associated resources.
After you retrieve the result, an error is given when you try to get the results again, until you free the resources associated with the returned result, which is why clearing the cache works to make them visible again. You need to either access the device's cache and display results from there as well, or clear the associated resources (within the program) whenever you want to access the results again.
I had the same problem until I found "Saved Games" in my Developer Console:
Go to Game Services -> Game Details -> Saved Games
Set the item to "On"
This should solve your issue.
Related
I am trying to implement a simple subscription IAP on Android using the Amazon SDK. I adjusted their subscription sample app. The code is really simple.
Set <String>productSkus = new HashSet<String>();
productSkus.add("TLS_SKU_MONTHLY" );
productSkus.add( "TLS_SKU" );
PurchasingService.getProductData(productSkus);
But the response from onProductDataResponse() is always fail. I'm not sure why, I cannot find any examples etc to even know if my SKUs are right, in the sample app they looked more like package names than this, but these strings are what I entered on the 'in-app items' on the apps page on Amazon. The app has not been submitted yet, but I need to test and implement IAP before that. Any ideas? I cannot even find a simple tutorial walking through this, and as usual their docs are poor.
edit, noticed im getting these errors that dont even come up on google
Kiwi: DataAuthenticationKeyLoaderV3: Unable to load authentication Key
java.io.FileNotFoundException: AppstoreAuthenticationKey.pem
DATA_AUTH_KEY_LOAD_FAILURE: CERT_NOT_FOUND: null
com.amazon.a.a.o.b.a.a: DATA_AUTH_KEY_LOAD_FAILURE: CERT_NOT_FOUND: null
I'm wondering, is this because I am running on real Android and not an Amazon device like a fire tablet or tv stick?
You should add your own AppstoreAuthenticationKey.pem to the project assets folder. It is not (and should not be) delivered together with the sample.
Basically, you must do a few things:
Login to the Amazon developer console and create your application.
Go to the “Apk Files" tab to download AppstoreAuthenticationKey.pem.
Add this file to the project’s assets folder.
You can get the full instructions from Amazon.
As for devices, yes, you must use an Amazon device. But this should not be the reason why you are getting this exception.
Working with Lollipop, I have a device-owner app that is installed with NFC at provision time.
What I need now is to handle automatic updates for my App, from Google Play to rely on the standard Android App update system...
So far I can imagine 2 ways to get this done, but don't know how to handle any of them :
in my NFC install constant EXTRA PROVISIONING DEVICE ADMIN PACKAGE
DOWNLOAD LOCATION install the App directly from the Play Store instead of the url on my own dev server. However
this constant need to handle the url of an apk file, and I did not find any
official way to get apk install direct from Play Store ? (as it will
be a production App in the future I'm not interested in hacks)
keep installing the apk from the dev server, but then allow the App
to update itself with its little brother located on the Play Store
with the same package name. To say it an other way: Would this be possible to install a v1 apk from a custom location, then put a v2 on the PlayStore... and let the magic come true ?
I'd be glad to hear if anyone could share experience about such procedures. Thanks for reading!
EDIT after #Stephan Branczyk suggestion I could make some more testing, here is what I did and the results:
1 - In the NFC provisioning I replaced the apk url with
snep://my.app.packagename without luck ; it just gives an error
without much explanation.
2 - I replaced this url by such a PlayStore link :
https://play.google.com/store/apps/details?id=my.app.packagename but
it gives a checksum error whether I use the checksum locally
computed, or the checksum given on the GooglePlay apk details. It looks not so far from the goal but I could not make it work.
3 - Finally I came back on my first solution, a self-hosted apk
versioned 1... but this time I tried to put on the PlayStore a newer
version 2 of the app with the exact same packagename... That led me
to strange things:
At first my App did not appear anywhere in the local PlayStore App,
but when I searched for it in Google Play, it showed up with the green
"installed" badge, and it proposed me to make an update... So did I.
Then, after this first manual update, the App is in v2, nice, and
better: it appears well listed in my PlayStore.
Optimistically, I uploaded a v3 of the App... just to see if my
PlayStore would automatically update my app (as is does for all the
other ones), but sadly no luck : even if my app is still listed in the
playstore, and proposing the "update" button... it never
updates by itself as it should ; I still need to click on it manually.
Isn't it a strange behavior ? If some have ideas about it, I would really need to be able to rely on the Play Store functionalities but so far no luck, and I cannot believe that Device-Owner app distribution is not compatible with PlayStore ?
Just in case, FYI here is the kind of provisioning code I'm using:
try {
Properties p = new Properties();
p.setProperty(
DevicePolicyManager.EXTRA_PROVISIONING_DEVICE_ADMIN_PACKAGE_NAME,
"my.app.packagename");
p.setProperty(
DevicePolicyManager.EXTRA_PROVISIONING_DEVICE_ADMIN_PACKAGE_DOWNLOAD_LOCATION,
"http://www.example.com/myDeviceOwnerApp.apk");
p.setProperty(
DevicePolicyManager.EXTRA_PROVISIONING_DEVICE_ADMIN_PACKAGE_CHECKSUM,
"U55o3fO0cXQtUoQCbQEO9c_gKrs");
ByteArrayOutputStream bos = new ByteArrayOutputStream();
OutputStream out = new ObjectOutputStream(bos);
p.store(out, "");
final byte[] bytes = bos.toByteArray();
NdefMessage msg = new NdefMessage(NdefRecord.createMime(
DevicePolicyManager.MIME_TYPE_PROVISIONING_NFC, bytes));
return msg;
} catch (Exception e) {
throw new RuntimeException(e);
}
Write your package name as an AAR record in the tag.
To confirm that this functionality works, use this app to write the tag with.
You need to set Base64 encoded SHA1 or SHA256 (from M forward) of the apk in the
EXTRA_PROVISIONING_DEVICE_ADMIN_PACKAGE_CHECKSUM
field when provisioning through NFC otherwise the provisioned device will not accept the URL for download.
Also see this answer for properly encoding the checksum.
I am using the GooglePlay game service for adding a Leaderboard in my game (actually, several leaderboards). Signing in to GooglePlayGameServices works, as well as submitting a score to a given Leaderboard-id. I checked this using a OnScoreSubmittedListener. The result is ok, the score is there.
When trying to retrieve the top scores for a given id using 'loadTopScores', the OnLeaderboardScoresLoadedListener gets called with STATUS_OK, one entry in the LeaderboardBuffer (I checked this entry, it is the exact same leaderboard-id I previously submitted the score to) and alway zero entries in the LeaderboardScoreBuffer. I could not find a solution to this problem. One thing that seems odd is that in the LeaderboardBuffer entry, the player rank is set to -1. But I couldn't find out what that means.
thanks in advance for any insights on this problem =)
I managed to find the problem myself finally =) It was rather easy. Since the services utilize one's google+ account, you have to set the permissions properly. Under "settings" -> "accounts" -> "google" -> "google+" -> "apps with google sign-in" is an entry for my game. There I had to allow uploading of scores to be public. Once I did that everything works fine for me.
I've been setting up Android in app billing v3, using the IABHelper class, and following the example code provided by Google. I have it mostly working all the way through purchase (with signed apk and real credit card charge).
However, in the course of testing today I started to get a new error in my QueryInventoryFinishedListener from the queryInventoryAsync() method:
IABResult message: "Error refreshing inventory (querying prices of items)"
IABResult response: 5:Developer Error
Weird thing #1 is that this occurs after the onIabSetupFinished() callback returns (with the customary "Hooray" message). Weird thing #2 is that I can subsequently & successfully process an in app purchase (using the launchPurchaseFlow() method).
I found a patch here that addresses the same symptoms I'm experiencing, but it didn't work for me.
I've tried using different devices, using different gmail accounts, and building a new product from scratch. I even getting the error on earlier versions of my app that ran correctly (what?!).
My question is: Why can't I query the product inventory, even after IABHelper has confirmed the set up was successful? What could be causing this error, and how can I fix it?
Thank you for any insight.
UPDATE
I was able to get the inventory query transactions to work again by ditching the account I was testing with, and switching to a new account. No code change.
My tentative conclusion is that something got corrupted in the user account I was using (?). During testing, I had hit it pretty hard with a lot of purchases of different in-app products -- but I still need to find out what happened, and make sure this doesn't happen to any of my users.
Please let me know if you have any experience with this. Thanks!
We had the same problem in one of our apps under test mode. Later, we figured out that, we had to clear the Cache of the Google Play Store app.
So you can try this -
Go your device's Settings menu.
Go to Applications (may also be labeled Application Manager).
Tab over to All Applications.
Search for and open the Google Play Store app. Tap on it, application settings will show
Tap on Clear Data and Clear Cache.
Now go back to your app and try to load inventory. It solved our problem.
I found by trial and error that if you query more than 20 items at once, it will fail with this error.
I submitted a patch for IabHelper.java that splits the list of SKUs into packets of 20 items each and does the query.
You can grab it there: https://code.google.com/p/marketbilling/issues/detail?id=123
I have the same issue with this log :
"InAppBillingManager.getSkuDetails: Input Error: skusBundle array associated with key ITEM_ID_LIST cannot contain more than 20 items."
this note had mentioned in IInAppBillingService.aidl file, see the documentation of the method getSkuDetails(..) .
So you should make the same process for each 20 items every time
I face same error but my issue is Date Time change
Go to setting and check your date time is accurate
Our beta app uses android.test.purchased so customers can test for free. But recently something broke with consuming these test products. The purchase process still works fine but when we try to consume:
int response = ms.consumePurchase(3, mContext.getPackageName(), token);
This now always returns RESULT_DEVELOPER_ERROR == 5. The data passed appears valid, token is inapp:com.lootworks.swords:android.test.purchased which I think is correct for the static test products.
Simultaneously all our earlier app versions also stopped working and we did not change our code, so it sure seems like something changed with IAB itself.
I also tested purchase/consume of the real (for $) products and it succeeds with the same code. So the consume problem seems to affect only the static response test item.
With Sean's help and some additional testing this appears to be a google play IAB regression. Have opened a bug https://code.google.com/p/android/issues/detail?id=53077
My team and I are experiencing this same issue. Nothing has changed with the app consume code, so it is very strange. The app is not release-ready yet, so we have plenty else to work on, but this throws a monkey wrench into testing for sure.
This may not be an option for you, but you could change the namespace, delete the app entry in the dev console and go through the process of making a new one, and splitting the key up again, etc.
I only suggest this because this problem does not seem to be happening for all apps. Anyway, if the consume in our app does not start magically working again soon, this is what we will try.