Java Question Game Play Services

Computersmith64

Well-Known Member
Licensed User
Longtime User
Hi guys

I will probably look at the Google Play Game Services library after my exams (begin february) because I might need it for my own project.

Regards,
Tomas

Sounds good. Let us know when you are going to start & I will upload the latest I have.
 

Computersmith64

Well-Known Member
Licensed User
Longtime User
Don't hesitate to upload your latest code because I'm not interested by all classes of the library and some of them will be left untested (and so unmodified).

I haven't made any changes that I can think of since I last uploaded it, so just go with that.

- Colin.
 

Informatix

Expert
Licensed User
Longtime User
With the latest Google Play Services library (v14), you have to:

- Add in the Manifest:
AddApplicationText(
<meta-data android:name="com.google.android.gms.games.APP_ID"
android:value="@string/app_id" />
<meta-data android:name="com.google.android.gms.appstate.APP_ID"
android:value="@string/app_id" />
<meta-data android:name="com.google.android.gms.version"
android:value="@integer/google_play_services_version" />)

- Copy all files from the res folder of the library (search in your Android SDK folders) to a folder in your B4A project.

- Add #AdditionalRes (B4A v3.20) in Main to indicate where are located these copied files:
#AdditionalRes: <path to the folder containing the resources>, com.google.android.gms

- Then place your games-ids.xml file in the values folder of the library (not in objects/res/values).

To generate the games-ids.xml file, there's a very simple way: go in the achievements or leaderboard section of your developer console and click on the link at the bottom:
ressources.png
 
Last edited:

Bas Hamstra

Member
Licensed User
Longtime User
Hi Informatix,

I am not sure what to make of your last post. Did you modify/extend the library? Where is it? Or are you saying Computersmith64's version works fine when above directions are followed?

I myself had no luck yet with the last posted version. I can login succesfully with G+, and after that it crashes with a message that some class is not defined. Probably because I tried to test it with the original poster's test app, the older lib/methods differ a bit here and there.

Can you clarify?

Kind regards,

Bas
 

Informatix

Expert
Licensed User
Longtime User
Hi Informatix,

I am not sure what to make of your last post. Did you modify/extend the library? Where is it? Or are you saying Computersmith64's version works fine when above directions are followed?

I myself had no luck yet with the last posted version. I can login succesfully with G+, and after that it crashes with a message that some class is not defined. Probably because I tried to test it with the original poster's test app, the older lib/methods differ a bit here and there.

Can you clarify?

Kind regards,

Bas
I don't use any other version than mine, which is not released for now as it still needs a lot of work, and I just published my findings while writing it. If you want to use the latest library available from Google (google-play-services v14), you have no other choice than doing what's in my post. Due to important changes made in this library, there are new constraints. For example, B4A v3.20 is mandatory to solve the main issue with resources.
 

Computersmith64

Well-Known Member
Licensed User
Longtime User
Hi Informatix,

Since you are working on the library wrapper, I should let you know about a bug in the existing one that you may or may not be aware of. I'm not sure exactly where the error is (connectNextClient() in GameHelper perhaps?), but you can have a situation where isSignedIn will report true when you actually aren't signed in. This can happen even when you have no internet connection, so I put a workaround in my B4A code that checks that you are connected to the outside world, rather than relying on isSignedIn. The problem with this workaround is that there is a bug in versions of Android earlier than APK17 that can cause an "invalid int" exception (*sigh*).

- Colin.
 

Informatix

Expert
Licensed User
Longtime User
Hi Informatix,

Since you are working on the library wrapper, I should let you know about a bug in the existing one that you may or may not be aware of. I'm not sure exactly where the error is (connectNextClient() in GameHelper perhaps?), but you can have a situation where isSignedIn will report true when you actually aren't signed in. This can happen even when you have no internet connection, so I put a workaround in my B4A code that checks that you are connected to the outside world, rather than relying on isSignedIn. The problem with this workaround is that there is a bug in versions of Android earlier than APK17 that can cause an "invalid int" exception (*sigh*).

- Colin.
I changed many things in the main connection class so I hope that I fixed what you're talking about. In my B4A code, I don't trust the value of IsSignedIn because it is based on a variable value, not on an connection check. So here's what I do in Activity_Resume:
B4X:
If GPC.IsSignedIn Then
      GPC.CheckConnections(True)
Else
      GPC.Connect(False)
End If
Explanation: if I'm supposed to be signed in, then I check that I'm really signed-in and reconnect automatically if it's not the case. If I'm not signed in, I connect only if it's not my first attempt (typically, you want to reconnect in Activity_Resume, not initiate a connection).
 

Computersmith64

Well-Known Member
Licensed User
Longtime User
I changed many things in the main connection class so I hope that I fixed what you're talking about. In my B4A code, I don't trust the value of IsSignedIn because it is based on a variable value, not on an connection check. So here's what I do in Activity_Resume:
B4X:
If GPC.IsSignedIn Then
      GPC.CheckConnections(True)
Else
      GPC.Connect(False)
End If
Explanation: if I'm supposed to be signed in, then I check that I'm really signed-in and reconnect automatically if it's not the case. If I'm not signed in, I connect only if it's not my first attempt (typically, you want to reconnect in Activity_Resume, not initiate a connection).

Awesome! Glad you got that sorted. Here's another one for you:

While I was thinking about the stupid error I get when trying to download achievements if not signed in (it's a signature mismatch for the onAchievementsLoaded callback), I thought I would go take another look at the code in the wrapper. In doing so, I found the cause of the mismatch error. Here's the code as it was:

B4X:
@Hide
    public void onAchievementsLoaded(int status, AchievementBuffer arg1) {
        List list1 = new List();
        if (status == GamesClient.STATUS_OK) {
            list1.Initialize();
            for (Achievement ach: arg1){
                AchievementWrapper aw = new AchievementWrapper(ach);
                //Toast.makeText(mBA.context, "Loading " + aw.getName(), Toast.LENGTH_SHORT).show();
                list1.Add(aw);
            }
            //Toast.makeText(mBA.context, "onAchievementsLoaded: ", Toast.LENGTH_SHORT).show();
            mBA.raiseEvent(this, eventName + "_onachievementsloaded", list1);
            return;
        }
        list1 = null;
        mBA.raiseEvent(this, eventName + "_onachievementsloaded", (Object[]) null);
     
    }

(Note the last 2 lines)

And here's what I changed it to:

B4X:
@Hide
    public void onAchievementsLoaded(int status, AchievementBuffer arg1) {
        List list1 = new List();
        list1.Initialize();
        if (status == GamesClient.STATUS_OK) {
            for (Achievement ach: arg1){
                AchievementWrapper aw = new AchievementWrapper(ach);
                //Toast.makeText(mBA.context, "Loading " + aw.getName(), Toast.LENGTH_SHORT).show();
                list1.Add(aw);
            }
            //Toast.makeText(mBA.context, "onAchievementsLoaded: ", Toast.LENGTH_SHORT).show();
            mBA.raiseEvent(this, eventName + "_onachievementsloaded", list1);
            return;
        }
        list1.Add("ERROR");
        mBA.raiseEvent(this, eventName + "_onachievementsloaded", list1);
    }

It appears that the way it was written was the cause of the signature mismatch - I guess because when the load failed, it was sending a null object instead of the initialized list that the onAchievementsLoaded callback sub was expecting in B4A. My fix may not be the correct way to address this (I admit that my Java skills are somewhat lacking), however it does work. In my B4A code, I simply do this:

B4X:
Sub GGS_OnAchievementsLoaded(listAchievements As List)
  
    Try
        If listAchievements.Get(0) = "ERROR" Then
            ToastMessageShow("Can't load achievements.", False)
        Else
            gAL = listAchievements
        End If
    Catch
        Send_Error_Report("GGS_onAchievementsLoaded", LastException.Message & CRLF & "Trace: " & Ex.StackTrace)
    End Try
  
End Sub

May be a bit crude, but it works...

- Colin.
 

Informatix

Expert
Licensed User
Longtime User
Awesome! Glad you got that sorted. Here's another one for you:

While I was thinking about the stupid error I get when trying to download achievements if not signed in (it's a signature mismatch for the onAchievementsLoaded callback), I thought I would go take another look at the code in the wrapper. In doing so, I found the cause of the mismatch error. Here's the code as it was:

B4X:
@Hide
    public void onAchievementsLoaded(int status, AchievementBuffer arg1) {
        List list1 = new List();
        if (status == GamesClient.STATUS_OK) {
            list1.Initialize();
            for (Achievement ach: arg1){
                AchievementWrapper aw = new AchievementWrapper(ach);
                //Toast.makeText(mBA.context, "Loading " + aw.getName(), Toast.LENGTH_SHORT).show();
                list1.Add(aw);
            }
            //Toast.makeText(mBA.context, "onAchievementsLoaded: ", Toast.LENGTH_SHORT).show();
            mBA.raiseEvent(this, eventName + "_onachievementsloaded", list1);
            return;
        }
        list1 = null;
        mBA.raiseEvent(this, eventName + "_onachievementsloaded", (Object[]) null);
    
    }

(Note the last 2 lines)

And here's what I changed it to:

B4X:
@Hide
    public void onAchievementsLoaded(int status, AchievementBuffer arg1) {
        List list1 = new List();
        list1.Initialize();
        if (status == GamesClient.STATUS_OK) {
            for (Achievement ach: arg1){
                AchievementWrapper aw = new AchievementWrapper(ach);
                //Toast.makeText(mBA.context, "Loading " + aw.getName(), Toast.LENGTH_SHORT).show();
                list1.Add(aw);
            }
            //Toast.makeText(mBA.context, "onAchievementsLoaded: ", Toast.LENGTH_SHORT).show();
            mBA.raiseEvent(this, eventName + "_onachievementsloaded", list1);
            return;
        }
        list1.Add("ERROR");
        mBA.raiseEvent(this, eventName + "_onachievementsloaded", list1);
    }

It appears that the way it was written was the cause of the signature mismatch - I guess because when the load failed, it was sending a null object instead of the initialized list that the onAchievementsLoaded callback sub was expecting in B4A. My fix may not be the correct way to address this (I admit that my Java skills are somewhat lacking), however it does work. In my B4A code, I simply do this:

B4X:
Sub GGS_OnAchievementsLoaded(listAchievements As List)
 
    Try
        If listAchievements.Get(0) = "ERROR" Then
            ToastMessageShow("Can't load achievements.", False)
        Else
            gAL = listAchievements
        End If
    Catch
        Send_Error_Report("GGS_onAchievementsLoaded", LastException.Message & CRLF & "Trace: " & Ex.StackTrace)
    End Try
 
End Sub

May be a bit crude, but it works...

- Colin.
I'm rewriting all the classes so I hope that these little bugs will be fixed. Currently all classes and methods for a turn-based game are functional and documented. I will add the real-time support + achievements and leaderboards later because I don't really need them. I should be able to deliver a first alpha version before the end of the week.
 

Computersmith64

Well-Known Member
Licensed User
Longtime User
I'm rewriting all the classes so I hope that these little bugs will be fixed. Currently all classes and methods for a turn-based game are functional and documented. I will add the real-time support + achievements and leaderboards later because I don't really need them. I should be able to deliver a first alpha version before the end of the week.

No worries - appreciate what you are doing & look forward to seeing the result.
 

Bas Hamstra

Member
Licensed User
Longtime User
Ditto! Turnbased game support would be AWSOME! If you could include a tiny test app in B4A for humble peasants like me? With

- Login G+
- Send an invite
- Accept an invite
- Set up and connect to a room
- Send a RT message to a player in the room

my prayers would be answered, and not only that, but there are very very few turnbased games for B4A and this could really really changed that! I have written a little quoridor app in B4A that currently only plays (decent) against computer and I would love to bring it online. Awsome strategic game. Google it!

Kind regards,

Bas
 

Informatix

Expert
Licensed User
Longtime User
Ditto! Turnbased game support would be AWSOME! If you could include a tiny test app in B4A for humble peasants like me? With

- Login G+
- Send an invite
- Accept an invite
- Set up and connect to a room
- Send a RT message to a player in the room

my prayers would be answered, and not only that, but there are very very few turnbased games for B4A and this could really really changed that! I have written a little quoridor app in B4A that currently only plays (decent) against computer and I would love to bring it online. Awsome strategic game. Google it!

Kind regards,

Bas
You should be able to test that tomorrow. :)
Note that does not work with a room (rooms are for real-time).
 

Informatix

Expert
Licensed User
Longtime User

LucaMs

Expert
Licensed User
Longtime User
Thanks, informatix.

But I suppose this would be a huge job; also your comment ...!
Here's the last alpha version (0.7). I think that my work is finished with Leaderboards but they are completely untested. I stop working on this library because Google just published a new version (v15) which deprecates all my work (they replaced the current classes and functions with a new API). I won't rewrite everything once more.

In addition, I need multplayer, "multirooms", interactivity... too much stuff.

What I would need would be a "simple" tutorial about the many operations to be performed with these Google services but ... in Italian!

I still have not decided to get a Google Account; this fact "probably" slightly complicates things :)


Thanks, anyway
 
Top