"signInSilently():失败";尝试使用LibGDX登录GooglePlay游戏服务时 [英] "signInSilently(): failure" when trying to sign in to GooglePlay Game Services with LibGDX
问题描述
过去3天,我一直在尝试将Google Game Services
添加到我的LibGDX项目中,起初我尝试了LibGDX教程,但它们似乎都已经过时了.然后,我被建议使用Google Game Services的官方代码
I have been trying to add Google Game Services
to my LibGDX project for the past 3 days now at first I tried the LibGDX tutorials but all of them seem to be outdated. Then I was advised to use the Google Game Services official code
我导入了示例项目 TypeANumber ,并试图将代码添加到我的项目中,但是当我尝试登录时,我得到了"signInSilently(): failure" error
,当我尝试打开排行榜和调试以及签名的APKS上的成就时,它崩溃了.
I imported the sample project TypeANumber and tried to add the code to my project but when I try to sign in I'm getting the "signInSilently(): failure" error
and it crashes when I try to open the leaderboards and achievements on both the debug and signed APKS.
这是我的代码:
AndroidLauncher:
AndroidLauncher:
private void signInSilently() {
Log.d(TAG, "signInSilently()");
mGoogleSignInClient.silentSignIn().addOnCompleteListener(this,
new OnCompleteListener<GoogleSignInAccount>() {
@Override
public void onComplete(@NonNull Task<GoogleSignInAccount> task) {
if (task.isSuccessful()) {
Log.d(TAG, "signInSilently(): success");
onConnected(task.getResult());
} else {
Log.d(TAG, "signInSilently(): failure", task.getException());
onDisconnected();
}
}
});
}
@Override
public void showLeaderboards(){
runOnUiThread(new Runnable() {
public void run() {
onShowLeaderboardsRequested();
}
});
}
@Override
public void showAchievements(){
runOnUiThread(new Runnable() {
public void run() {
onShowAchievementsRequested();
}
});
}
清单:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.harrybanda.blaster" >
<uses-sdk android:minSdkVersion="14" android:targetSdkVersion="27" />
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<meta-data android:name="com.google.android.gms.games.APP_ID"
android:value="@string/app_id" />
<meta-data android:name="com.google.android.gms.version"
android:value="@integer/google_play_services_version"/>
<application
android:allowBackup="true"
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@style/GdxTheme" >
<activity
android:name="com.google.android.gms.ads.AdActivity"
android:configChanges="keyboard|keyboardHidden|orientation|screenLayout|uiMode|screenSize|smallestScreenSize"
android:theme="@android:style/Theme.Translucent" />
<activity
android:name="com.harrybanda.blaster.AndroidLauncher"
android:label="@string/app_name"
android:screenOrientation="portrait"
android:configChanges="keyboard|keyboardHidden|orientation|screenSize">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
在我的build.gradle中添加:
In my build.gradle i added:
compile "com.google.android.gms:play-services-games:11.8.0"
compile "com.google.android.gms:play-services-auth:11.8.0"
Logcat:
01-07 09:56:30.011 618-618/? D/Blaster: onResume()
01-07 09:56:30.011 618-618/? D/Blaster: signInSilently()
01-07 09:56:30.512 618-618/? D/Blaster: signInSilently(): failure
com.google.android.gms.common.api.b: 4:
at com.google.android.gms.common.internal.y.a(Unknown Source)
at com.google.android.gms.common.internal.ae.a(Unknown Source)
at com.google.android.gms.common.internal.af.a(Unknown Source)
at com.google.android.gms.common.api.internal.BasePendingResult.c(Unknown Source)
at com.google.android.gms.common.api.internal.BasePendingResult.a(Unknown Source)
at com.google.android.gms.auth.api.signin.internal.g.a(Unknown Source)
at com.google.android.gms.auth.api.signin.internal.r.onTransact(Unknown Source)
at android.os.Binder.execTransact(Binder.java:451)
01-07 09:56:30.512 618-618/? D/Blaster: onDisconnected()
推荐答案
从问题的1 st 看,似乎您将元数据保留在应用程序标记之外,但应该在应用程序内部AndroidManifest.xml
文件
From 1st look of your question, It seems that you're keeping meta data outside the application tag but should be inside application tag in AndroidManifest.xml
file
喜欢这个:
<application
android:allowBackup="true"
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@style/GdxTheme" >
<activity
android:name="com.google.android.gms.ads.AdActivity"
android:configChanges="keyboard|keyboardHidden|orientation|screenLayout|uiMode|screenSize|smallestScreenSize"
android:theme="@android:style/Theme.Translucent" />
<activity
android:name="com.harrybanda.blaster.AndroidLauncher"
android:label="@string/app_name"
android:screenOrientation="portrait"
android:configChanges="keyboard|keyboardHidden|orientation|screenSize">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<meta-data android:name="com.google.android.gms.games.APP_ID"
android:value="@string/app_id" />
<meta-data android:name="com.google.android.gms.version"
android:value="@integer/google_play_services_version"/>
</application>
StatusCode 4(SIGN_IN_REQUIRED)错误表示客户端尝试执行以下操作: 连接到服务,但用户未登录.
StatusCode 4 (SIGN_IN_REQUIRED) error means client attempted to connect to the service but the user is not signed in.
这是我的AndroidLauncher
课
public class AndroidLauncher extends AndroidApplication implements MyServices {
private GoogleSignInClient mGoogleSignInClient;
private LeaderboardsClient mLeaderboardsClient;
private PlayersClient mPlayersClient;
private static final String TAG=AndroidLauncher.class.getSimpleName();
private static final int RC_SIGN_IN = 9001;
private static final int RC_UNUSED = 5001;
private static final int RC_LEADERBOARD_UI = 9004;
private String greetingMsg="Welcome, ";
private boolean greetingDisplayed;
@Override
protected void onCreate (Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
greetingDisplayed=false;
AndroidApplicationConfiguration config = new AndroidApplicationConfiguration();
initialize(new GdxGame(this), config);
mGoogleSignInClient = GoogleSignIn.getClient(this,
new GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_GAMES_SIGN_IN).build());
}
@Override
public boolean isSignedIn() {
return GoogleSignIn.getLastSignedInAccount(this) != null;
}
private void signInSilently() {
mGoogleSignInClient.silentSignIn().addOnCompleteListener(this,
new OnCompleteListener<GoogleSignInAccount>() {
@Override
public void onComplete(@NonNull Task<GoogleSignInAccount> task) {
if (task.isSuccessful()) {
greetingMsg="Welcome back, ";
onConnected(task.getResult());
} else {
onDisconnected();
}
}
});
}
private void onConnected(GoogleSignInAccount googleSignInAccount) {
mLeaderboardsClient = Games.getLeaderboardsClient(this, googleSignInAccount);
mPlayersClient = Games.getPlayersClient(this, googleSignInAccount);
mPlayersClient.getCurrentPlayer()
.addOnCompleteListener(new OnCompleteListener<Player>() {
@Override
public void onComplete(@NonNull Task<Player> task) {
String displayName;
if (task.isSuccessful()) {
displayName = task.getResult().getDisplayName();
} else {
Exception e = task.getException();
handleException(e, getString(R.string.players_exception));
displayName = "???";
}
if(!greetingDisplayed)
welcomeMessage(displayName);
}
});
}
private void welcomeMessage(String name){
Toast toast = Toast.makeText(this, greetingMsg + name, Toast.LENGTH_LONG);
toast.setGravity(Gravity.TOP, 0, 0);
View view = toast.getView();
TextView text = (TextView) view.findViewById(android.R.id.message);
toast.show();
greetingDisplayed=true;
}
@Override
public void startSignInIntent() {
startActivityForResult(mGoogleSignInClient.getSignInIntent(), RC_SIGN_IN);
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent intent) {
super.onActivityResult(requestCode, resultCode, intent);
if (requestCode == RC_SIGN_IN) {
Task<GoogleSignInAccount> task = GoogleSignIn.getSignedInAccountFromIntent(intent);
try {
GoogleSignInAccount account = task.getResult(ApiException.class);
greetingMsg="Welcome, ";
onConnected(account);
} catch (ApiException apiException) {
String message = apiException.getMessage();
if (message == null || message.isEmpty()) {
message = getString(R.string.signin_other_error);
}
onDisconnected();
}
}
}
@Override
protected void onResume() {
super.onResume();
signInSilently();
}
private void signOut() {
if (!isSignedIn()) {
Log.w(TAG, "signOut() called, but was not signed in!");
return;
}
mGoogleSignInClient.signOut().addOnCompleteListener(this,
new OnCompleteListener<Void>() {
@Override
public void onComplete(@NonNull Task<Void> task) {
boolean successful = task.isSuccessful();
Log.d(TAG, "signOut(): " + (successful ? "success" : "failed"));
onDisconnected();
}
});
}
private void onDisconnected() {
mLeaderboardsClient = null;
mPlayersClient = null;
}
@Override
public void submitScore(int score){
if(isSignedIn())
mLeaderboardsClient.submitScore(getString(R.string.leaderboard_id), score);
}
@Override
public void showLeaderBoard() {
if(isSignedIn())
mLeaderboardsClient.getLeaderboardIntent(getString(R.string.leaderboard_id))
.addOnSuccessListener(new OnSuccessListener<Intent>() {
@Override
public void onSuccess(Intent intent) {
startActivityForResult(intent, RC_LEADERBOARD_UI);
}
});
}
private void handleException(Exception e, String details) {
int status = 0;
if (e instanceof ApiException) {
ApiException apiException = (ApiException) e;
status = apiException.getStatusCode();
}
String message = getString(R.string.status_exception_error, details, status, e);
new AlertDialog.Builder(this)
.setMessage(message)
.setNeutralButton(android.R.string.ok, null)
.show();
}
}
和MyServices
界面
interface MyServices{
void startSignInIntent();
boolean isSignedIn();
void showLeaderBoard();
void submitScore(int score);
}
在用户安装应用程序后,我第一次自己调用界面的startSignInIntent()
.
First time I call startSignInIntent()
of interface by myself after user install app.
这篇关于"signInSilently():失败";尝试使用LibGDX登录GooglePlay游戏服务时的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!