FacebookTwitterGoogle+Share

Dealing with the Android back button for Heaps/Hashlink

I wanted the back button on Android to work in a reasonable way for Hexlock: If you’re playing, the back button should take you back to the level select screen. If you’re at the level select screen, it should do what the back button does on Androids, and minimize the app.

It turns out that different versions of Android send different key codes with the event when you hit the back button, (and I also wanted to support Esc and Backspace on keyboard), so I matched a few of them.

var g = new LevelSelect();
sceneManager.requestMainMenu = function() {
	var s = sceneManager.switchScene(g);
	if (s == g) {
		trace("Already on the main menu, exit game");
		exitapp();
	}
}

hxd.Window.getInstance().addEventTarget(function(event : hxd.Event) {
	switch(event.kind) {
		case EKeyUp: 
			// backspace and escape; the last one is what my android sends for back
			if (event.keyCode == 8 || event.keyCode == 27 || event.keyCode == 1270)
				sceneManager.requestMainMenu();
		case _: // Match the rest
	}
});

Then I added a static function exitapp() to my Main class, the idea being that it would do nothing unless I was compiling for Android. (I added -D android to my compile-to-c.hxml for just this purpose). There may already be a hlNative one, but who knows at this point. I didn’t see one, and adding -D android was easy enough.

#if android
@:hlNative("Java_io_heaps_android_HeapsActivity")
#end
public static function exitapp() : Void { }

When compiling to C code for Hashlink, calls to the function Main.exitapp() get replaced with Java_io_heaps_android_HeapsActivity_exitapp(), which I defined in my jni.c1 file.

JNIEXPORT void JNICALL Java_io_heaps_android_HeapsActivity_exitapp() {
	(*jvm)->AttachCurrentThread(jvm, &thisEnv, 0);
	jclass cls = (*thisEnv)->FindClass(thisEnv, "io/heaps/android/HeapsActivity");
	jmethodID method = (*thisEnv)->GetStaticMethodID(thisEnv, cls, "callbackExit", "()V");
	if (method > 0)
		(*thisEnv)->CallStaticVoidMethod(thisEnv, cls, method);
}

To find out more about where thisEnv and jvm come from, check out triggering vibration on Android from Heaps/Hashlink.

As you can see the C code assumes there is an callbackExit() function in io.heaps.android.HeapsActivity, and there is, because I added one!

public static void callbackExit() {
	Intent intent = new Intent(Intent.ACTION_MAIN);
	intent.addCategory(Intent.CATEGORY_HOME);
	instance.startActivity(intent);
}

And that seemed to work! Even better, it didn’t crash.

If you want to find out more about the files I’m referencing (including a Git repo hosting them), you can do so here: Hello World; Heaps on Android.

Comments

You must be logged in to post a comment.