mirror of
https://github.com/libsdl-org/SDL.git
synced 2026-07-31 04:28:56 +00:00
Use the modern OnBackInvokedCallback method to trap the back button on newer Android devices (#16052)
This commit is contained in:
@@ -71,7 +71,7 @@
|
||||
android:icon="@mipmap/ic_launcher"
|
||||
android:allowBackup="true"
|
||||
android:theme="@style/AppTheme"
|
||||
android:enableOnBackInvokedCallback="false"
|
||||
android:enableOnBackInvokedCallback="true"
|
||||
android:hardwareAccelerated="true" >
|
||||
|
||||
<!-- Example of setting SDL hints from AndroidManifest.xml:
|
||||
|
||||
@@ -24,6 +24,7 @@ import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
import android.os.Handler;
|
||||
import android.os.LocaleList;
|
||||
import android.os.Looper;
|
||||
import android.os.Message;
|
||||
import android.os.ParcelFileDescriptor;
|
||||
import android.provider.DocumentsContract;
|
||||
@@ -50,6 +51,8 @@ import android.widget.LinearLayout;
|
||||
import android.widget.RelativeLayout;
|
||||
import android.widget.TextView;
|
||||
import android.widget.Toast;
|
||||
import android.window.OnBackInvokedCallback;
|
||||
import android.window.OnBackInvokedDispatcher;
|
||||
|
||||
import java.io.FileNotFoundException;
|
||||
import java.util.ArrayList;
|
||||
@@ -784,6 +787,47 @@ public class SDLActivity extends Activity implements View.OnSystemUiVisibilityCh
|
||||
}
|
||||
}
|
||||
|
||||
static OnBackInvokedCallback backButtonCallback = new OnBackInvokedCallback() {
|
||||
Handler mBackKeyHandler;
|
||||
|
||||
@Override
|
||||
public void onBackInvoked() {
|
||||
if (mBackKeyHandler == null) {
|
||||
mBackKeyHandler = new Handler(Looper.getMainLooper());
|
||||
}
|
||||
|
||||
onNativeKeyDown(KeyEvent.KEYCODE_BACK);
|
||||
mBackKeyHandler.postDelayed(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
onNativeKeyUp(KeyEvent.KEYCODE_BACK);
|
||||
}
|
||||
}, 500);
|
||||
}
|
||||
};
|
||||
|
||||
static boolean mBackKeyTrapEnabled = false;
|
||||
public static void setBackButtonTrapEnabled(boolean enabled) {
|
||||
|
||||
if ( Build.VERSION.SDK_INT < 33 ) {
|
||||
// We're old enough that we just use the old onBackPressed behavior.
|
||||
return;
|
||||
}
|
||||
|
||||
// Check so we don't register the same callback twice.
|
||||
if (enabled == mBackKeyTrapEnabled) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (enabled) {
|
||||
mSingleton.getOnBackInvokedDispatcher().registerOnBackInvokedCallback(OnBackInvokedDispatcher.PRIORITY_DEFAULT, backButtonCallback);
|
||||
}
|
||||
else {
|
||||
mSingleton.getOnBackInvokedDispatcher().unregisterOnBackInvokedCallback(backButtonCallback);
|
||||
}
|
||||
mBackKeyTrapEnabled = enabled;
|
||||
}
|
||||
|
||||
// File dialog types
|
||||
private static final int SDL_FILEDIALOG_OPENFILE = 0;
|
||||
private static final int SDL_FILEDIALOG_SAVEFILE = 1;
|
||||
|
||||
@@ -101,6 +101,7 @@ static jmethodID midManualBackButton;
|
||||
static jmethodID midShowFileDialog;
|
||||
#endif // !SDL_DIALOG_DISABLED
|
||||
static jmethodID midGetPreferredLocales;
|
||||
static jmethodID midSetBackButtonTrapEnabled;
|
||||
|
||||
#ifndef SDL_VIDEO_DISABLED
|
||||
// Video/surface method signatures
|
||||
@@ -681,6 +682,7 @@ JNIEXPORT void JNICALL SDL_JAVA_INTERFACE(nativeSetupJNI)(JNIEnv *env, jclass cl
|
||||
midShowFileDialog = (*env)->GetStaticMethodID(env, mActivityClass, "showFileDialog", "([Ljava/lang/String;ZILjava/lang/String;I)Z");
|
||||
#endif // !SDL_DIALOG_DISABLED
|
||||
midGetPreferredLocales = (*env)->GetStaticMethodID(env, mActivityClass, "getPreferredLocales", "()Ljava/lang/String;");
|
||||
midSetBackButtonTrapEnabled = (*env)->GetStaticMethodID(env, mActivityClass, "setBackButtonTrapEnabled", "(Z)V");
|
||||
|
||||
if (!midGetContext ||
|
||||
!midGetDeviceFormFactor ||
|
||||
@@ -698,7 +700,8 @@ JNIEXPORT void JNICALL SDL_JAVA_INTERFACE(nativeSetupJNI)(JNIEnv *env, jclass cl
|
||||
#ifndef SDL_DIALOG_DISABLED
|
||||
!midShowFileDialog ||
|
||||
#endif
|
||||
!midGetPreferredLocales) {
|
||||
!midGetPreferredLocales ||
|
||||
!midSetBackButtonTrapEnabled) {
|
||||
__android_log_print(ANDROID_LOG_WARN, "SDL", "Missing some core Java callbacks, do you have the latest version of SDLActivity.java?");
|
||||
}
|
||||
|
||||
@@ -3714,4 +3717,14 @@ bool Android_JNI_ShowFileDialog(
|
||||
}
|
||||
#endif // !SDL_DIALOG_DISABLED
|
||||
|
||||
void Android_JNI_SetBackButtonTrapActive(bool enabled)
|
||||
{
|
||||
if (!midSetBackButtonTrapEnabled) {
|
||||
return;
|
||||
}
|
||||
|
||||
JNIEnv *env = Android_JNI_GetEnv();
|
||||
(*env)->CallStaticVoidMethod(env, mActivityClass, midSetBackButtonTrapEnabled, enabled);
|
||||
}
|
||||
|
||||
#endif // SDL_PLATFORM_ANDROID
|
||||
|
||||
@@ -60,6 +60,7 @@ void Android_LockActivityMutex(void);
|
||||
void Android_UnlockActivityMutex(void);
|
||||
|
||||
void Android_SetAllowRecreateActivity(bool enabled);
|
||||
void Android_JNI_SetBackButtonTrapActive(bool enabled);
|
||||
|
||||
#ifndef SDL_VIDEO_DISABLED
|
||||
#include <EGL/eglplatform.h>
|
||||
|
||||
@@ -28,6 +28,7 @@
|
||||
#include "../SDL_pixels_c.h"
|
||||
#include "../../events/SDL_events_c.h"
|
||||
#include "../../events/SDL_windowevents_c.h"
|
||||
#include "../../SDL_hints_c.h"
|
||||
|
||||
#include "SDL_androidvideo.h"
|
||||
#include "SDL_androidgl.h"
|
||||
@@ -81,6 +82,16 @@ static void Android_DeleteDevice(SDL_VideoDevice *device)
|
||||
SDL_free(device);
|
||||
}
|
||||
|
||||
// Input is part of video for Android, so this goes here.
|
||||
static void SDLCALL Android_Video_InternalHintCallback(
|
||||
void *userdata,
|
||||
const char *name,
|
||||
const char *oldvalue,
|
||||
const char *newvalue)
|
||||
{
|
||||
Android_JNI_SetBackButtonTrapActive(SDL_GetStringBoolean(newvalue, false));
|
||||
}
|
||||
|
||||
static SDL_VideoDevice *Android_CreateDevice(void)
|
||||
{
|
||||
SDL_VideoDevice *device;
|
||||
@@ -185,6 +196,8 @@ bool Android_VideoInit(SDL_VideoDevice *_this)
|
||||
display->current_orientation = Android_JNI_GetDisplayCurrentOrientation();
|
||||
display->content_scale = Android_ScreenDensity;
|
||||
|
||||
SDL_AddHintCallback(SDL_HINT_ANDROID_TRAP_BACK_BUTTON, Android_Video_InternalHintCallback, 0);
|
||||
|
||||
Android_InitTouch();
|
||||
|
||||
Android_InitMouse();
|
||||
@@ -195,6 +208,7 @@ bool Android_VideoInit(SDL_VideoDevice *_this)
|
||||
|
||||
void Android_VideoQuit(SDL_VideoDevice *_this)
|
||||
{
|
||||
SDL_RemoveHintCallback(SDL_HINT_ANDROID_TRAP_BACK_BUTTON, Android_Video_InternalHintCallback, 0);
|
||||
Android_QuitMouse();
|
||||
Android_QuitTouch();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user