Google Play Services (Suggested updates to Android Main Activity for plugin)

@iwgeric said: Sorry for the delay, been pretty busy lately the last few weeks.

Anyway, can you share how you are modifying the layout in MainActivity to include the ad view?

Personally, we’ve added “in-app purchases”, but we haven’t attempted ads yet. Honestly, I’m not sure how effective ads are in mobile games. That’s the main reason we haven’t attempted it yet.

Also, let me know if you are still looking for a way to trigger displaying the ad view from the main app. Calling a method in the android project from the main project is pretty easy. We did this to trigger the in-app purchase by having an interface defined in the main app and then implementing the interface in MainActivity.

Sure… it’s all temporary… but the general idea was:

[java]
@Override
public void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);

	AdView adView = new AdView(this);
	adView.setAdSize(AdSize.BANNER);
	adView.setAdUnitId("AD_UNIT_ID_ASSIGNED_WHEN_REGISTERING_THE_APP_AND_DEFINING_AD_SPACE");
	adView.buildLayer();
	
	LinearLayout ll = new LinearLayout(this);
	ll.setGravity(Gravity.BOTTOM);
	ll.addView(adView);
	this.addContentView(ll, new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT));
	AdRequest adRequest = new AdRequest.Builder()
		.addTestDevice("YOUR_DEVICES_HASHED_ID")
		.build();
	adView.loadAd(adRequest);
	adView.bringToFront();
}

[/java]

And if you wouldn’t mind sharing an example of calling back to the MainActivity, that would be GREATLY appreciated!

Also note that the ad doesn’t show up until the app loses and gains focus again. Not sure why.

@t0neg0d said: And if you wouldn't mind sharing an example of calling back to the MainActivity, that would be GREATLY appreciated!

Here it is:

Main Project:

JmeToAndroid interface
[java]
package mygame;

/**

  • Simple interface for the main jME app to poke the Android project
  • @author iwgeric
    */
    public interface JmeToAndroid {
    public void displayAds(boolean display);
    }
    [/java]

Main:
[java]
package mygame;

import com.jme3.app.SimpleApplication;
import com.jme3.material.Material;
import com.jme3.math.ColorRGBA;
import com.jme3.renderer.RenderManager;
import com.jme3.scene.Geometry;
import com.jme3.scene.shape.Box;
import java.util.logging.Level;
import java.util.logging.Logger;

/**

  • Test app to create a hook for the main project to call the Android project

  • @author iwgeric
    */
    public class Main extends SimpleApplication {
    private static final Logger logger = Logger.getLogger(Main.class.getName());
    private JmeToAndroid android = null;
    private float elapsedTime = 0;
    private boolean displayAds = false;

    public static void main(String args) {
    Main app = new Main();
    app.start();
    }

    public void setAndroidListener(JmeToAndroid android) {
    this.android = android;
    }

    @Override
    public void simpleInitApp() {
    Box b = new Box(1, 1, 1);
    Geometry geom = new Geometry(“Box”, b);

     Material mat = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md");
     mat.setColor("Color", ColorRGBA.Blue);
     geom.setMaterial(mat);
    
     rootNode.attachChild(geom);
    

    }

    @Override
    public void simpleUpdate(float tpf) {
    if (android != null) {
    elapsedTime += tpf;
    if (elapsedTime > 3f) {
    displayAds = !displayAds;
    logger.log(Level.INFO, “sending to android: {0}”, displayAds);
    android.displayAds(displayAds);
    elapsedTime = 0f;
    }
    }
    }

    @Override
    public void simpleRender(RenderManager rm) {
    //TODO: add render code
    }
    }
    [/java]

Android project:

MainActivity:
[java]
package com.jmonkeyengine.playstoreintegration;

import android.content.pm.ActivityInfo;
import android.os.Bundle;
import com.jme3.app.AndroidHarness;
import com.jme3.system.android.AndroidConfigChooser.ConfigType;
import java.util.logging.Level;
import java.util.logging.LogManager;
import java.util.logging.Logger;
import mygame.JmeToAndroid;
import mygame.Main;

public class MainActivity extends AndroidHarness implements JmeToAndroid {
private static final Logger mainActivityLogger = Logger.getLogger(MainActivity.class.getName());

/*
 * Note that you can ignore the errors displayed in this file,
 * the android project will build regardless.
 * Install the 'Android' plugin under Tools->Plugins->Available Plugins
 * to get error checks and code completion for the Android project files.
 */

public MainActivity(){
    // Set the application class to run
    appClass = "mygame.Main";
    // Try ConfigType.FASTEST; or ConfigType.LEGACY if you have problems
    eglConfigType = ConfigType.BEST;
    // Exit Dialog title & message
    exitDialogTitle = "Exit?";
    exitDialogMessage = "Press Yes";
    // Enable verbose logging
    eglConfigVerboseLogging = false;
    // Choose screen orientation
    screenOrientation = ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE;
    // Enable MouseEvents being generated from TouchEvents (default = true)
    mouseEventsEnabled = true;
    // Set the default logging level (default=Level.INFO, Level.ALL=All Debug Info)
    LogManager.getLogManager().getLogger("").setLevel(Level.INFO);
}

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    if (app != null) {
        ((Main)app).setAndroidListener(this);
    } else {
        throw new IllegalArgumentException("app is null!");
    }
}



public void displayAds(boolean display) {
    mainActivityLogger.log(Level.INFO, "displayAds: {0}", display);
}

}
[/java]

1 Like
@iwgeric said: Here it is:

Just wanted you to know how helpful this was. It pretty much solves the one big issue that was making this difficult to implement. Well, aside from Google’s examples being a bit cryptic since they changed their ID system and half the examples still refer to old code.

I’ll throw together a start on the Wiki once I have everything up and running. From there, others should be able to expand on it until it becomes something useful for everyone.

1 Like

Below is an example of how I add the jME SurfaceView to a standard Android layout that has a TextView positioned below the SurfaceView. Admittedly, this isn’t using the Google Play Services API (just a standard TextView), but hopefully the theory is the same. The code below just has a few tweeks to the code I posted earlier. Instead of displaying ads, it simply updates a standard Android TextView with some text from the Main project.

I also used a standard Android layout xml file to lay out the screen instead of creating it all in code.

Main Project:

JmeToAndroid interface

[java]
package mygame;

/**

  • Simple interface for the main jME app to poke the Android project
  • @author iwgeric
    */
    public interface JmeToAndroid {
    public void displayAds(boolean display);
    public void displayText(String text);
    }
    [/java]

Main:
[java]
package mygame;

import com.jme3.app.SimpleApplication;
import com.jme3.material.Material;
import com.jme3.math.ColorRGBA;
import com.jme3.renderer.RenderManager;
import com.jme3.scene.Geometry;
import com.jme3.scene.shape.Box;
import java.util.logging.Level;
import java.util.logging.Logger;

/**

  • Test app to create a hook for the main project to call the Android project

  • @author iwgeric
    */
    public class Main extends SimpleApplication {
    private static final Logger logger = Logger.getLogger(Main.class.getName());
    private JmeToAndroid android = null;
    private float elapsedTime = 0;
    private boolean displayAds = false;

    public static void main(String[] args) {
    Main app = new Main();
    app.start();
    }

    public void setAndroidListener(JmeToAndroid android) {
    this.android = android;
    }

    @Override
    public void simpleInitApp() {
    Box b = new Box(1, 1, 1);
    Geometry geom = new Geometry(“Box”, b);

     Material mat = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md");
     mat.setColor("Color", ColorRGBA.Blue);
     geom.setMaterial(mat);
    
     rootNode.attachChild(geom);
    

    }

    @Override
    public void simpleUpdate(float tpf) {
    if (android != null) {
    elapsedTime += tpf;
    if (elapsedTime > 3f) {
    displayAds = !displayAds;
    logger.log(Level.INFO, “sending to android: {0}”, displayAds);
    android.displayAds(displayAds);
    android.displayText("elapsedTime: " + elapsedTime);
    elapsedTime = 0f;
    }
    }
    }

    @Override
    public void simpleRender(RenderManager rm) {
    //TODO: add render code
    }
    }
    [/java]

Android Project:

/mobile/res/layout/layoutwithads.xml

[java]
<?xml version="1.0" encoding="utf-8"?>

    

    
    

[/java]

MainActivity:
[java]
package com.jmonkeyengine.playstoreintegration;

import android.content.pm.ActivityInfo;
import android.os.Bundle;
import android.view.ViewGroup;
import android.widget.LinearLayout;
import android.widget.TextView;
import com.jme3.app.AndroidHarness;
import com.jme3.system.android.AndroidConfigChooser.ConfigType;
import java.util.logging.Level;
import java.util.logging.LogManager;
import java.util.logging.Logger;
import mygame.JmeToAndroid;
import mygame.Main;

public class MainActivity extends AndroidHarness implements JmeToAndroid {
private static final Logger mainActivityLogger = Logger.getLogger(MainActivity.class.getName());
private boolean firstUpdate = true;
private TextView adsView;

/*
 * Note that you can ignore the errors displayed in this file,
 * the android project will build regardless.
 * Install the 'Android' plugin under Tools->Plugins->Available Plugins
 * to get error checks and code completion for the Android project files.
 */

public MainActivity(){
    // Set the application class to run
    appClass = "mygame.Main";
    // Try ConfigType.FASTEST; or ConfigType.LEGACY if you have problems
    eglConfigType = ConfigType.BEST;
    // Exit Dialog title & message
    exitDialogTitle = "Exit?";
    exitDialogMessage = "Press Yes";
    // Enable verbose logging
    eglConfigVerboseLogging = false;
    // Choose screen orientation
    screenOrientation = ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE;
    // Enable MouseEvents being generated from TouchEvents (default = true)
    mouseEventsEnabled = true;
    // Set the default logging level (default=Level.INFO, Level.ALL=All Debug Info)
    LogManager.getLogManager().getLogger("").setLevel(Level.INFO);
}

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    if (app != null) {
        ((Main)app).setAndroidListener(this);
    } else {
        throw new IllegalArgumentException("app is null!");
    }
}

@Override
public void update() {
    super.update();
    // put this in the first update loop so that the standard splash screen
    // support still works (splash screen removed in the first update call)
    if (firstUpdate) {
        firstUpdate = false;
        this.runOnUiThread(new Runnable() {
            @Override
            public void run() {
                setContentView(R.layout.layoutwithads);
                adsView = (TextView)findViewById(R.id.AdsView);
                LinearLayout jmeLayout = (LinearLayout)findViewById(R.id.JmeLayout);
                if (view.getParent() != null) {
                    ((ViewGroup) view.getParent()).removeView(view);
                }
                jmeLayout.addView(view);
                view.requestFocus();
                view.requestFocusFromTouch();
            }
        });
    }

}



public void displayAds(boolean display) {
    mainActivityLogger.log(Level.INFO, "displayAds: {0}", display);
}

public void displayText(final String string) {
    if (adsView != null) {
        this.runOnUiThread(new Runnable() {
            @Override
            public void run() {
                adsView.setText(string);
            }
        });
    }
}

}
[/java]

2 Likes

One other thing I meant to pass along if you want to adjust layouts via code: (for anyone interested)

everything must be enqueued through runOnUiThread(Runnable runnable);

For example, showing an Interstitial would look like:

[java]
public void displayInterstitialAd() {
runOnUiThread(new Runnable() {
public void run() {
AdRequest adRequest = new AdRequest.Builder()
.addTestDevice(“SOME_DEVICE_ID”)
.build();
interstitial.loadAd(adRequest);
}
});
}
[/java]

Heh… ninja’d… I missed your post when I posted this :wink:

@iwgeric
Heyas you… I am hitting a really irritating problem with Google Play Services API and can’t seem to resolve it. I’m hoping you might be able to help me through this…

I’ve successfully imported the library, however… there seems to be portions of it just not there. I can’t get code completion to work with com.google.anything… so I can’t actually see what the jar file contains through the IDE.

Aside from importing the jar file, is there something I am missing that would make this work in Netbeans? I’ve never hit this problem before, so not really sure how to fix it. Can’t find anything on the net about this, so I am at a loss for how to proceed.

It is making integrating play services a real nightmare. =(

Grrr…

Time for a rant on Google. Maybe this will lead someone to point out why they have done what they have with Play Services… but… I doubt it :wink:

  1. What the F**K were they thinking naming classes a, b, c, d, e, f , g, etc?? Seriously… that is beyond… I just don’t even know how to put into words my feelings on this.
  2. Why do they keep changing the f’ing API??!? None of there example projects run atm due to referencing a package that does not exist anymore in the current API >.< So, all their lovely bits about leveraging GameHelper.java is a no go.
  3. Is Google’s whole company managed this way? Or did they save this extra special way of doing things specifically for their mobile dev team?
  4. I literally want to tear my eyeballs out and mail them to the Google Play Services team so they can see how this piece of shit looks through my eyes.

Is there ANY hope of actually integrating this API into an Android project? Or should I be looking for a different solution?

I am desperate for any help at this point >.<

@t0neg0d said: Aside from importing the jar file, is there something I am missing that would make this work in Netbeans?

Well, I’ve got ads displaying and auto completion working. I haven’t written down the steps yet, but from memory it was something like the following:

  1. Use Android SDK Manager to download Google Play Services under Extras
  2. Copy the library project from android_sdk_directory->extras->google->google_play_services->libproject to somewhere
  3. Open the library project and go to project properties on the library project and pick a target android version then do a build on the library project
  4. Open your apps ‘mobile’ project created by the jme sdk
  5. Go to project properties of the mobile project and add the library in ‘referenced library projects’
  6. Do a clean and build on the apps mobile project

After that auto completion worked for me.

I’ve been able to display apps 2 ways. In a Relative Layout where the ad is place on the screen below the jme app (jme app shrunk to exposed the space for the ad) and in a Frame Layout where the ad is showing through the back of the full screen jme app (jme app in Best_Translucent mode).

I haven’t been able to get the ad to display on top of the jme app yet. The SurfaceView seems to alway be on top of the ad. Not sure why yet.

There is not a lot of code in MainActivity itself once the library project from google is added so I’m not sure yet what can be included in jme.

That’s what I got so far.

1 Like
@iwgeric said: Well, I've got ads displaying and auto completion working. I haven't written down the steps yet, but from memory it was something like the following:
  1. Use Android SDK Manager to download Google Play Services under Extras
  2. Copy the library project from android_sdk_directory->extras->google->google_play_services->libproject to somewhere
  3. Open the library project and go to project properties on the library project and pick a target android version then do a build on the library project
  4. Open your apps ‘mobile’ project created by the jme sdk
  5. Go to project properties of the mobile project and add the library in ‘referenced library projects’
  6. Do a clean and build on the apps mobile project

After that auto completion worked for me.

I’ve been able to display apps 2 ways. In a Relative Layout where the ad is place on the screen below the jme app (jme app shrunk to exposed the space for the ad) and in a Frame Layout where the ad is showing through the back of the full screen jme app (jme app in Best_Translucent mode).

I haven’t been able to get the ad to display on top of the jme app yet. The SurfaceView seems to alway be on top of the ad. Not sure why yet.

There is not a lot of code in MainActivity itself once the library project from google is added so I’m not sure yet what can be included in jme.

That’s what I got so far.

Yep…

This is about where I am at as well. Hopefully, things start going better today :wink:

Just a side note… if you are trying to use Play Game Services from google, you will need to update to version:

4323000

or there are missing packages.

Good god, Google really needs to get their shit together and decide on a static structure for their API. As it is, you can pretty much count on having to rewrite everything once a month or so >.<

@iwgeric
So sorry to be a bother… I finally almost have this. My last issue is how to build the BaseGameUtils library and I can’t seem to figure this one out (which isn’t a huge surprise, as this has been nightmarish)

There is no project, just the sources for both the basegameutils library (which consists of a whole 3 files) and a needed resource (android.support.v4.app.FragmentActivity)

I can’t find anything on the web about building this in Netbeans…

Any pointer in the right direction would be greatly appreciated.

Hey all…

Just wanted to post a bit of info on integrating Play Games Services. Setting it up was very simple, however, me being the moron I am, I didn’t consider the simple solution and was trying to get things set up the way the suggested, ignoring the suggested alternative. So, long story short…

Compile the Google Play Services jar the way it is explained here by @iwgeric and in Google’s documentation. Aside from a couple quirks, this will allow you to get AdMob going.

Now… for Play Games Services (leaderboards, achievements, Google+ login, etc, etc) you’ll want to download the BaseGameUtils project, though, you’ll only need the following files:

In the project src, where Android Main Activity is located, add:

GameHelper.java
GameHelperUtils.java

in res/values/ add:

gamehelper_strings.xml

Then clean and build your project and all should be good. Do remember that this requires Google Play Services.

Anyways, hopefully someone else will find this useful.

Heh… forgot to mention the need for:

<Android Install Dir>\sdk\extras\android\support\v4\android-support-v4.jar

Also… apparently, there is something else needed that I haven’t quite tracked down yet. It compiles, but errors out with the following:

[java]
E/AndroidRuntime(20059): FATAL EXCEPTION: main
E/AndroidRuntime(20059): java.lang.IllegalStateException: A fatal developer error has occurred. Check the logs for further information.
E/AndroidRuntime(20059): at com.google.android.gms.internal.eh$h.b(Unknown Source)
E/AndroidRuntime(20059): at com.google.android.gms.internal.eh$h.a(Unknown Source)
E/AndroidRuntime(20059): at com.google.android.gms.internal.eh$b.ec(Unknown Source)
E/AndroidRuntime(20059): at com.google.android.gms.internal.eh$a.handleMessage(Unknown Source)
E/AndroidRuntime(20059): at android.os.Handler.dispatchMessage(Handler.java:99)
E/AndroidRuntime(20059): at android.os.Looper.loop(Looper.java:137)
E/AndroidRuntime(20059): at android.app.ActivityThread.main(ActivityThread.java:4424)
E/AndroidRuntime(20059): at java.lang.reflect.Method.invokeNative(Native Method)
E/AndroidRuntime(20059): at java.lang.reflect.Method.invoke(Method.java:511)
E/AndroidRuntime(20059): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:784)
E/AndroidRuntime(20059): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:551)
E/AndroidRuntime(20059): at dalvik.system.NativeStart.main(Native Method)
[/java]

There is also a few messages before this referring to Google Play Services resources not being available (which makes no sense as it is their project that is added to the game I am running. And another stating that the manafest is missing the proper meta-data tag for APP_ID which is there as follows (as well as the @strings/app_id variable:

[java]
<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"/>
[/java]

Both of these reside in the Android Manafest under the application tag as specified in the documentation. Once again, I’m at a loss for how to proceed.

Any help would be appreciated.

Well… nm on the help. I think I have this one figured out. Google’s documentation assumes that you are extending the BaseGameActivity class and that just isn’t gonna happen. So, perhaps this will be useful to others:

Updates to Android Main Activity in prep of incorporating Google Play Services & Play Games Services:

[java]
import android.content.Intent;
import android.content.pm.ActivityInfo;
import android.os.Bundle;
import android.view.Gravity;
import android.view.ViewGroup;
import android.widget.LinearLayout;
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.common.api.GoogleApiClient;
import com.google.android.gms.games.Games;
import com.jme3.app.AndroidHarness;
import com.jme3.system.android.AndroidConfigChooser.ConfigType;
import java.util.logging.Level;
import java.util.logging.LogManager;
import <PACKAGE NAME>.Main;
import <PACKAGE NAME>.JmeToHarness;

public class MainActivity extends AndroidHarness implements JmeToHarness, GameHelper.GameHelperListener {
public static final int CLIENT_GAMES = GameHelper.CLIENT_GAMES;
public static final int CLIENT_APPSTATE = GameHelper.CLIENT_APPSTATE;
public static final int CLIENT_PLUS = GameHelper.CLIENT_PLUS;
public static final int CLIENT_ALL = GameHelper.CLIENT_ALL;

private AdView adView;
private GoogleApiClient client;
private GoogleApiClient.Builder builder;
private GoogleApiClient.ApiOptions options = null;
private GameHelper mHelper;

protected int mRequestedClients = CLIENT_GAMES;
protected boolean mDebugLog = false;

public MainActivity(){
	appClass = "&lt;PACKAGE NAME&gt;.Main";
	eglConfigType = ConfigType.FASTEST;
	exitDialogTitle = "Exit?";
	exitDialogMessage = "Press Yes";
	eglConfigVerboseLogging = false;
	screenOrientation = ActivityInfo.SCREEN_ORIENTATION_SENSOR_PORTRAIT;
	mouseEventsEnabled = true;
	LogManager.getLogManager().getLogger("").setLevel(Level.INFO);
	splashPicID = R.drawable.&lt;SPLASH SCREEN IMAGE NAME&gt;;
}

@Override
public void onCreate(Bundle savedInstanceState) {
	setRequestedClients(CLIENT_GAMES | CLIENT_APPSTATE);
	if (mHelper == null)
		getGameHelper();
	
	super.onCreate(savedInstanceState);
	
	mHelper.setup(this);
	
	if (app != null)
		((Main)app).setHarnessListener(this);
	
	adView = new AdView(this);
	adView.setAdSize(AdSize.FULL_BANNER);
	adView.setAdUnitId("&lt;YOUR AD UNIT ID&gt;");
	adView.buildLayer();

	LinearLayout ll = new LinearLayout(this);
	ll.setGravity(Gravity.BOTTOM);
	ll.addView(adView);
	addContentView(ll, new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));
}

@Override
public void update() {
	super.update();
}

@Override
public void onDestroy() {
	super.onDestroy();
	System.runFinalization();
	android.os.Process.killProcess(android.os.Process.myPid());
}

//************************//
// Base Game Activity Port
//************************//
protected void setRequestedClients(int requestedClients) {
	mRequestedClients = requestedClients;
}

public GameHelper getGameHelper() {
	if (mHelper == null) {
		mHelper = new GameHelper(this, mRequestedClients);
		mHelper.enableDebugLog(mDebugLog);
	}
	return mHelper;
}

@Override
protected void onStart() {
	super.onStart();
	mHelper.onStart(this);
}

@Override
protected void onStop() {
	super.onStop();
	mHelper.onStop();
}

@Override
protected void onActivityResult(int request, int response, Intent data) {
	super.onActivityResult(request, response, data);
	mHelper.onActivityResult(request, response, data);
}

protected GoogleApiClient getApiClient() {
	return mHelper.getApiClient();
}

protected boolean isSignedIn() {
	return mHelper.isSignedIn();
}

protected void beginUserInitiatedSignIn() {
	mHelper.beginUserInitiatedSignIn();
}

protected void signOut() {
	mHelper.signOut();
}

protected void showAlert(String message) {
	mHelper.makeSimpleDialog(message).show();
}

protected void showAlert(String title, String message) {
	mHelper.makeSimpleDialog(title, message).show();
}

protected void enableDebugLog(boolean enabled) {
	mDebugLog = true;
	if (mHelper != null) {
		mHelper.enableDebugLog(enabled);
	}
}

protected String getInvitationId() {
	return mHelper.getInvitationId();
}

protected void reconnectClient() {
	mHelper.reconnectClient();
}

protected boolean hasSignInError() {
	return mHelper.hasSignInError();
}

protected GameHelper.SignInFailureReason getSignInError() {
	return mHelper.getSignInError();
}

public void onSignInFailed() {

}

public void onSignInSucceeded() {

}

//************************//
// JmeToHarness methods
//************************//
public void unlockAchievement(String uid) {
	if (mHelper.isSignedIn())
		Games.Achievements.unlock(mHelper.getApiClient(), uid);
}

public void submitScore(String uid, long score) {
	if (mHelper.isSignedIn())
		Games.Leaderboards.submitScore(mHelper.getApiClient(), uid, score);
}

public void submitTime(String uid, long score) {
	if (mHelper.isSignedIn())
		Games.Leaderboards.submitScore(mHelper.getApiClient(), uid, score);
}

public void displayInterstitialAd() {
	InterstitialAd interstitial = new InterstitialAd(this);
	interstitial.setAdUnitId("&lt;YOUR AD UNIT ID&gt;");

	AdRequest adRequest = new AdRequest.Builder()
		.addTestDevice("&lt;YOUR TEST DEVICE ID&gt;")
		.build();
	interstitial.loadAd(adRequest);
}

public void displayBannerAd() {
	runOnUiThread(new Runnable() {
		public void run() {
			AdRequest adRequest = new AdRequest.Builder()
				.addTestDevice("&lt;YOUR TEST DEVICE ID&gt;")
				.build();
			adView.loadAd(adRequest);
			adView.bringToFront();
			adView.requestFocus();
		}
	});
}

}
[/java]

And here is JmeToHarness:
[java]
public interface JmeToHarness {
public void displayInterstitialAd();
public void displayBannerAd();
public void unlockAchievement(String uid);
public void submitScore(String uid, long score);
public void submitTime(String uid, long time);
}
[/java]

Likely you will want to disable auto-login in GameHelper.onStart() until you decide what you want to do with it.

Also note, this is by no means a final, however, it now compiles and runs properly with the above info about setting up the needed dependencies. Ignore the last post concerning something missing… it came down to setting up the helper options in onCreate before calling super.onCreate and then calling GameHelper.setup after the super call.

What I would like to eventually see incorporated into a plugin:

  • Standard Leaderboard functionality (submits, top 10 retrieval and your placement)
  • Standard Achievements functionality
  • Cloud Save and Load (Would be nice if there was a some HashMap type data structure for storing user info, save games, etc that makes this simple method calls through the JmeToHarness interface)
  • Possibly the addition of other common Ad services
  • Facebook integration might be a valid option as well. Perhaps the entire plugin suite could consist of multiple integrations that are aware of each other?

Anyways, really looking forward to this becoming a plugin like the one available for Unity. Their’s is plug & play… no reason not to have this same sort of thing for JME.

Hi there,

I’ve been trying for the last day to try and get this to work, and unfortunately I believe I am not even importing the google-play services jar correctly, as my Main Activity class won’t import any of the information.

I’ve downloaded the google services jar through the android sdk, and I try to add the jar to the project by adding it as a library directly, or turning it into a library using the library manager.

I’m using the jme sdk to attempt to do this and I am quite frustrated at this point.

Any help is appreciated here.

As far as i know Android studio has GServices. Can we check how they did it?
http://developer.android.com/sdk/installing/studio.html

They use IntellyJ Idea.

@BigBob said: Hi there,

I’ve been trying for the last day to try and get this to work, and unfortunately I believe I am not even importing the google-play services jar correctly, as my Main Activity class won’t import any of the information.

I’ve downloaded the google services jar through the android sdk, and I try to add the jar to the project by adding it as a library directly, or turning it into a library using the library manager.

I’m using the jme sdk to attempt to do this and I am quite frustrated at this point.

Any help is appreciated here.

I’ll try and help here, though I am seeing all sorts of resource not found crap in the logcat… it doesn’t stop the app, but I have a feeling I am not really doing this right as well.

I am doing the following to add Google Play Services:

Downloading through SDK Manager
Copying <INSTALL DIR>\sdk\extras\google\google_play_services\libproject to a new location (somewhere under you JME Projects folder would work fine)
Opening the project through JME’s IDE
Opening up the project properties and selecting the target version for the build
Running Clean & Build
Adding the outputted .jar to my Android project

EDIT: My next attempt will be to add the project as a library and see if the res crap can be resolved properly.

@mifth said: As far as i know Android studio has GServices. Can we check how they did it? http://developer.android.com/sdk/installing/studio.html

They use IntellyJ Idea.

I’ll look into this after resolving a couple of questions/support requests with the GUI library. The part of this that has been so frustrating is it looks like just about NOBODY uses NetBeans for Android dev, so there is ZILCH info out there on getting this to work through NetBeans. =(

Hopefully your suggestion will shed some light on it.