I have been asking questions related to my Libgdx game Google play game services configuration error. Up-till now I have solved sign in errors but Now I am stuck at Unlock Achievements. So I am posting my code may Be some one can help me out then.
Here Is my ActionResolver Interface That I created In Core Libgdx project
package com.------.game;
public interface ActionResolver {
public boolean getSignedInGPGS();
public void loginGPGS();
public void submitScoreGPGS(int score);
public void unlockAchievementGPGS(String achievementId);
public void getLeaderboardGPGS();
public void getAchievementsGPGS();
public void onShowAchievementsRequested() ;
}
My AndroidLauncher class is
package com.------.game.android;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import android.widget.Toast;
import com.badlogic.gdx.Game;
import com.badlogic.gdx.backends.android.AndroidApplication;
import com.badlogic.gdx.backends.android.AndroidApplicationConfiguration;
import com.google.android.gms.analytics.GoogleAnalytics;
import com.google.android.gms.analytics.HitBuilders;
import com.google.android.gms.analytics.Tracker;
import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.api.GoogleApiClient;
import com.google.android.gms.games.Games;
import com.google.android.gms.plus.Plus;
import com.google.example.games.basegameutils.BaseGameUtils;
import com.google.example.games.basegameutils.GameHelper;
import com.google.example.games.basegameutils.GameHelper.GameHelperListener;
import com.-----.game.ActionResolver;
import com.-----.game.MainGame;
public class AndroidLauncher extends AndroidApplication implements
ActionResolver, GameHelperListener , GoogleApiClient.ConnectionCallbacks,
GoogleApiClient.OnConnectionFailedListener
{
private GameHelper gameHelper;
private GoogleApiClient client;
private Exception e;
final String TAG = "TanC";
private boolean mResolvingConnectionFailure = false;
// Has the user clicked the sign-in button?
private boolean mSignInClicked = false;
// Automatically start the sign-in flow when the Activity starts
private boolean mAutoStartSignInFlow = true;
// request codes we use when invoking an external activity
// private static final int RC_RESOLVE = 5000;
private static final int RC_UNUSED = 5001;
private static final int RC_SIGN_IN = 9001;
// tag for debug logging
final boolean ENABLE_DEBUG = true;
// playing on hard mode?
boolean mHardMode = false;
private int Score;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Score= 100;
client = new GoogleApiClient.Builder(this)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.addApi(Plus.API).addScope(Plus.SCOPE_PLUS_LOGIN)
.addApi(Games.API).addScope(Games.SCOPE_GAMES)
.build();
GameHelper.GameHelperListener gameHelperListener = new GameHelper.GameHelperListener() {
#Override
public void onSignInFailed() {
Log.i("Game Helper", "Sign in failed");
}
#Override
public void onSignInSucceeded() {
Log.i("Game Helper", "Sign in succeeded");
}
};
if (gameHelper == null) {
gameHelper = new GameHelper(this, GameHelper.CLIENT_GAMES);
gameHelper.enableDebugLog(true);
}
AndroidApplicationConfiguration config = new AndroidApplicationConfiguration();
initialize(new MainGame(this), config); // or initialize (game,
// config);
// gameHelper.setPlusApiOptions(PlusOptions.builder().build());
// no title is needed
gameHelper.setup(gameHelperListener );
// gameHelper.setup(gameHelperListener );
}
#Override
public void onStart() {
super.onStart();
gameHelper.onStart(this);
client.connect();
}
#Override
public void onStop() {
super.onStop();
// ...
gameHelper.onStop();
if (client.isConnected()) {
client.disconnect();
}
}
#Override
public void loginGPGS() {
try {
runOnUiThread(new Runnable() {
public void run() {
gameHelper.beginUserInitiatedSignIn();
}
});
} catch (final Exception ex) {
e.printStackTrace ();
}
}
#Override
public void unlockAchievementGPGS(String achievementId) {
if ( getSignedInGPGS()) {
if(Score>=100){
unlockAchievementGPGS("ABC-------");
}
Games.Achievements.unlock(client, getString(R.string.achievement_Trekker));
}
}
#Override
public void getLeaderboardGPGS() {
}
#Override
public void getAchievementsGPGS() {
if (gameHelper.isSignedIn()) {
startActivityForResult(
Games.Achievements.getAchievementsIntent(gameHelper
.getApiClient()), 101);
} else if (!gameHelper.isConnecting()) {
loginGPGS();
}
}
#Override
public void submitScoreGPGS( int score) {
submitScoreGPGS(Score);
// game.actionResolver.submitScoreGPGS(world.score);
}
#Override
public void onActivityResult(int request, int response, Intent data) {
super.onActivityResult(request, response, data);
gameHelper.onActivityResult(request, response, data);
}
#Override
public boolean getSignedInGPGS() {
return gameHelper.isSignedIn();
}
private boolean isSignedIn() {
return (client!= null && client.isConnected());
}
#Override
public void onShowAchievementsRequested() {
if (isSignedIn()) {
startActivityForResult(Games.Achievements.getAchievementsIntent(client),
RC_UNUSED);
} else {
BaseGameUtils.makeSimpleDialog(this, getString(R.string.achievement_Trekker)).show();
}
}
#Override
public void onSignInFailed() {
}
#Override
public void onSignInSucceeded() {
}
#Override
public void onConnectionFailed(ConnectionResult arg0) {
Log.d(TAG, "onConnectionFailed(): attempting to resolve");
/* if (mResolvingConnectionFailure) {
Log.d(TAG, "onConnectionFailed(): already resolving");
return;
}
if (mSignInClicked || mAutoStartSignInFlow) {
mAutoStartSignInFlow = false;
mSignInClicked = false;
mResolvingConnectionFailure = true;
if (!BaseGameUtils.resolveConnectionFailure(this, client, connectionResult,
RC_SIGN_IN, getString(R.string.unknown_error))) {
mResolvingConnectionFailure = false;
}*/
}
#Override
public void onConnected(Bundle arg0) {
Log.i("Google API", "onConnected(): connected to Google APIs");
}
#Override
public void onConnectionSuspended(int arg0) {
Log.d(TAG, "onConnectionSuspended(): attempting to connect");
client.connect();
}
}
This score int that has a value of 100 I just tried to test if it helps to unlock achievement.
My MainGame class in Core project is
package com.----------.game;
import com.badlogic.gdx.Application.ApplicationType;
import com.badlogic.gdx.Game;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.graphics.Texture;
import com.badlogic.gdx.graphics.g2d.SpriteBatch;
import com.-------.helpers.AssetLoader;
import com.------.screens.FirstSplash;
public class MainGame extends Game {
SpriteBatch batch;
Texture img;
public ActionResolver actionResolver;
Game game;
public MainGame(ActionResolver actionresolver) {
this.actionResolver = actionresolver;
}
#Override
public void create() {
Gdx.app.log("Game", "created");
AssetLoader.load();
setScreen(new FirstSplash(this));
}
public void show() {
Gdx.app.log("my Splash Screen", "show called");
if (Gdx.app.getType() == ApplicationType.Android) {
actionResolver.getSignedInGPGS();
actionResolver.submitScoreGPGS(110);
actionResolver.unlockAchievementGPGS("ABC-----");
} else {
actionResolver.loginGPGS();
}
}
#Override
public void dispose() {
super.dispose();
AssetLoader.dispose();
}
}
My Android Manifest File is
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.--------.game.android"
android:versionCode="2"
android:versionName="1.1" >
<uses-sdk android:minSdkVersion="11" android:targetSdkVersion="20" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<application
android:allowBackup="true"
android:icon="#drawable/smallicon"
android:label="#string/app_name"
android:theme="#style/GdxTheme"
android:name="com.---------.game.android.MyApplication">
<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"/>
<activity
android:name="com.outofboxapps.game.android.AndroidLauncher"
android:label="#string/app_name"
android:screenOrientation="landscape"
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>
My Strings File in Android/Res folder has this
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="app_name">My Game</string>
<string name="app_id">------------</string> // has my app id
</resources>
My Logcat says this when I run my app in Debug Mode(Note: I have already configured Google play game services on Developer console| My game is already published without Game services in First Version so to test Game services I have published my Game services in Alpha. I have successfully added testers. I am able to sign in with test account. I also have Dubug plus release certificates Client ID)
03-11 10:28:49.823: I/my Spash Screen(16750): constructor called
03-11 10:28:49.829: I/my Splash Screen(16750): hide called
03-11 10:28:49.830: I/my Splash Screen(16750): rendered 2 times.
03-11 10:28:49.830: I/my Splash Screen(16750): show called
03-11 10:28:50.030: D/GameHelper(16750): GameHelper: onConnected: connected!
03-11 10:28:50.038: D/GameHelper(16750): GameHelper: succeedSignIn
03-11 10:28:50.044: D/GameHelper(16750): GameHelper: Notifying LISTENER of sign-in SUCCESS
03-11 10:28:52.837: I/my Spash Screen(16750): constructor called
03-11 10:28:52.869: I/my Splash Screen(16750): hide called
03-11 10:28:52.869: I/my Splash Screen(16750): rendered 180 times.
03-11 10:28:57.361: I/GameScreen(16750): show called
03-11 10:28:57.361: I/GameScreen(16750): resizing
Now I dont get it. when I am SUCCESSFULLY CONNECTED why i cant do anything else in game services. I just have achievements that I need to unlock on a particular score.
Using all LIBGDX game tutorials, Google Type a number and trival exmaple and tutorial I feel hopeless now that I cant configure these game services at all.
I was also sending my scores at game over from gamescreen class but removed it now because it simply generate Null pointer exception on Sign in(to google game services). I can post that code as well
if (Gameover ----) {
if ((game.actionResolver.getSignedInGPGS())) { // My app crashes at this point ton check Sign in by giving Null pointer exception
game.actionResolver.submitScoreGPGS(AssetLoader.getScore);
if (AssetLoader.getScore >= 2500) game.actionResolver.unlockAchievementGPGS("-----"); // my id is here
}
}
KINDLY ANYBODY WHO HAS DONE THIS SUCCESSFULLY. hELP ME OUT.
Take a look at your loginGPGS() method in your launcher class...You can successfully connect because loginGPGS is run on the ui thread....Try accessing GPGS on the ui thread because it needs to be run in the context of your Main activity....This is how I access mine:
#Override
public void getLeaderboardGPGS() {
try {
runOnUiThread(new Runnable() {
public void run() {
if (gameHelper.isSignedIn()) {
startActivityForResult(
Games.Leaderboards.getLeaderboardIntent(
gameHelper.getApiClient(),
"XXXXXXXXXX-XXX-XXX"), 100);
} else if (!gameHelper.isConnecting()) {
loginGPGS();
}
}
});
} catch (final Exception ex) {
}
}
#Override
public void sendScoreGPGS() {
try {
runOnUiThread(new Runnable() {
public void run() {
if (gameHelper.isSignedIn()) {
startActivityForResult(
Games.Leaderboards.submitScore(gameHelper.getApiClient(),
"YOUR-GPGS-HASH", score);
} else if (!gameHelper.isConnecting()) {
loginGPGS();
}
}
});
} catch (final Exception ex) {
}
}
Related
Made a game with Libgdx and eventually got GPGS Leaderboard and Achievements to work. Or so I thought.
They run fine on my phone and tablet when I install the APK directly through Android Studio but it won't allow users to sign in when they have downloaded the game from Google Play Store.
Failed to sign in. Please check your network connection and try again
The SHA-1 matches in console.developers.google.com/apis/credentials/oauthclient/ and gradle.
Leaderboards etc have all been published days ago.
What have I forgotten to do? Is there a new SHA-1 I should add to developer console that I don't know how to find? I'm "certain" I've covered all the basics illustrated in other questions on SO.
I am thinking/hoping it is something in the developer console I've forgotten/missed.
Here's AndroidLauncher though just in case I'm wrong about that, thanks in advance:
package com.weavernap.chuggydodge;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.graphics.Color;
import android.os.Bundle;
import android.support.multidex.MultiDex;
import android.view.View;
import android.widget.RelativeLayout;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.backends.android.AndroidApplication;
import com.badlogic.gdx.backends.android.AndroidApplicationConfiguration;
import com.google.android.gms.ads.AdRequest;
import com.google.android.gms.ads.AdSize;
import com.google.android.gms.ads.AdView;
import com.google.android.gms.ads.InterstitialAd;
import com.google.android.gms.ads.MobileAds;
import com.google.android.gms.games.Games;
import com.google.example.games.basegameutils.GameHelper;
import com.weavernap.cdHelpers.AdsController;
public class AndroidLauncher extends AndroidApplication implements GameHelper.GameHelperListener, AdsController {
protected void attachBaseContext(Context base) {
super.attachBaseContext(base);
MultiDex.install(this);
}
private static final String BANNER_AD_UNIT_ID = "ca-app-pub-3737397260010456/7958274520";
private static final String INTERSTITIAL_AD_UNIT_ID = "ca-app-pub-3737397260010456/3314422124";
protected AdView adView;
private InterstitialAd interstitialAd;
protected View gameView;
private GameHelper gameHelper;
// private AdsController adsController;
// private GoogleApiClient mGoogleApiClient;
private SharedPreferences prefs;
private boolean writeLogs = true;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
MobileAds.initialize(getApplicationContext(), "ca-app-pub-3737397260010456~9090257326");
AndroidApplicationConfiguration config = new AndroidApplicationConfiguration();
RelativeLayout relativeLayout = new RelativeLayout(this);
relativeLayout.setLayoutParams(new RelativeLayout.LayoutParams(-1, -1));
AdView adView = this.createAdView();
relativeLayout.addView(adView);
relativeLayout.addView(this.createGameView(config));
this.setContentView(relativeLayout);
this.startAdvertising(adView);
this.interstitialAd = new InterstitialAd(this);
this.interstitialAd.setAdUnitId(INTERSTITIAL_AD_UNIT_ID);
if (this.gameHelper == null) {
this.gameHelper = new GameHelper(this, 1);
this.gameHelper.enableDebugLog(this.writeLogs);
}
this.gameHelper.setup(this);
//
// // Create a gameView and a bannerAd AdView
// View gameView = initializeForView(new CDGame(this), config);
// setupAds();
// // Define the layout
// RelativeLayout layout = new RelativeLayout(this);
// layout.addView(gameView, ViewGroup.LayoutParams.MATCH_PARENT,
// ViewGroup.LayoutParams.MATCH_PARENT);
// RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(
// ViewGroup.LayoutParams.MATCH_PARENT,
// ViewGroup.LayoutParams.WRAP_CONTENT);
// params.addRule(RelativeLayout.ALIGN_PARENT_TOP);
// layout.addView(bannerAd, params);
//
// setContentView(layout);
}
#Override
public void onStart() {
super.onStart();
gameHelper.onStart(this);
}
#Override
public void onStop() {
super.onStop();
gameHelper.onStop();
}
#Override
public void onActivityResult(int request, int response, Intent data) {
super.onActivityResult(request, response, data);
gameHelper.onActivityResult(request, response, data);
}
#Override
public void showOrLoadInterstitial(final boolean showAd) {
try {
this.runOnUiThread(new Runnable() {
public void run() {
if (AndroidLauncher.this.interstitialAd.isLoaded() && showAd) {
AndroidLauncher.this.interstitialAd.show();
return;
} //else
{
AdRequest adRequest = new AdRequest.Builder().build();
AndroidLauncher.this.interstitialAd.loadAd(adRequest);
}
}
});
return;
} catch (Exception e) {
Gdx.app.log("ChuggerDodge.ERROR", "Exception in showOrLoadInterstitial:" + e.toString());
return;
}
}
#Override
public void submitScoreGPGS(int score) {
if (this.getSignedInGPGS()) {
Games.Leaderboards.submitScore(this.gameHelper.getApiClient(), this.getString(R.string.leaderboard_top_scores), score);
}
}
#Override
public void unlockAchievementGPGS(int score) {
if (this.getSignedInGPGS()) {
if (score == 0) {
Games.Achievements.unlock(this.gameHelper.getApiClient(),
this.getString(R.string.achievement_the_every_loser_wins_trophy));
}
if (score > 3) {
Games.Achievements.unlock(this.gameHelper.getApiClient(),
this.getString(R.string.achievement_not_completely_useless));
}
if (score > 19) {
Games.Achievements.unlock(this.gameHelper.getApiClient(),
this.getString(R.string.achievement_hey_youre_all_right_you_are_));
}
if (score == 42) {
Games.Achievements.unlock(this.gameHelper.getApiClient(),
this.getString(R.string.achievement_the_hyperintelligent_pandimensional_being_prize));
}
if (score > 43) {
Games.Achievements.unlock(this.gameHelper.getApiClient(),
this.getString(R.string.achievement_wowzers__youre_about_as_good_as_me_now_));
}
if (score > 76) {
Games.Achievements.unlock(this.gameHelper.getApiClient(),
this.getString(R.string.achievement_actually_thats_quite_impressive_));
}
}
}
#Override
public void getGPGSLeaderboard() {
if (this.gameHelper.isSignedIn()) {
this.startActivityForResult(Games.Leaderboards.getLeaderboardIntent(this.gameHelper.getApiClient(), this.getString(R.string.leaderboard_top_scores)), 100);
return;
} else {
if (this.gameHelper.isConnecting()) return;
{
this.loginGPGS();
return;
}
}
}
#Override
public boolean getSignedInGPGS() {
if (this.gameHelper != null) {
System.out.println("Superduperdavid");
return this.gameHelper.isSignedIn();
}
System.out.println("Nah");
return false;
}
//
#Override
public void loginGPGS() {
// if (!gameHelper.isSignedIn()) {
try {
runOnUiThread(new Runnable() {
public void run() {
gameHelper.beginUserInitiatedSignIn();
}
});
return;
} catch (final Exception ex) {
Gdx.app.log("MainActivity", "Log in failed: " + ex.getMessage() + ".");
return;
}
//
}
//
#Override
public void getAchievementsGPGS() {
// if (gameHelper.isSignedIn()) {
startActivityForResult(Games.Achievements.getAchievementsIntent(gameHelper.getApiClient()), 101);
// } else if (!gameHelper.isConnecting()) {
// loginGPGS();
// }
}
//Following from toaster code
private AdView createAdView() {
this.adView = new AdView(this);
this.adView.setAdSize(AdSize.SMART_BANNER);
this.adView.setAdUnitId(BANNER_AD_UNIT_ID);
RelativeLayout.LayoutParams layoutParams = new RelativeLayout.LayoutParams(-1, -2);
layoutParams.addRule(12, -1);
layoutParams.addRule(14, -1);
this.adView.setLayoutParams(layoutParams);
this.adView.setBackgroundColor(Color.TRANSPARENT);
return this.adView;
}
private View createGameView(AndroidApplicationConfiguration androidApplicationConfiguration) {
this.gameView = this.initializeForView(new CDGame(this), androidApplicationConfiguration);
RelativeLayout.LayoutParams layoutParams = new RelativeLayout.LayoutParams(-1, -2);
layoutParams.addRule(10, -1);
layoutParams.addRule(14, -1);
layoutParams.addRule(2, this.adView.getId());
this.gameView.setLayoutParams(layoutParams);
return this.gameView;
}
private void startAdvertising(AdView adView) {
adView.loadAd(new AdRequest.Builder().build());
}
#Override
public void onDestroy() {
if (this.adView != null) {
this.adView.destroy();
}
super.onDestroy();
}
#Override
public void onPause() {
if (this.adView != null) {
this.adView.pause();
}
super.onPause();
}
#Override
public void onResume() {
super.onResume();
if (this.adView != null) {
this.adView.resume();
}
}
#Override
public void onSignInFailed() {
gameHelper.getSignInError();
}
#Override
public void onSignInSucceeded() {
}
}
Okay, so at some point I had entered the debug SHA-1 into the developer console to get GPGS working during testing. But did not realise that you had to revert back to the original.
So following this and making the changes in the console did the trick pretty much straight away.
This is my main activity
package com.sdsmdg.cycle;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.util.Log;
import com.badlogic.gdx.backends.android.AndroidApplication;
import com.badlogic.gdx.backends.android.AndroidApplicationConfiguration;
import com.google.android.gms.games.Games;
import com.google.android.gms.games.GamesActivityResultCodes;
import com.google.example.games.basegameutils.GameHelper;
import com.sdsmdg.ball.R;
public class AndroidLauncher extends AndroidApplication implements PlayServices {
private GameHelper gameHelper;
private final static int requestCode = 1;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
AndroidApplicationConfiguration config = new AndroidApplicationConfiguration();
initialize(new CGame(this), config);
gameHelper = new GameHelper(this, GameHelper.CLIENT_GAMES);
GameHelper.GameHelperListener gameHelperListener = new GameHelper.GameHelperListener() {
#Override
public void onSignInFailed() {
Log.i("AndroidLauncher", "Sign in Failed!");
}
#Override
public void onSignInSucceeded() {
Log.i("AndroidLauncher", "Sign in Successful!");
}
};
gameHelper.setup(gameHelperListener);
}
#Override
protected void onStart() {
super.onStart();
gameHelper.onStart(this);
}
#Override
protected void onStop() {
super.onStop();
gameHelper.onStop();
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
gameHelper.onActivityResult(requestCode, resultCode, data);
if (resultCode == GamesActivityResultCodes.RESULT_RECONNECT_REQUIRED){
// force a disconnect to sync up state, ensuring that mClient reports "not connected"
gameHelper.disconnect();
}
}
#Override
public void signIn() {
try {
runOnUiThread(new Runnable() {
#Override
public void run() {
gameHelper.beginUserInitiatedSignIn();
}
});
} catch (Exception e) {
Log.i("MainActivity", "Log in failed: " + e.getMessage() + ".");
}
}
#Override
public void signOut() {
try {
runOnUiThread(new Runnable() {
#Override
public void run() {
gameHelper.signOut();
}
});
} catch (Exception e) {
Log.i("MainActivity", "Log out failed: " + e.getMessage() + ".");
}
}
#Override
public void rateGame() {
String str = "Your PlayStore Link";
startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse(str)));
}
#Override
public void unlockAchievementBeginner() {
//This achievement is named Beginner, for playing 10 games
if (gameHelper.isSignedIn())
Games.Achievements.unlock(gameHelper.getApiClient(),
getString(R.string.achievement_beginner));
}
#Override
public void unlockAchievement2() {
//This gets unlocked on making a score of 2
if (gameHelper.isSignedIn())
Games.Achievements.unlock(gameHelper.getApiClient(),
getString(R.string.achievement_welcome_to_the_2_group));
}
#Override
public void unlockAchievementTrickyOne() {
//This gets unlocked when the ball hits the bat only once in a game
if (gameHelper.isSignedIn())
Games.Achievements.unlock(gameHelper.getApiClient(),
getString(R.string.achievement_the_tricky_one));
}
#Override
public void unlockAchievementCentury() {
if (gameHelper.isSignedIn())
Games.Achievements.unlock(gameHelper.getApiClient(),
getString(R.string.achievement_century));
}
#Override
public void unlockAchievementHalfCentury() {
if (gameHelper.isSignedIn())
Games.Achievements.unlock(gameHelper.getApiClient(),
getString(R.string.achievement_half_century));
}
#Override
public void unlockAchievementBored() {
//Play 100 games to unlock this achievement
if (gameHelper.isSignedIn())
Games.Achievements.unlock(gameHelper.getApiClient(),
getString(R.string.achievement_bored));
}
#Override
public void unlockAchievementIntoHeavens() {
//hit the ball such that it goes out of the screen 3 times continuously without dying
if (gameHelper.isSignedIn()) {
Games.Achievements.unlock(gameHelper.getApiClient(),
getString(R.string.achievement_into_the_heavens));
}
}
#Override
public void unlockAchievementYouAreGod() {
//hit the ball such that it goes out of the screen 4 times continuously without dying
if (gameHelper.isSignedIn()) {
Games.Achievements.unlock(gameHelper.getApiClient(),
getString(R.string.achievement_you_are_the_god));
}
}
#Override
public void submitScore(int highScore) {
if (isSignedIn()) {
Games.Leaderboards.submitScore(gameHelper.getApiClient(),
getString(R.string.leaderboard_leaderboard), highScore);
}
}
#Override
public void showAchievement() {
if (isSignedIn()) {
startActivityForResult(Games.Achievements.getAchievementsIntent(gameHelper.getApiClient()), requestCode);
} else {
signIn();
}
}
#Override
public void showScore() {
if (isSignedIn() == true) {
startActivityForResult(Games.Leaderboards.getLeaderboardIntent(gameHelper.getApiClient(),
getString(R.string.leaderboard_leaderboard)), requestCode);
} else {
signIn();
}
}
#Override
public boolean isSignedIn() {
return gameHelper.isSignedIn();
}
}
The game works fine in the first few runs but starts to lag afterwards. The error in Android Monitor is like this:
E/ActivityThread: Service com.google.android.gms.car.CarService has leaked ServiceConnection fmj#35e4d4a that was originally bound here
android.app.ServiceConnectionLeaked: Service com.google.android.gms.car.CarService has leaked ServiceConnection fmj#35e4d4a that was originally bound here
at android.app.LoadedApk$ServiceDispatcher.<init>(LoadedApk.java:1093)
at android.app.LoadedApk.getServiceDispatcher(LoadedApk.java:987)
at android.app.ContextImpl.bindServiceCommon(ContextImpl.java:1313)
at android.app.ContextImpl.bindService(ContextImpl.java:1296)
at android.content.ContextWrapper.bindService(ContextWrapper.java:610)
at android.content.ContextWrapper.bindService(ContextWrapper.java:610)
at android.content.ContextWrapper.bindService(ContextWrapper.java:610)
at ivw.a(:com.google.android.gms:120)
at ivw.a(:com.google.android.gms:137)
at fmj.h(:com.google.android.gms:76)
at fmj.<init>(:com.google.android.gms:64)
at fpn.i(:com.google.android.gms:551)
at com.google.android.gms.car.CarChimeraService.onBind(:com.google.android.gms:165)
at com.google.android.chimera.container.ServiceProxy.onBind(:com.google.android.gms:165)
at android.app.ActivityThread.handleBindService(ActivityThread.java:2938)
at android.app.ActivityThread.-wrap2(ActivityThread.java)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1451)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:148)
at android.app.ActivityThread.main(ActivityThread.java:5461)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
SQLiteConnectionPool: A SQLiteConnection object for database '/data/user/0/com.google.android.gms/databases/metrics.db' was leaked! Please fix your application to end transactions in progress properly and to close the database when it is no longer needed.
09-12 16:45:59.072 8993-9001/com.google.android.gms W/SQLiteConnectionPool: A SQLiteConnection object for database '/data/user/0/com.google.android.gms/databases/help_responses.db' was leaked! Please fix your application to end transactions in progress properly and to close the database when it is no longer needed.
09-12 16:45:59.074 8993-9001/com.google.android.gms W/SQLiteConnectionPool: A SQLiteConnection object for database '/data/user/0/com.google.android.gms/databases/auto_complete_suggestions.db' was leaked! Please fix your application to end transactions in progress properly and to close the database when it is no longer needed.
09-12 16:47:41.038 8993-9001/com.google.android.gms E/DataBuffer: Internal data leak within a DataBuffer object detected! Be sure to explicitly call release() on all DataBuffer extending objects when you are done with them. (internal object: com.google.android.gms.common.data.DataHolder#dbfbc4)
09-12 16:47:45.845 18100-18108/com.google.android.gms.ui E/DataBuffer: Internal data leak within a DataBuffer object detected! Be sure to explicitly call release() on all DataBuffer extending objects when you are done with them. (internal object: com.google.android.gms.common.data.DataHolder#d4f2783)
The last part indicates that there is a memory leak in google gms service. I have been searching the web for weeks now, but cannot find out what I am doing wrong
The stackstrace you posted does not seem to have a reference to AndroidLauncher.java. It looks like things go wrong in another part of your code.
The log says at the end
'Internal data leak within a DataBuffer object detected! Be sure to explicitly call release() on all DataBuffer extending objects when you are done with them.'
Do you use any DataBuffer extending objects?
The problem was that I was trying to call unlockAchievementBeginner() too many times which probably lead to too frequent garbage collections causing the game to lag
I'm trying to make ads that give "100 coins" and the button just disappear after 0,2 - 1 second.
I've got no clue why this error could appear. Has someone got an idea how to fix that?
My error
06-03 21:42:16.017: V/PTAdHeyzapBridge(27950): PTAdHeyzapBridge -- Start Session: "MyHeyzapID"
06-03 21:42:16.023: E/Heyzap(27950): Heyzap encountered a runtime exception and is now disabled. Error: Attempt to invoke virtual method 'java.lang.String android.content.Context.getPackageName()' on a null object reference
06-03 21:42:16.023: V/PTAdHeyzapBridge(27950): PTAdHeyzapBridge -- Start Session FAILED : Attempt to invoke virtual method 'java.lang.String android.content.Context.getPackageName()' on a null object reference
06-03 21:42:16.023: V/PTAdHeyzapBridge(27950): Heyzap SDK Version : 8.4.1
My PTAdHeyzapBridge.java
package com.secrethq.ads;
import java.lang.ref.WeakReference;
import org.cocos2dx.lib.Cocos2dxActivity;
import com.google.android.gms.ads.AdView;
import com.heyzap.sdk.ads.HeyzapAds;
import com.heyzap.sdk.ads.InterstitialAd;
import com.heyzap.sdk.ads.VideoAd;
import com.heyzap.sdk.ads.IncentivizedAd;
import com.heyzap.sdk.ads.BannerAdView;
import com.heyzap.sdk.ads.HeyzapAds.BannerListener;
import com.heyzap.sdk.ads.HeyzapAds.BannerError;
import com.heyzap.sdk.ads.HeyzapAds.OnStatusListener;
import com.heyzap.sdk.ads.HeyzapAds.OnIncentiveResultListener;
import android.util.Log;
import android.view.View;
import android.widget.FrameLayout;
import android.widget.RelativeLayout;
public class PTAdHeyzapBridge {
private static native String bannerId();
private static native String interstitialId();
private static native void interstitialDidFail();
private static native void bannerDidFail();
private static native void rewardVideoComplete();
private static final String TAG = "PTAdHeyzapBridge";
private static Cocos2dxActivity activity;
private static WeakReference<Cocos2dxActivity> s_activity;
private static BannerAdView bannerAdView;
public static void initBridge(Cocos2dxActivity activity){
Log.v(TAG, "PTAdHeyzapBridge -- INIT");
PTAdHeyzapBridge.s_activity = new WeakReference<Cocos2dxActivity>(activity);
PTAdHeyzapBridge.activity = activity;
PTAdHeyzapBridge.initBanner();
PTAdHeyzapBridge.initInterstitial();
PTAdHeyzapBridge.initVideo();
}
public static void initBanner(){
Log.v(TAG, "PTAdHeyzapBridge -- Init Banner");
PTAdHeyzapBridge.s_activity.get().runOnUiThread( new Runnable() {
public void run() {
PTAdHeyzapBridge.bannerAdView = new BannerAdView(PTAdHeyzapBridge.activity);
FrameLayout frameLayout = (FrameLayout)PTAdHeyzapBridge.activity.findViewById(android.R.id.content);
RelativeLayout layout = new RelativeLayout( PTAdHeyzapBridge.activity );
frameLayout.addView( layout );
RelativeLayout.LayoutParams adViewParams = new RelativeLayout.LayoutParams(
AdView.LayoutParams.WRAP_CONTENT,
AdView.LayoutParams.WRAP_CONTENT);
adViewParams.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM);
adViewParams.addRule(RelativeLayout.CENTER_IN_PARENT, RelativeLayout.TRUE);
layout.addView(PTAdHeyzapBridge.bannerAdView, adViewParams);
PTAdHeyzapBridge.bannerAdView.setVisibility( View.INVISIBLE );
// Add a listener.
PTAdHeyzapBridge.bannerAdView.setBannerListener(new BannerListener() {
#Override
public void onAdClicked(BannerAdView b) {
// The ad has been clicked by the user.
}
#Override
public void onAdLoaded(BannerAdView b) {
// The ad has been loaded.
}
#Override
public void onAdError(BannerAdView b, BannerError bannerError) {
// There was an error loading the ad.
Log.v(TAG, "PTAdHeyzapBridge -- Banner onAdError : " + bannerError.getErrorMessage());
bannerDidFail();
}
});
}
});
}
public static void initInterstitial(){
Log.v(TAG, "PTAdHeyzapBridge -- Init Interstitial");
InterstitialAd.setOnStatusListener(new OnStatusListener() {
#Override
public void onShow(String tag) {
// Ad is now showing
}
#Override
public void onClick(String tag) {
// Ad was clicked on. You can expect the user to leave your application temporarily.
}
#Override
public void onHide(String tag) {
// Ad was closed. The user has returned to your application.
}
#Override
public void onFailedToShow(String tag) {
// Display was called but there was no ad to show
}
#Override
public void onAvailable(String tag) {
// An ad has been successfully fetched
}
#Override
public void onFailedToFetch(String tag) {
// No ad was able to be fetched
Log.v(TAG, "PTAdHeyzapBridge -- Interstitial onFailedToFetch : " + tag);
interstitialDidFail();
}
#Override
public void onAudioFinished() {
// TODO Auto-generated method stub
}
#Override
public void onAudioStarted() {
// TODO Auto-generated method stub
}
});
}
public static void initVideo() {
IncentivizedAd.setOnIncentiveResultListener(new OnIncentiveResultListener() {
#Override
public void onComplete(String tag) {
Log.v(TAG, "PTAdHeyzapBridge -- IncentivizedAd Complete ");
// Give the player their reward
rewardVideoComplete();
}
#Override
public void onIncomplete(String tag) {
// Don't give the player their reward, and tell them why
Log.v(TAG, "PTAdHeyzapBridge -- IncentivizedAd InComplete ");
}
});
PTAdHeyzapBridge.s_activity.get().runOnUiThread( new Runnable() {
public void run() {
// As early as possible, and after showing a rewarded video, call fetch
IncentivizedAd.fetch();
}
});
}
public static void showRewardedVideo(){
Log.v(TAG, "PTAdHeyzapBridge -- showRewardedVideo");
PTAdHeyzapBridge.s_activity.get().runOnUiThread( new Runnable() {
public void run() {
if (IncentivizedAd.isAvailable()) {
IncentivizedAd.display(PTAdHeyzapBridge.activity);
}
}
});
}
public static void startSession( String sdkKey ){
if(sdkKey != null){
Log.v(TAG, "PTAdHeyzapBridge -- Start Session: " + sdkKey);
try {
HeyzapAds.start(sdkKey, PTAdHeyzapBridge.activity);
} catch (Exception e) {
// TODO: handle exception
Log.v(TAG, "PTAdHeyzapBridge -- Start Session FAILED : " + e.getMessage());
}
Log.v(TAG, "Heyzap SDK Version : " + HeyzapAds.getVersion());
}else{
Log.v(TAG, "Start Session : null ");
}
}
public static void showFullScreen(){
Log.v(TAG, "PTAdHeyzapBridge -- showFullScreen");
PTAdHeyzapBridge.s_activity.get().runOnUiThread( new Runnable() {
public void run() {
// InterstitialAds are automatically fetched from our server
InterstitialAd.display(PTAdHeyzapBridge.activity);
}
});
}
public static void showBannerAd(){
Log.v(TAG, "PTAdHeyzapBridge -- showBannerAd");
PTAdHeyzapBridge.s_activity.get().runOnUiThread( new Runnable() {
public void run() {
if(PTAdHeyzapBridge.bannerAdView != null){
PTAdHeyzapBridge.bannerAdView.setVisibility(View.VISIBLE);
// Load the banner ad.
PTAdHeyzapBridge.bannerAdView.load();
}
}
});
}
public static void hideBannerAd(){
Log.v(TAG, "PTAdHeyzapBridge -- hideBannerAd");
PTAdHeyzapBridge.s_activity.get().runOnUiThread( new Runnable() {
public void run() {
if(PTAdHeyzapBridge.bannerAdView != null){
PTAdHeyzapBridge.bannerAdView.setVisibility(View.INVISIBLE);
}
}
});
}
public static boolean isBannerVisible() {
return (PTAdHeyzapBridge.bannerAdView.getVisibility() == View.VISIBLE);
}
public static boolean isRewardedVideoAvialable(){
return IncentivizedAd.isAvailable();
}
}
My Main activity
package com.lopeostudios.runningpanda;
import org.cocos2dx.lib.Cocos2dxActivity;
import org.cocos2dx.lib.Cocos2dxGLSurfaceView;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import android.view.WindowManager;
import android.widget.Toast;
import com.secrethq.store.PTStoreBridge;
import com.google.android.gms.games.GamesActivityResultCodes;
import com.lopeostudios.runningpanda.R;
import com.secrethq.ads.*;
import com.secrethq.utils.*;
import com.onesignal.OneSignal;
public class PTPlayer extends Cocos2dxActivity {
private static native void loadModelController();
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
Log.v("----------","onActivityResult: request: " + requestCode + " result: "+ resultCode);
if(PTStoreBridge.iabHelper().handleActivityResult(requestCode, resultCode, data)){
Log.v("-----------", "handled by IABHelper");
}
else if(requestCode == PTServicesBridge.RC_SIGN_IN){
if(resultCode == RESULT_OK){
PTServicesBridge.instance().onActivityResult(requestCode, resultCode, data);
}
else if(resultCode == GamesActivityResultCodes.RESULT_SIGN_IN_FAILED){
int duration = Toast.LENGTH_SHORT;
Toast toast = Toast.makeText(this, "Google Play Services: Sign in error", duration);
toast.show();
}
else if(resultCode == GamesActivityResultCodes.RESULT_APP_MISCONFIGURED){
int duration = Toast.LENGTH_SHORT;
Toast toast = Toast.makeText(this, "Google Play Services: App misconfigured", duration);
toast.show();
}
}
}
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
OneSignal.startInit(this).init();
getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
}
#Override
public void onNativeInit(){
initBridges();
}
private void initBridges(){
PTStoreBridge.initBridge( this );
PTServicesBridge.initBridge(this, getString( R.string.app_id ));
if (PTJniHelper.isAdNetworkActive("kChartboost")) {
PTAdChartboostBridge.initBridge(this);
}
if (PTJniHelper.isAdNetworkActive("kRevMob")) {
PTAdRevMobBridge.initBridge(this);
}
if (PTJniHelper.isAdNetworkActive("kAdMob") || PTJniHelper.isAdNetworkActive("kFacebook")) {
PTAdAdMobBridge.initBridge(this);
}
if (PTJniHelper.isAdNetworkActive("kAppLovin")) {
PTAdAppLovinBridge.initBridge(this);
}
if (PTJniHelper.isAdNetworkActive("kLeadBolt")) {
PTAdLeadBoltBridge.initBridge(this);
}
if (PTJniHelper.isAdNetworkActive("kVungle")) {
PTAdVungleBridge.initBridge(this);
}
if (PTJniHelper.isAdNetworkActive("kPlayhaven")) {
PTAdUpsightBridge.initBridge(this);
}
if (PTJniHelper.isAdNetworkActive("kMoPub")) {
PTAdMoPubBridge.initBridge(this);
}
if (PTJniHelper.isAdNetworkActive("kFacebook")) {
PTAdFacebookBridge.initBridge(this);
}
if (PTJniHelper.isAdNetworkActive("kHeyzap")) {
PTAdHeyzapBridge.initBridge(this);
}
}
#Override
public Cocos2dxGLSurfaceView onCreateView() {
Cocos2dxGLSurfaceView glSurfaceView = new Cocos2dxGLSurfaceView(this);
glSurfaceView.setEGLConfigChooser(8, 8, 8, 0, 0, 0);
return glSurfaceView;
}
static {
System.loadLibrary("player");
}
#Override
protected void onResume() {
super.onResume();
if (PTJniHelper.isAdNetworkActive("kChartboost")) {
PTAdChartboostBridge.onResume( this );
}
}
#Override
protected void onStart() {
super.onStart();
if (PTJniHelper.isAdNetworkActive("kChartboost")) {
PTAdChartboostBridge.onStart( this );
}
}
#Override
protected void onStop() {
super.onStop();
if (PTJniHelper.isAdNetworkActive("kChartboost")) {
PTAdChartboostBridge.onStop( this );
}
}
#Override
protected void onDestroy() {
super.onDestroy();
}
}
I'm an engineer at Heyzap. Our SDK will catch exceptions from third party SDKs, and shut down our SDK if we catch one (this is our last line of defense in preventing exceptions from crashing your game). In this case, we're catching this exception:
06-03 21:42:16.023: E/Heyzap(27950): Heyzap encountered a runtime exception and is now disabled. Error: Attempt to invoke virtual method 'java.lang.String android.content.Context.getPackageName()' on a null object reference
We've previously seen this exception caused by an outdated UnityAds SDK. Are you using that network, and if so, can you try UnityAds 1.5.6? If you're not, can you tell us which networks you're using, or the Android package of your game?
Also, I see in yours logs that you're using Heyzap 8.4.1, which was released in June of last year. Can you update to our latest version?
After migrating to Android Studio from Eclipse, I was struggling at best with it. Problem was that most guides and tutorials you could find are for Eclipse , but if you can find one for Android Studio, it is missing most important parts - implementing libraries or 3rd party code. After week of problems and errors here is a guide
Requirements: Google play services and Google Repostory (under Extras in SDK manager), BaseGameUtils
Firstly we need to add BaseGameUtils as Module:
then select Import Gradle Project and chose BaseGameUtil folder (do not copy BaseGameUtils in project before that step. Let Android Studio do that)
After gradle is done with syncing selefct Build > Make Module 'BaseGameUtils'
NOTE if u have uses-sdk:minSdkVersion error while build check this click here. Build :BaseGameUtils again after this
Last step for integranting BaseGameUtils is to include it into android module:
Sync project afterwards.
NOTE if you get uses-sdk:minSdkVersion error while build this will help - link
Now it's time to open your AndroidManifest file and include:
before application tag
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
NOTE: there is no need to add google play dependencies in android gradle script becouse it is already included in BaseGameUtils
in application, before 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" />
Now you need to set app_id number in Srtings (android/res/values/Strings.xml)
<string name="app_id">928019648708</string>
Your app id is located in GooglePlay developer console under Game Services section (under game name)
For passing android native code to game code we will create ActionResolver interface in core module:
package com.mygame.test;
public interface ActionResolver {
public boolean getSignedInGPGS();
public void loginGPGS();
public void submitScoreGPGS(int score, String id);
public void unlockAchievementGPGS(String achievementId);
public void getLeaderboardGPGS();
public void getAchievementsGPGS();
}
Now we need to make changes in AndroidLauncher class (check imports if you have problems):
package com.mygame.test.android;
import android.os.Bundle;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.backends.android.AndroidApplication;
import com.badlogic.gdx.backends.android.AndroidApplicationConfiguration;
import com.google.android.gms.games.Games;
import com.google.example.games.basegameutils.GameHelper;
import com.mygame.test.ActionResolver;
import com.mygame.test.MyGame;
public class AndroidLauncher extends AndroidApplication implements ActionResolver, GameHelper.GameHelperListener {
private GameHelper gameHelper;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (gameHelper == null) {
gameHelper = new GameHelper(this, GameHelper.CLIENT_GAMES);
gameHelper.enableDebugLog(true);
}
gameHelper.setup(this);
AndroidApplicationConfiguration config = new AndroidApplicationConfiguration();
initialize(new MyGame(this), config);
}
#Override
public boolean getSignedInGPGS() {
return gameHelper.isSignedIn();
}
#Override
public void loginGPGS() {
if (!gameHelper.isSignedIn()) {
try {
runOnUiThread(new Runnable() {
public void run() {
gameHelper.beginUserInitiatedSignIn();
}
});
} catch (final Exception ex) {
Gdx.app.log("MainActivity", "Log in failed: " + ex.getMessage() + ".");
}
} else {
gameHelper.reconnectClient();
}
}
#Override
public void submitScoreGPGS(int score, String id) {
Games.Leaderboards.submitScore(gameHelper.getApiClient(), id, score);
}
#Override
public void unlockAchievementGPGS(String achievementId) {
Games.Achievements.unlock(gameHelper.getApiClient(), achievementId);
}
#Override
public void getLeaderboardGPGS() {
if (gameHelper.isSignedIn()) {
startActivityForResult(Games.Leaderboards.getLeaderboardIntent(gameHelper.getApiClient(), "CgkI5MyZk4FbHAJQXQ"), 100);
} else if (!gameHelper.isConnecting()) {
loginGPGS();
}
}
#Override
public void getAchievementsGPGS() {
if (gameHelper.isSignedIn()) {
startActivityForResult(Games.Achievements.getAchievementsIntent(gameHelper.getApiClient()), 101);
} else if (!gameHelper.isConnecting()) {
loginGPGS();
}
}
#Override
public void onSignInFailed() {
gameHelper.getSignInError();
}
#Override
public void onSignInSucceeded() {
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data){
super.onActivityResult(requestCode, resultCode, data);
gameHelper.onActivityResult(requestCode, resultCode, data);
}
}
Create constructor in your main class (MyGame in this example):
public ActionResolver resolver;
public Base(ActionResolver ar) {
resolver = ar;
}
to connect with gplay services call:
if (!resolver.getSignedInGPGS())
resolver.loginGPGS();
unlock achievements and submit scores with:
if (resolver.getSignedInGPGS()){
if (currentScore == 0){
resolver.unlockAchievementGPGS("CgkI5MyZk4EbEAIQAg");
}
if (Cookie.bestScore >= 100){
resolver.unlockAchievementGPGS("CgkI5MyZk4EbEAIQAw");
}
resolver.submitScoreGPGS(Cookie.bestScore, "CgkI5MyZk4EbEAIQAQ");
}
note: use corresponding id valuses found in developer console for each achievement and for leaderbord
and call leaderboards and achievements with
resolver.getLeaderboardGPGS();
resolver.getAchievementsGPGS();
Lastly desktop, ios and html launcher can be resolved in the same way (example for desktop launcher)
public static void main (String[] arg) {
LwjglApplicationConfiguration config = new LwjglApplicationConfiguration();
ActionResolver resolver= new ActionResolver() {
#Override
public boolean getSignedInGPGS() {
return false;
}
#Override
public void loginGPGS() {
}
#Override
public void submitScoreGPGS(int score, String id) {
}
#Override
public void unlockAchievementGPGS(String achievementId) {
}
#Override
public void getLeaderboardGPGS() {
}
#Override
public void getAchievementsGPGS() {
}
};
new LwjglApplication(new MyGame(resolver), config);
}
I am a starter with Libgdx and Android.
I have developed a small game.
I have tried following up Google play game services tutorial at https://github.com/TheInvader360/libgdx-gameservices-tutorial using super jumper example. I have also checked every thing on Google developers Documentation.Also I have followed this tutorial
http://forum.xda-developers.com/android/apps-games/setting-eclipse-to-google-play-game-t2889796 Plus stack overflow.
a. SHA1 key is same when application Is EXPORT from eclipse.
b. Client ID is generated by O Auth2.0
c. Application package name is same .
d. My game is already published.
e. I also published Google play Game Services.(Its written on Google developer documentation that if app is published then also publish game services)
f. I upload Signed apk generated by Eclipse on my device for testing.
but no luck.
The error I got is that "Failed to sign in. Please check your network connection and try again. "
My application Manifest file is
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="...."
android:versionCode="1"
android:versionName="1.1" >
<uses-sdk android:minSdkVersion="11" android:targetSdkVersion="20" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<application
......>
<activity ....../>
<meta-data
android:name="com.google.android.gms.analytics.globalConfigResource"
android:resource="#xml/global_tracker" />
<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>
</manifest>
the configuration that I gave in my main Android Class is
public class AndroidLauncher extends AndroidApplication implements
ActionResolver, GameHelperListener , GoogleApiClient.ConnectionCallbacks,
GoogleApiClient.OnConnectionFailedListener {
private GameHelper gameHelper;
private GoogleApiClient client;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
client = new GoogleApiClient.Builder(this)
.addApi(Games.API)
.addScope(Games.SCOPE_GAMES)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.build();
GameHelper.GameHelperListener gameHelperListener = new GameHelper.GameHelperListener() {
#Override
public void onSignInFailed() {
Log.i("Game Helper", "Sign in failed");
}
#Override
public void onSignInSucceeded() {
Log.i("Game Helper", "Sign in succeeded");
}
};
gameHelper = new GameHelper(this, GameHelper.CLIENT_GAMES);
gameHelper.enableDebugLog(true);
AndroidApplicationConfiguration config = new AndroidApplicationConfiguration();
initialize(new MainGame(this) , config);
gameHelper.setup(gameHelperListener );
}
#Override
public void onStart() {
super.onStart();
gameHelper.onStart(this);
client.connect();
}
#Override
public void onStop() {
super.onStop();
gameHelper.onStop();
client.disconnect();
}
#Override
public void onActivityResult(int request, int response, Intent data) {
super.onActivityResult(request, response, data);
gameHelper.onActivityResult(request, response, data);
}
#Override
public boolean getSignedInGPGS() {
return gameHelper.isSignedIn();
}
#Override
public void loginGPGS() {
try {
runOnUiThread(new Runnable() {
public void run() {
gameHelper.beginUserInitiatedSignIn();
}
});
} catch (final Exception ex) {
}
}
#Override
public void unlockAchievementGPGS(String achievementId) {
Games.Achievements.unlock(gameHelper.getApiClient(), achievementId);
}
#Override
public void getLeaderboardGPGS() {
}
#Override
public void getAchievementsGPGS() {
if (gameHelper.isSignedIn()) {
startActivityForResult(
Games.Achievements.getAchievementsIntent(gameHelper
.getApiClient()), 101);
} else if (!gameHelper.isConnecting()) {
loginGPGS();
}
}
#Override
public void onSignInFailed() {
System.out.println("Sign in succeeded");
}
#Override
public void onSignInSucceeded() {
System.out.println("Sign in failed");
}
#Override
public void submitScoreGPGS(int score) {
// TODO Auto-generated method stub
}
#Override
public void onConnectionFailed(ConnectionResult arg0) {
// TODO Auto-generated method stub
}
#Override
public void onConnected(Bundle arg0) {
Log.i("Google API", "Connection Complete");
}
#Override
public void onConnectionSuspended(int arg0) {
Log.i("Google API", "Connection Failed: " );
}
}
I have given the exact same app id in my string file in the resource folder.
I dont get it why I get this error.
action resolver interface has all the methods specified. Main Game class initiate this interface.
On Game over I send score to unlock achievements.
I only have Achievements in my game.
Any other piece of Code is needed I can provide but kindly help me out.
Here are a few points that might help you.
It takes several hours before your changes on Developer Console are actually published. Test the game after a few hours.
You don't need to publish in order to test it. You can do that by adding tester accounts in your developer console.
You can't "test" Google Play Services with developer account. You will need another account for that.
Edit:
Very Important:
Make sure you added required permissions to AndroidManifest.xml in your Android project.