Allow handling ACTION_MULTIPLE for unicode and voice message

This commit is contained in:
Benau 2019-05-18 09:15:58 +08:00
parent 2d3ae6aefc
commit 0e1c0d1541
5 changed files with 97 additions and 5 deletions

View File

@ -131,7 +131,8 @@ LOCAL_CFLAGS := -I../lib/irrlicht/source/Irrlicht/ \
-I../lib/irrlicht/include/ \
-Iobj/jpeglib/ \
-Iobj/libpng/ \
-Iobj/zlib/
-Iobj/zlib/ \
-DANDROID_PACKAGE_CALLBACK_NAME=$(PACKAGE_CALLBACK_NAME)
LOCAL_CPPFLAGS := -std=gnu++0x
LOCAL_STATIC_LIBRARIES := jpeglib png zlib
include $(BUILD_STATIC_LIBRARY)

View File

@ -5,17 +5,16 @@
android:versionName="git"
android:installLocation="auto">
<!-- This .apk has no Java code itself, so set hasCode to false. -->
<application android:label="@string/app_name"
android:icon="@drawable/icon"
android:banner="@drawable/banner"
android:hasCode="false"
android:hasCode="true"
android:isGame="true"
android:theme="@android:style/Theme.DeviceDefault.NoActionBar.TranslucentDecor"
android:hardwareAccelerated="true"
android:resizeableActivity="false">
<activity android:name="android.app.NativeActivity"
<activity android:name=".SuperTuxKartActivity"
android:label="@string/app_name"
android:launchMode="singleTask"
android:configChanges="fontScale|keyboard|keyboardHidden|layoutDirection|locale|mcc|mnc|navigation|orientation|screenLayout|screenSize|uiMode"

View File

@ -52,16 +52,19 @@ export COMPILE_SDK_VERSION_X86_64=26
export APP_NAME_RELEASE="SuperTuxKart"
export PACKAGE_NAME_RELEASE="org.supertuxkart.stk"
export PACKAGE_CALLBACK_NAME_RELEASE="org_supertuxkart_stk"
export APP_DIR_NAME_RELEASE="supertuxkart"
export APP_ICON_RELEASE="$DIRNAME/icon.png"
export APP_NAME_BETA="SuperTuxKart Beta"
export PACKAGE_NAME_BETA="org.supertuxkart.stk_beta"
export PACKAGE_CALLBACK_NAME_BETA="org_supertuxkart_stk_1beta"
export APP_DIR_NAME_BETA="supertuxkart-beta"
export APP_ICON_BETA="$DIRNAME/icon-dbg.png"
export APP_NAME_DEBUG="SuperTuxKart Debug"
export PACKAGE_NAME_DEBUG="org.supertuxkart.stk_dbg"
export PACKAGE_CALLBACK_NAME_DEBUG="org_supertuxkart_stk_1dbg"
export APP_DIR_NAME_DEBUG="supertuxkart-dbg"
export APP_ICON_DEBUG="$DIRNAME/icon-dbg.png"
@ -154,6 +157,7 @@ if [ "$BUILD_TYPE" = "debug" ] || [ "$BUILD_TYPE" = "Debug" ]; then
export IS_DEBUG_BUILD=1
export APP_NAME="$APP_NAME_DEBUG"
export PACKAGE_NAME="$PACKAGE_NAME_DEBUG"
export PACKAGE_CALLBACK_NAME="$PACKAGE_CALLBACK_NAME_DEBUG"
export APP_DIR_NAME="$APP_DIR_NAME_DEBUG"
export APP_ICON="$APP_ICON_DEBUG"
elif [ "$BUILD_TYPE" = "release" ] || [ "$BUILD_TYPE" = "Release" ]; then
@ -162,6 +166,7 @@ elif [ "$BUILD_TYPE" = "release" ] || [ "$BUILD_TYPE" = "Release" ]; then
export IS_DEBUG_BUILD=0
export APP_NAME="$APP_NAME_RELEASE"
export PACKAGE_NAME="$PACKAGE_NAME_RELEASE"
export PACKAGE_CALLBACK_NAME="$PACKAGE_CALLBACK_NAME_RELEASE"
export APP_DIR_NAME="$APP_DIR_NAME_RELEASE"
export APP_ICON="$APP_ICON_RELEASE"
elif [ "$BUILD_TYPE" = "beta" ] || [ "$BUILD_TYPE" = "Beta" ]; then
@ -170,6 +175,7 @@ elif [ "$BUILD_TYPE" = "beta" ] || [ "$BUILD_TYPE" = "Beta" ]; then
export IS_DEBUG_BUILD=0
export APP_NAME="$APP_NAME_BETA"
export PACKAGE_NAME="$PACKAGE_NAME_BETA"
export PACKAGE_CALLBACK_NAME="$PACKAGE_CALLBACK_NAME_BETA"
export APP_DIR_NAME="$APP_DIR_NAME_BETA"
export APP_ICON="$APP_ICON_BETA"
else
@ -464,7 +470,10 @@ sed -i "s/targetSdkVersion=\".*\"/targetSdkVersion=\"$TARGET_SDK_VERSION\"/g" \
sed -i "s/package=\".*\"/package=\"$PACKAGE_NAME\"/g" \
"$DIRNAME/AndroidManifest.xml"
sed -i "s/package .*/package $PACKAGE_NAME;/g" \
"$DIRNAME/src/main/java/SuperTuxKartActivity.java"
sed -i "s/versionName=\".*\"/versionName=\"$PROJECT_VERSION\"/g" \
"$DIRNAME/AndroidManifest.xml"

View File

@ -0,0 +1,36 @@
package org.supertuxkart.stk_dbg;
import android.app.NativeActivity;
import android.os.Bundle;
import android.view.KeyEvent;
public class SuperTuxKartActivity extends NativeActivity
{
private native void saveFromJavaChars(String chars);
@Override
public void onCreate(Bundle instance)
{
super.onCreate(instance);
System.loadLibrary("main");
}
@Override
public boolean dispatchKeyEvent(KeyEvent event)
{
// ACTION_MULTIPLE deprecated in API level Q, it says if the key code
// is KEYCODE_UNKNOWN, then this is a sequence of characters as
// returned by getCharacters()
if (event.getKeyCode() == KeyEvent.KEYCODE_UNKNOWN &&
event.getAction() == KeyEvent.ACTION_MULTIPLE)
{
String chars = event.getCharacters();
if (chars != null)
{
saveFromJavaChars(chars);
return true;
}
}
return super.dispatchKeyEvent(event);
}
}

View File

@ -9,10 +9,37 @@
#ifdef _IRR_COMPILE_WITH_ANDROID_DEVICE_
#include <assert.h>
#include <vector>
#include "os.h"
#include "CContextEGL.h"
#include "CFileSystem.h"
#include "COGLES2Driver.h"
#include "../../../../src/utils/utf8/unchecked.h"
std::string g_from_java_chars;
// Save any String in java to g_from_java_chars (triggered by voice-text input,
// clipboard or unicode char from keyboard) and manually postEventFromUser for
// each character
#if !defined(ANDROID_PACKAGE_CALLBACK_NAME)
#error
#endif
#define MAKE_ANDROID_CALLBACK(x) JNIEXPORT void JNICALL Java_ ## x##_SuperTuxKartActivity_saveFromJavaChars(JNIEnv* env, jobject this_obj, jstring from_java_chars)
#define ANDROID_CALLBACK(PKG_NAME) MAKE_ANDROID_CALLBACK(PKG_NAME)
extern "C"
ANDROID_CALLBACK(ANDROID_PACKAGE_CALLBACK_NAME)
{
if (from_java_chars == NULL)
return;
const char* chars = env->GetStringUTFChars(from_java_chars, NULL);
if (chars == NULL)
return;
g_from_java_chars += chars;
env->ReleaseStringUTFChars(from_java_chars, chars);
}
namespace irr
{
@ -240,6 +267,26 @@ bool CIrrDeviceAndroid::run()
while (!Close)
{
if (!g_from_java_chars.empty())
{
std::vector<wchar_t> utf32;
const char* chars = g_from_java_chars.c_str();
utf8::unchecked::utf8to32(chars, chars + strlen(chars), back_inserter(utf32));
for (wchar_t wc : utf32)
{
SEvent event;
event.EventType = EET_KEY_INPUT_EVENT;
event.KeyInput.Char = wc;
event.KeyInput.PressedDown = true;
event.KeyInput.Key = IRR_KEY_UNKNOWN;
event.KeyInput.Shift = false;
event.KeyInput.Control = false;
event.KeyInput.SystemKeyCode = 0;
event.KeyInput.Key = IRR_KEY_UNKNOWN;
postEventFromUser(event);
}
g_from_java_chars.clear();
}
s32 Events = 0;
android_poll_source* Source = 0;
bool should_run = (IsStarted && IsFocused && !IsPaused);