B4A Library Google Play Game Services

First off, my apologies on my Wrapping Skill, this is no where near as polished as from the big boys of wrapping here. Also, many thanks to Erel for helping me get through this.

The story: I need this library, and it is working for me. If you know what it is, and have been waiting for it, hopefully my tutorial will help you get going with it. If you don't know what this library does, or if you need it, check out here

Right now, this library can handle Leaderboards, Achievements, Room Creation/Communication (have not done RealTimeSocket yet), One-Click signIn, and Anti-Piracy Checks. Did not implement Cloud Save.

Still interested? Read on.

First, please review Google's branding guidelines, as there is no way I can keep that up to date on this thread. Here

Next, I recommend just studying the flow of events here particularly the Developer's Guide section.

Still awake? Good.

Before any of this works, you need to register your app within your Developer Account, to get the OAuth necessary. The Google/Java speak instructions are in that developer's guide.

For B4A speak. Must do the following:

1. Follow these directions for adding your app to the console here.

** EDIT - See Erel's post below on how to grab SHA1 fingerprint straight from B4A... **

When you get to the part about adding your SHA1 fingerprint, it's time to break out your command prompt. (If you already know how to get your SHA1 fingerprint, then continue on) First, find out where (or make a new) password file for B4A is kept by looking at your B4A->Tools->Private Sign Key.

Then in your command prompt, change to the directory with keytool in it (for me that is "c:\Program Files\Java\jre6\bin") and type
B4X:
keytool -exportcert -keystore <path-to-debug-or-production-keystore> -list -v
which for me would be
B4X:
keytool -exportcert -keystore C:\Programming\b4a.keystore -list -v
A prompt asking for your password should then pop up. Type your password in that you used to create it(shown on your B4A->Private Sign Key window)

Then, enter that SHA1 fingerprint (type it, copy paste it... I copy the whole command prompt to notepad, and then copy/paste it from there) into the final OAUTH Step and you should get back that your app is linked.
Note the code back will look something like this -> 211205627476-74off6bsgue1qbcka2878p3lurctabft.apps.googleusercontent.com ONLY THE FIRST PART BEFORE THE HASH IS YOUR APP_ID FOR USE IN THE XML FILE

2. Create your new B4A project and include this in your manifest:
AddApplicationText(
<meta-data android:name="com.google.android.gms.games.APP_ID"
android:value="@string/app_id" />
)

3. Create an XML file in your B4A (using your favorite text editor) project called ids.xml in your projectdirectory-> Objects -> res -> values folder, and put something like this in it
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright (C) 2013 Google Inc.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<resources>
<!-- TODO: Replace this by your app's app ID! -->
<string name="app_id">ReplaceME</string>
</resources>

Put your AppID obtained from before in the ReplaceMe section and then make sure to set the file to read only (just edit the file included in the sample app)

4. Now it is time for the achievements/leaderboard ID's Need to do that here and here

In the sample app created I use two leaderboards (easy and hard) and four achievements (put in five if you need to continue in your Developer account, but not required to use them all) the four achievements are:
B4X:
Dim easyLeaderboard As String = "ReplaceMe"
Dim hardLeaderboard As String = "ReplaceMe"
Dim EasyAchievement As String = "ReplaceMe" 'for playing a game of easy level
Dim HardAchievement As String = "ReplaceMe" 'for playing a game of hard leve
Dim IncrementAchievement As String = "ReplaceMe" 'for playing 10 games (either hard or easy)
Dim HiddenAchievement As String = "ReplaceMe" 'not visibile until hard and easy games played

Follow these directions, but use these sample Achievements and Leaderboards for the sample application and fill in with your own pithy comments, and Replace the ReplaceMe's for each one in the sample app **Note the IncrementAchivement is of type increment and I used 10 as the amount. The HiddenAchivement is of type Hidden, and you can see in the code how I went about unlocking it**

5. Now time for a choice, either download the attached xml/jar files that go in your library, or (advanced mode) download and compile the attached project source files. Either way, must have gameplayservices.jar, gameplayservices.xml (which are the library wrappers) installed in your Libraries folder and then have gameplayservices selected in B4A. Also, I am a big fan of having a bit of something in my demos, so you will also need Informatix' most excellent AnimationPlus library installed (do search for latest link) and Agraham's superbly efficient ByteConverter library (again, do search).

6. Not sure why, but in order to get the required dependency file "googleplayservices.jar" You must follow the directions here to download the SDK. Then, grab that file and put it in your library. (the file itself is a bit above the limit for me to include here, and I'm not sure about the legal ramifications of including it by itself after reading here) If anybody can tell me otherwise, I'll post it someplace else for easier access to download.

7. Three modules are included in the sample app. The main module is just the basics of logging in (once you get past that, then it's time for the other two) and displaying the SignIn button. The other two modules are my own take on the Type A Number and Button Clicker sample apps (no typing of numbers in my version, but I do add displaying player icons, more robust message passing)

8. Logic/documentation. As I said, trying to figure out how to wrap all of this was a very good challenge/learning process for me. As some of these wrappers included nested classes, and I didn't know exactly how to approach, I made the nested classes separate classes for exposing to B4A. What does that mean? Well, some of the things that happen "behind the scenes" in the original library, I had to make a choice on where they happen in my wrapper. I finally decided that almost anything to do with Room Stuff, happens in the gRoomConfig wrapper (As opposed to RoomConfig, Room and GamesClient in original flow). My samples show a lot of what was wrapped, but if you have a question about a function, and you go to look for more detail on Google's developer site, Where that function is exposed may be different in this library, and sometimes not at all. (If not exposed, it is generally something I didn't see how to write a wrapper for that functionality, at least not yet, but again... it's working for me with a lot of what I wanted to accomplish) I am also including all of the source files, which may help out for those looking to try and learn how to wrap things in the future. Please forgive my poor coding logic in advance. Also, some things are exposed that don't do anything (at least not for me) and are there to show where I think they should be exposed moving forward (most notably the RealTimeSocket stuff), but they are annotated with the hint system as not being ready for prime time!

Of note, many, many listeners in this, and I did include code in the Java to explain many of them, but I don't see how to bring up those hints when using the "Sub "space-Tab" auto-fill" feature.

9. Going forward - I am sure I will be updating some things as I go along, but I don't know at what pace, and who knows, maybe RTS's are really, really important to someone, or the ability to do cloud saving. So, I also am including the source files that I used to wrap. While a learning tool in and of themselves, I do ask, that if you add any functionality, that you pass those additions back to the community. I think we all benefit from using these libraries that others create, and let's face it, sometimes having that 1 library wrapped makes all the difference.. and until Erel figures out how to auto-wrap any library out there... some of us come to a halt going down certain paths unless someone out there can help boot strap our project. (which is why I started this in the first place :) ) Also, please note you'll probably see some ("why is THAT there") in the source code, and it's because I learned a LOT doing this, and changed how some implementations worked as I kept building wrapper classes. I would do it all from scratch to make it cleaner... but I need to get going on the projects that I built this for!
 

Attachments

  • GoogleGameServiceSampleApp.zip
    20.5 KB · Views: 537
  • GamePlayServicesLibraryFiles.zip
    56.3 KB · Views: 620
  • EclipseSourceFiles.zip
    87.6 KB · Views: 459
Last edited:

Informatix

Expert
Licensed User
Longtime User
Well I don't think it's an internet connection issue because all the other functions are working fine, plus I can get this functionality to work fine with the old library. I'll keep looking.
I have no clues on this matter. These errors are generated by the Google's lib (which is more recent than the one you used with the previous GPlay lib) and everything is possible: from a bug in this new version (but we should find reports on internet) to a misconfiguration in your app. Since my lib does not connect to internet and doesn't query the servers (it's done by the Google's lib), I cannot do anything on my side. Maybe the cached data on your device are corrupted (I suppose that's the reason why my account stopped working suddenly and re-worked again when I uninstalled Google+). You can also delete the linked app and recreate it in your dev console, and remove and recreate your email address in the list of allowed accounts. That will end for sure any pending request (so error 7007 will have no reason to persist).
 

Computersmith64

Well-Known Member
Licensed User
Longtime User
Well, I've spent the better part of the last 2 days trying to get it to work & I can't. I've even reverted back to the old version of the library that was working & now even it isn't working. I've tried everything I can think of, including creating a new test app in the developer console, but I cannot get it to successfully create a room. I wonder if it's something to do with the new version of the Google Play Services APK? I have it on both devices I've been trying to test with. Anyway, I've wasted enough time trying to get it to work for now - so I'm going to move on to more productive things. Unfortunately it means I can't do any more testing of the new library until I can be bothered coming back to try & figure out the problem.

- Colin.
 

Informatix

Expert
Licensed User
Longtime User
Well, I've spent the better part of the last 2 days trying to get it to work & I can't. I've even reverted back to the old version of the library that was working & now even it isn't working. I've tried everything I can think of, including creating a new test app in the developer console, but I cannot get it to successfully create a room. I wonder if it's something to do with the new version of the Google Play Services APK? I have it on both devices I've been trying to test with. Anyway, I've wasted enough time trying to get it to work for now - so I'm going to move on to more productive things. Unfortunately it means I can't do any more testing of the new library until I can be bothered coming back to try & figure out the problem.

- Colin.
Thank you for your efforts. I hope that you will find a solution soon.
 

Informatix

Expert
Licensed User
Longtime User
Can we retrieve leaderboard and scoreboard information with this library Frederick?
Yes, but only partially. To get a better idea of what can be done or not, read the posts above where I announce each alpha version. The current version fits my needs so I will finish the other parts only on request AFTER the existing code has been carefully tested and validated (I won't test myself the real-time for example so I need people to do so).
 

Informatix

Expert
Licensed User
Longtime User
Here's the alpha version 5. I added the AppState client and finished the Achievements. This includes also a minor bug fix (buffers were not closed).

What is finished and works fine:
- Connection
- AppState
- Turn-based matches
- Achievements
- Intents (dialogs)

Still unfinished and untested:
- Real-Time
- Leaderboards

[File deleted]
 
Last edited:

walterf25

Expert
Licensed User
Longtime User
Here's the alpha version 5. I added the AppState client and finished the Achievements. This includes also a minor bug fix (buffers were not closed).

What is finished and works fine:
- Connection
- AppState
- Turn-based matches
- Achievements
- Intents (dialogs)

Still unfinished and untested:
- Real-Time
- Leaderboards

No new version is planned after this one.
Thanks Frederick, it works great!
 

Computersmith64

Well-Known Member
Licensed User
Longtime User
Here's the alpha version 5. I added the AppState client and finished the Achievements. This includes also a minor bug fix (buffers were not closed).

What is finished and works fine:
- Connection
- AppState
- Turn-based matches
- Achievements
- Intents (dialogs)

Still unfinished and untested:
- Real-Time
- Leaderboards

No new version is planned after this one.

So I can report that from the testing I did, the Leaderboard functionality for submitting scores & viewing the leaderboard work fine. I don't use any of the other Leaderboard functions, so I can't comment as to whether they work or not.

- Colin.
 

Bas Hamstra

Member
Licensed User
Longtime User
Hi guys, I am probably very stupid, but can't get even the basics right. I spelled Fredericks earlier post (in other forum) about the following:

First my app_id is in place in Google Developer console, and working (since I tested with older implementations of this lib and could at least sign in G+)

Created AdditionalRes folder, called Res, (B4a finds it, no error on that)

Copied like you said: everything (lot of folders) from the res directory of the SDK lib for google play to the above created folder. To be precise: I copied from here: C:\Program Files (x86)\Android\android-sdk\extras\google\google_play_services\libproject\google-play-services_lib\res

Created games-ids.xml (from developer console) and placed it in the values folder (read-only). To be precise: in the additionalres folder/values

Now when I try to run Fredericks testapp "Turnbasedmatch", B4A complains as follows:

Parsing code. 0.04
Compiling code. 0.14
Compiling layouts code. 0.00
Generating R file. Error
AndroidManifest.xml:10: error: No resource identifier found for attribute 'xlargeScreens' in package 'android'
AndroidManifest.xml:20: error: Error: No resource found that matches the given name (at 'value' with value '@string/app_id').
AndroidManifest.xml:22: error: Error: No resource found that matches the given name (at 'value' with value '@string/app_id').
AndroidManifest.xml:24: error: Error: No resource found that matches the given name (at 'value' with value '@integer/google_play_services_version').

I have tried to place games-ids.xml in various places, but keep gettting the above error. As a side note I try to run this in an Android 4.3 emulator of type "Google APIs", which should support GPLay.

I hope I am not beyond help...?

Kind regards,

Bas Hamstra
 

Informatix

Expert
Licensed User
Longtime User
Hi guys, I am probably very stupid, but can't get even the basics right. I spelled Fredericks earlier post (in other forum) about the following:

First my app_id is in place in Google Developer console, and working (since I tested with older implementations of this lib and could at least sign in G+)

Created AdditionalRes folder, called Res, (B4a finds it, no error on that)

Copied like you said: everything (lot of folders) from the res directory of the SDK lib for google play to the above created folder. To be precise: I copied from here: C:\Program Files (x86)\Android\android-sdk\extras\google\google_play_services\libproject\google-play-services_lib\res

Created games-ids.xml (from developer console) and placed it in the values folder (read-only). To be precise: in the additionalres folder/values

Now when I try to run Fredericks testapp "Turnbasedmatch", B4A complains as follows:

Parsing code. 0.04
Compiling code. 0.14
Compiling layouts code. 0.00
Generating R file. Error
AndroidManifest.xml:10: error: No resource identifier found for attribute 'xlargeScreens' in package 'android'
AndroidManifest.xml:20: error: Error: No resource found that matches the given name (at 'value' with value '@string/app_id').
AndroidManifest.xml:22: error: Error: No resource found that matches the given name (at 'value' with value '@string/app_id').
AndroidManifest.xml:24: error: Error: No resource found that matches the given name (at 'value' with value '@integer/google_play_services_version').

I have tried to place games-ids.xml in various places, but keep gettting the above error. As a side note I try to run this in an Android 4.3 emulator of type "Google APIs", which should support GPLay.

I hope I am not beyond help...?

Kind regards,

Bas Hamstra
Do you have an AdditionalRes line in your Project Attributes at the beginning of Main? because the error msg above suggests the contrary.
And what android.jar do you have in your Paths configuration? because it seems a bit old.
 

Bas Hamstra

Member
Licensed User
Longtime User
Absolutely, I am sure of it, see below. If I rename Res to QRes THEN I get an error that the folder is not found. With the below, there is no such error.

#Region Project Attributes
#ApplicationLabel: TurnBasedMatch
#VersionCode: 001
#VersionName: 0.01
'SupportedOrientations possible values: unspecified, landscape or portrait.
#SupportedOrientations: landscape
#CanInstallToExternalStorage: False
#AdditionalRes: Res, com.google.android.gms
#End Region

About paths in B4A:

javac.exe = C:\Program Files (x86)\Java\jdk1.7.0_07\bin\javac.exe
android.jar = C:\Program Files (x86)\Android\android-sdk\platforms\android-8\android.jar
additionalibs = D:\SimpleLibraryCompiler\FirstLibrary

Hm... you may be on to something here. What is your recommendation? I know that android 4.3 (=18) supports GPlay. But I am not quite sure what's best to fill in? The current paths have until now worked fine, even on Android 4.03 or 4.3 emulators.

Thanks for your pointers...!

Bas Hamstra
 

Informatix

Expert
Licensed User
Longtime User
Absolutely, I am sure of it, see below. If I rename Res to QRes THEN I get an error that the folder is not found. With the below, there is no such error.

#Region Project Attributes
#ApplicationLabel: TurnBasedMatch
#VersionCode: 001
#VersionName: 0.01
'SupportedOrientations possible values: unspecified, landscape or portrait.
#SupportedOrientations: landscape
#CanInstallToExternalStorage: False
#AdditionalRes: Res, com.google.android.gms
#End Region

About paths in B4A:

javac.exe = C:\Program Files (x86)\Java\jdk1.7.0_07\bin\javac.exe
android.jar = C:\Program Files (x86)\Android\android-sdk\platforms\android-8\android.jar
additionalibs = D:\SimpleLibraryCompiler\FirstLibrary

Hm... you may be on to something here. What is your recommendation? I know that android 4.3 (=18) supports GPlay. But I am not quite sure what's best to fill in? The current paths have until now worked fine, even on Android 4.03 or 4.3 emulators.

Thanks for your pointers...!

Bas Hamstra
The answer is in your post: ...platforms\android-8\android.jar. You're compiling for Android Froyo ! The current version is 19 (Kitkat).
The version that you use here has no relation with the version of the OS on the device. It's just for compilation.

EDIT: ... and you have to set the full path to your AdditionalRes folder. "Res" alone points to the wrong res folder.
 
Last edited:

Bas Hamstra

Member
Licensed User
Longtime User
Initial problems fixed... Thanks for your help, in paths api level set to 18 (=A4.3). I'm not sure the additionalres folder has to be named "res" but in my case "d:\res" works. Put the "games-ids.xml" in d:\res\values. App now compiles and I see the start screen. Next problem is the log shows:

Connect: isGooglePlayServicesAvailable returned 2
GPC_onSignInFailed: Reason=Google Play services not available

- package name is correct: b4a.com.example
- SHA1 is correct
- Google account logging in in is correct

Hm...in the past I *have* succcesfully logged in with the exact same developer console settings. I will do some more checks. But I am very pleased to make progress, I must say.

Kind regards,

Bas
 

Bas Hamstra

Member
Licensed User
Longtime User
Note: the rejection is almost instant. I remember from previous attempts that login can take a few seconds, but in this case immediate response: return 2.

Emulator = android 4.3 with Google APIs.

- appid = correct
- package name = correct

Bas
 

Informatix

Expert
Licensed User
Longtime User
Note: the rejection is almost instant. I remember from previous attempts that login can take a few seconds, but in this case immediate response: return 2.

Emulator = android 4.3 with Google APIs.

- appid = correct
- package name = correct

Bas
It is instant because it fails to find the GP services on your device. It needs them to communicate with the remote servers. It's the message that I get on my Kindle Fire where the Play Store is not installed.
 
Last edited:

Bas Hamstra

Member
Licensed User
Longtime User
Hi Frederick, seems you are right... Here's what I did: I started GenyMotion with Galaxy S4, with Google Play installed. First no luck. Then via Google Play I downloaded Google Play Services app. Then successful login! So thanks a lot! Now I am checking out your test app, lots to discover!
 

Bas Hamstra

Member
Licensed User
Longtime User
Some notes: my regular Android 4.3 emulator (slow) with Google APIs it DOES have Google Play Services, but an older version, that it refuses to update on the emulator. That's return code 2, I think (total absence of GGS will return code 9, is my impression).

I abandoned GenyMotion because of stablity issues in the past, but updated to new version 2.1.1 (also updated Virtual Box to latest version). Unfortunately in GM 2.1.1 there is no Google apps, but there is a trick for that. Just drag a zipfile with GAPPS.ZIP to the emulator to install them. I ended up with a GM stable and fast XPeriaZ Android 4.3 emulator including Google apps, which has not crashed on me yet.

To get GoogleApps to GenyMotion 2.1.1 this worked for me:

http://blog.zeezonline.com/2013/11/install-google-play-on-genymotion-2-0/

Bas
 

Informatix

Expert
Licensed User
Longtime User
Here's the alpha version 6. I reverted a change introduced in version 5. Buffers must not be closed (it's not safe to let them open, but it's better than a not-working solution). I also finished LoadPlayerCenteredScores, LoadMoreScores and SendUnreliableRealTimeMessage.

[File deleted]
 
Last edited:

Bas Hamstra

Member
Licensed User
Longtime User
Tested with 2 Genymotion emulators, each with it's own Gmail/G+ account. Both via Google Play latest GGS installed.

- Login on both succesful
- show friends succesful
- Invite succesful
- Take turn succesful

Notes/observations:

1) since one of the GMail's is the same as on my phone, my phone receives notifications each turn :)
2) testapp behaves a little unpredictable: sometimes I have an automatic screenrefresh, when oppo has taken turn, and sometimes the only way to force screenupdate is via statusbutton-->click on the notification
3) the testapp is slightly odd in that you can start a match BEFORE the invite is accepted

If there is anything I can do to help (with my ant-brain, be warned!) let me know. At this point I am interested in sending messages (other than notifications). Once that works, we have the core for a multiplayer boardgame, wow!

With respect,

Bas Hamstra
 

Informatix

Expert
Licensed User
Longtime User
Tested with 2 Genymotion emulators, each with it's own Gmail/G+ account. Both via Google Play latest GGS installed.

- Login on both succesful
- show friends succesful
- Invite succesful
- Take turn succesful

Notes/observations:

1) since one of the GMail's is the same as on my phone, my phone receives notifications each turn :)
2) testapp behaves a little unpredictable: sometimes I have an automatic screenrefresh, when oppo has taken turn, and sometimes the only way to force screenupdate is via statusbutton-->click on the notification
3) the testapp is slightly odd in that you can start a match BEFORE the invite is accepted

If there is anything I can do to help (with my ant-brain, be warned!) let me know. At this point I am interested in sending messages (other than notifications). Once that works, we have the core for a multiplayer boardgame, wow!

With respect,

Bas Hamstra
As I have seen many strange things with the GenyMotion emulator (whatever version I tried), I hardly trust a result positive or negative on this emulator. I prefer tests made with real games on real devices (or official emulators). I have myself many real devices (phones and tablets) so I tested every aspect of turn-based matches and all seems to work fine. Currently, I need tests for real-time because I don't have any game in project using real-time.
Concerning your tests, I'm unable to reproduce the point #2 (do you get the notification in the notification bar or absolutely nothing?), and could you explain your point #3? Nothing prevents you from starting a game while you're waiting for the other player to accept the invitation and join the match, but if the invitation is not accepted, you won't be able to take your turn. That's why I disable the Take Turn button while waiting for the other player. Do you mean it is enabled on your device?
 
Last edited:
Top