play-games-plugin-for-unity
play-games-plugin-for-unity copied to clipboard
AndroidJavaException: java.lang.NoSuchMethodError
When calling PlayGamesPlatform.Instance.LoadScores
I am getting this error: AndroidJavaException: java.lang.NoSuchMethodError: no non-static method with name='getStatusCode' signature='()I' in class Ljava.lang.Object;
I'm using 0.10.12 GPS unity package
this does not occur if I go to 0.9.64 GPS unity package
Any guidance would be great! Steve
Same with PlayGamesPlatform.Instance.SavedGame.OpenWithAutomaticConflictResolution using 0.10.12
Same with PlayGamesPlatform.Instance.SavedGame.OpenWithAutomaticConflictResolution using 0.10.12
Same thing.
I can confirm the exact same message as the above people using 0.10.12. This was not happening in previous versions. This is also failing on the PlayGamesPlatform.Instance.SavedGame.OpenWithAutomaticConflictResolution call above.
The weird thing is that it is only happening on some devices. I am currently testing on a Samsung A30 on Android 10 (security patch 1st March 2021) where it all works perfectly, but another phone using the exact same Google Play log in, which is the Oppo AX5s on Android 8.1.0 (security patch 5th Feburary 2021) is failing with the issue above.
When calling PlayGamesPlatform.Instance.LoadScores
I am getting this error: AndroidJavaException: java.lang.NoSuchMethodError: no non-static method with name='getStatusCode' signature='()I' in class Ljava.lang.Object;
I'm using 0.10.12 GPS unity package
this does not occur if I go to 0.9.64 GPS unity package
Any guidance would be great! Steve
Same problem!
same
Just as something else I have seen with this issue, it seems like it is affecting logging into the Google Play Games account on the device that it affects. Here is the current flow of what I am observing:
- Game Starts, The "Hi There, [ACCOUNT_NAME]" message shows up.
- Game attempts to download the Cloud Save for this user, but we get the error: AndroidJavaException: java.lang.NoSuchMethodError: no non-static method with name='getStatusCode' signature='()I' in class Ljava.lang.Object;
- When we enter into our Settings Menu, sometimes the game will detect that we have been logged in (using Social.localUser.authenticated), but occasionally we will be signed out again, so we have to manually sign back in.
- We have a button in game that attempts to save the data to the cloud, but when we call the ((PlayGamesPlatform)Social.Active).SavedGame.CommitUpdate, it returns back an error with AuthenticationError, which should only happen if the user isn't signed in.
This is happening on the Oppo AX5s on Google Play Services plugin 0.10.12, but everything works fine on a Samsung A30.
As a side note, these same devices work with this plugin on one of our other games, with the exact same code, but running on 0.10.04.
Any help on how to fix this is appreciated, as it is breaking almost all of our Google interactions on these devices.
I made a quick temporary fix, not beautiful, but it worked for me. Here is the idea: In my case error happens inside AndroidSavedGameClient.cs in method 'AddOnFailureListenerWithSignOut' We add 'AddOnFailureListener' and try to call 'getStatusCode' from Exception object. But 'getStatusCode' is method for ApiException, which inherited from Exception. Exception doesn't have this method. I think this is the problem. So I cast Exception to ApiException if it possible, and after that trying to call getStatusCode. I do it in java class and call it from Unity.
Unity method which I'm calling instead of 'getStatusCode':
public static int GetStatusCode(AndroidJavaObject exception) { using (var native = new AndroidJavaClass("com.<yourcompanyname>.ExceptionsUtils")) { return native.CallStatic<int>("GetStatusCode", exception); } }
Code for native java class:
import com.google.android.gms.common.api.ApiException; import com.google.android.gms.common.api.CommonStatusCodes; @UnityCallable public class ExceptionsUtils { @UnityCallable public static int GetStatusCode(Exception ex) { if (ex instanceof ApiException) { return ((ApiException) ex).getStatusCode(); } return CommonStatusCodes.ERROR; } }
Also I replaced the same way other cases of using 'getStatusCode' for Exception object
Hey @MoodyMuffin ,
Thanks for the heads up on a way to fix this issue. I have used the code that you have provided, but I don't seem to be having much luck getting the c# code to nicely work with the native function. I've double checked on how to implement native .java classes (it seems like they made it much easier than it used to be before 2018.3), although I keep getting the NoSuchMethodError on the GetStatusCode call. Do you know if there is any specific location that the java file needs to exist (e.g. Plugins/Android), or defining the package of the java file (or does it only use the Package Name), or affected by Gradle build settings?
Any pointers on this would be appreciated!
Hey @MoodyMuffin ,
Thanks for the heads up on a way to fix this issue. I have used the code that you have provided, but I don't seem to be having much luck getting the c# code to nicely work with the native function. I've double checked on how to implement native .java classes (it seems like they made it much easier than it used to be before 2018.3), although I keep getting the NoSuchMethodError on the GetStatusCode call. Do you know if there is any specific location that the java file needs to exist (e.g. Plugins/Android), or defining the package of the java file (or does it only use the Package Name), or affected by Gradle build settings?
Any pointers on this would be appreciated!
Hey In java file I define package name, like: 'package com.A.B.C.D;' java file is located inside app/src/main/java/com/A/B/C/D And in C# file I call new AndroidJavaClass("com.A.B.C.D.ExceptionsUtils")
Also, this package is added in proguard-unity.txt, maybe you should try it too
Thanks, After double checking, the java file does indeed get exported to the app/src/main/java/com/... directory when I build a gradle project, and I have defined the package name to be the same in the Java script and the C# script. The only main difference I have between the code is the that I let Unity generate the proguard-unity.txt, and that I am unable to get @UnityCallable compiling as it "Cannot Find Symbol". From what I have read up, it seems like just an interface in the Facebook plugin, but it doesn't seem like it does too much, and other examples I have seen do not require it.
I do hate Unity's lack of documentation on this stuff though, which would make things much easier than just a few dot points.
We just ran into the exact same issue after adding a 2nd OAuth credential (to be able to test Games Services when building locally with the Debug certificate). In our case, it seems like the problem was related to Saved Games. Turns out we had a cloud save that had been uploaded from an Internal Test version of the app, signed with Play App Signing. The app signed with the Debug certificate was not able to download this cloud save and crashed with the NoSuchMethodError
(getStatusCode).
We were able to solve it by deleting the Play Games data for the game through the Play Games app (Settings > Delete Play Games account & data
). Not sure if this is the same issue that you guys are having, but it might be worth a try if you're using multiple OAuth credentials.
I'm still looking for a perfect solution but figure this will help the community find the actual problem. based on what @MoodyMuffin said I use this c# code that has an extension function that casts the AndroidJavaObject to com.google.android.gms.common.api.ApiException without having to use a java plugin.
So far I see that the object has been of 3 types: "com.google.android.gms.common.api.ApiException", "com.google.games.bridge.TokenResult", "java.lang.IllegalStateException" // doesnt have getStatusCode function
By doing this I was able to see this error:
I/Unity: LoadScores failed: java.lang.IllegalStateException: Max results must be between 1 and 30
I think the bug might be related to this somehow...
Waiting to hear if anyone has any improvements or better solutions heres the code:
using System;
using System.Collections;
using System.Collections.Generic;
using GooglePlayGames.BasicApi;
using UnityEngine;
public static class AndroidJavaObjectUtilities
{
public static AndroidJavaObject ClassForName(string className)
{
using (var clazz = new AndroidJavaClass("java.lang.Class"))
{
return clazz.CallStatic<AndroidJavaObject>("forName", className);
}
}
// Cast extension method
public static AndroidJavaObject Cast(this AndroidJavaObject source, string destClass)
{
using (var destClassAJC = ClassForName(destClass))
{
return destClassAJC.Call<AndroidJavaObject>("cast", source);
}
}
public static int GetStatusCode(this AndroidJavaObject exception)
{
string[] casts = new string[]
{
"com.google.android.gms.common.api.ApiException",
"com.google.games.bridge.TokenResult",
"java.lang.IllegalStateException" // doesnt have getStatusCode function
};
int res;
foreach (var cast in casts)
{
res = GetStatusCode(exception, cast);
if (res != int.MinValue)
{
Debug.LogFormat("casted to {0} and returnes {1}", cast, res);
return res;
}
}
Debug.Log("failed to cast returning error code error");
return (int)CommonStatusCodes.Error;
}
public static int GetStatusCode(this AndroidJavaObject exception, string castClass)
{
try
{
// com.google.games.bridge.TokenResult
//using (var apiException = exception.Cast("com.google.android.gms.common.api.ApiException"))
using (var apiException = exception.Cast(castClass))
{
return apiException.Call<int>("getStatusCode");
}
}
catch (Exception e)
{
Debug.LogWarning("Failed to cast to ApiException. Error: " + e.Message);
//return (int)CommonStatusCodes.Error;
return int.MinValue;
}
}
}
There's still a bug with public void LoadScores(ILeaderboard board, Action
https://github.com/playgameservices/play-games-plugin-for-unity/issues/2803
changed this:
mClient.LoadScores(
board.id,
LeaderboardStart.PlayerCentered,
board.range.count > 0 ? board.range.count : mClient.LeaderboardMaxResults(),
board.userScope == UserScope.FriendsOnly ? LeaderboardCollection.Social : LeaderboardCollection.Public,
timeSpan,
(scoreData) => HandleLoadingScores(
(PlayGamesLeaderboard)board, scoreData, callback));
to this:
mClient.LoadScores(
board.id,
LeaderboardStart.PlayerCentered,
Math.Min(board.range.count, mClient.LeaderboardMaxResults()), //10,
board.userScope == UserScope.FriendsOnly ? LeaderboardCollection.Social : LeaderboardCollection.Public,
timeSpan,
(scoreData) => HandleLoadingScores(
(PlayGamesLeaderboard)board, scoreData, callback));
Still getting the error though..
Hi folks, until some seconds ago, I was fighting against this issue. But, I found a problem in my code. I was building a Metadata with a PNG cover data with a Array Lenght equals zero.
SavedGameMetadataUpdate.Builder builder = new SavedGameMetadataUpdate.Builder();
builder = builder
.WithUpdatedPlayedTime(TimeSpan.FromSeconds(Time.unscaledTime))
.WithUpdatedDescription("Saved game at " + DateTime.Now);
builder = builder.WithUpdatedPngCoverImage(new byte[0]); //WRONG LINE
I just remove this wrong line and solved. tadãh!
I suposse that I must pass a array with length zero in case without a png cover.
Im still getting this message "Max results must be between 1 and 30" from the HandleLoadingScores function sending rowcount=75 . I tried maxing it to 25, that get rid of the message but I'm not getting the leaderboard results. any ideas?
internal void HandleLoadingScores(
PlayGamesLeaderboard board,
LeaderboardScoreData scoreData,
Action<bool> callback)
{
bool ok = board.SetFromData(scoreData);
if (ok && !board.HasAllScores() && scoreData.NextPageToken != null)
{
int rowCount = board.range.count - board.ScoreCount;
// rowCount = Math.Min(rowCount, mClient.LeaderboardMaxResults());
// need to load more scores
mClient.LoadMoreScores(
scoreData.NextPageToken,
rowCount,
(nextScoreData) =>
HandleLoadingScores(board, nextScoreData, callback));
}
else
{
callback(ok);
}
}
@aerialninja I see you made some changes to the github What do you think about this change? https://github.com/playgameservices/play-games-plugin-for-unity/issues/3002#issuecomment-825010982
What do we need to do to get it in the next build and to make sure it's correct? what's the procces? thanks in advance!
Had same issue. Problem was in play services initialization: I forgot to add .EnableSavedGames() while setup confuguration.
Same issue. I don't know why it appears. Sometimes I sign in successfully but sometimes this error occures and I can't load my saved game. Logs: https://justpaste.it/98hbi Code PlayGames.cs: https://paste.ofcode.org/YjuUgCjp75ndzJ9PZg9iJt SaveManager.cs: https://paste.ofcode.org/7ts3dtEjHqPrxmH5hCHysA CloudSaveController.cs: https://paste.ofcode.org/34LujFi7MqjcvK7PkL2dfR2
GooglePlayGames Plugin Version is 0.10.12
We also started having the same error @MarkMa-LS mentioned above started yesterday. We saw some errors related to SaveGames API but we fixed those by updating the SHA-1. It did decrease the amount but we still have a lot of AndroidJavaException: java.lang.NoSuchMethodError: no non-static method with name='getStatusCode' signature='()I' in class Ljava.lang.Object;
coming from players. We also have 2 devices within the team having the same issue. GCP window pops up but then throws this error.
We also started having the same error @MarkMa-LS mentioned above started yesterday. We saw some errors related to SaveGames API but we fixed those by updating the SHA-1. It did decrease the amount but we still have a lot of
AndroidJavaException: java.lang.NoSuchMethodError: no non-static method with name='getStatusCode' signature='()I' in class Ljava.lang.Object;
coming from players. We also have 2 devices within the team having the same issue. GCP window pops up but then throws this error.
While developing the game further, I haven't seen this problem for the last two days, but is there a 100% fix for it?
I was getting this error while trying to get all time high score of the current user. I changed my code from this:
PlayGamesPlatform.Instance.LoadScores(
GPGSIds.leaderboard_test,
LeaderboardStart.PlayerCentered,
100,
LeaderboardCollection.Public,
LeaderboardTimeSpan.AllTime,
data => {
if (data.PlayerScore == null) {
Debug.Log("User has no Score on leaderboard");
} else {
Debug.Log(data.Valid);
Debug.Log(data.Id);
Debug.Log(data.PlayerScore);
Debug.Log(data.PlayerScore.userID);
Debug.Log(data.PlayerScore.formattedValue);
}
});
to this:
PlayGamesPlatform.Instance.LoadScores(
GPGSIds.leaderboard_test,
LeaderboardStart.PlayerCentered,
1,
LeaderboardCollection.Public,
LeaderboardTimeSpan.AllTime,
data => {
if (data.PlayerScore == null) {
Debug.Log("User has no Score on leaderboard");
} else {
Debug.Log(data.Valid);
Debug.Log(data.Id);
Debug.Log(data.PlayerScore);
Debug.Log(data.PlayerScore.userID);
Debug.Log(data.PlayerScore.formattedValue);
}
});
and the error dissapeared.
We've been seeing this exception as well when trying to load saved games resulting in the callback never being called and players being stuck on loading screens. Is there any workaround for this?
We've been seeing this exception as well when trying to load saved games resulting in the callback never being called and players being stuck on loading screens. Is there any workaround for this?
Same here !!!!
Guys, Are you sure you have enabled Saved Games on Developer Console?
Same here, this error pops up on some (not all) devices when trying to load a cloud save with version 10.12. Need a fix ASAP
1- Try Using the Plugin Without Overriding the Default Social Platform ( https://github.com/playgameservices/play-games-plugin-for-unity#advanced-using-the-plugin-without-overriding-the-default-social-platform )
2- make sure you have enabled "saved game" on google play developer console
3- if you are using proguard check this ( https://github.com/playgameservices/play-games-plugin-for-unity#decreasing-apk-size )
number (1) resolved my problem, (2) and (3) were also problems with my project
I had the same issue, and wasted a couple hours to try and solve it because of poor error handling from the plugin. I was just trying to get the player high score, so called PlayGamesPlatform.Instance.LoadScores with a rowCount of 0 (because I have no interest in other players scores..) When I changed it to 1, it started working. If I had an explicit error message, it'd had been just a matter of seconds, but poor error handling + large iteration time (because everything only works on device) is a bad combination.
To be able to read a proper error message, I modified AndroidClient.AddOnFailureListenerWithSignOut to just silent the exception. It's bad but for development time it helps a lot.
private void AddOnFailureListenerWithSignOut(AndroidJavaObject task, Action<AndroidJavaObject> callback)
{
AndroidTaskUtils.AddOnFailureListener(
task,
exception =>
{
try
{
var statusCode = exception.Call<int>("getStatusCode");
if (statusCode == /* CommonStatusCodes.SignInRequired */ 4 ||
statusCode == /* GamesClientStatusCodes.CLIENT_RECONNECT_REQUIRED */ 26502)
{
SignOut();
}
}
catch (Exception)
{
}
callback(exception);
});
}
Guys, Are you sure you have enabled Saved Games on Developer Console?
I didn't bother checking this because I KNEW I had this enabled! But after reading I thought "Ah you know what I'll double check it" Lesson being, always double check! F#cker was NOT enabled!
We just ran into the exact same issue after adding a 2nd OAuth credential (to be able to test Games Services when building locally with the Debug certificate). In our case, it seems like the problem was related to Saved Games. Turns out we had a cloud save that had been uploaded from an Internal Test version of the app, signed with Play App Signing. The app signed with the Debug certificate was not able to download this cloud save and crashed with the
NoSuchMethodError
(getStatusCode).We were able to solve it by deleting the Play Games data for the game through the Play Games app (
Settings > Delete Play Games account & data
). Not sure if this is the same issue that you guys are having, but it might be worth a try if you're using multiple OAuth credentials.
Well even after my previous post and enabling Saved Games in the console I still received an error. But it turns out that removing my games data from the Google Play Games app within its settings did the trick! I was able to successfully save my game data to Google Cloud after I did this. Hoo-rah...
About the noSuchMethod error. getStatusCode is called via JNI in two locations: AndroidClient and AndroidSavedGameClients. The methods are similar but with a crucial difference: a check for `Misc.IsApiException' is missing in AndroidClient.
Adding it should fix the problem. This is valid for 0.10.14
private void AddOnFailureListenerWithSignOut(AndroidJavaObject task, Action<AndroidJavaObject> callback)
{
AndroidTaskUtils.AddOnFailureListener(
task,
exception =>
{
if( Misc.IsApiException(exception) )
{
var statusCode = exception.Call<int>("getStatusCode");
if( statusCode == /* CommonStatusCodes.SignInRequired */ 4 ||
statusCode == /* GamesClientStatusCodes.CLIENT_RECONNECT_REQUIRED */ 26502 )
{
SignOut();
}
}
callback(exception);
});
}