Android alert display functionality using JNI

This commit is contained in:
saschawillems 2018-04-30 22:24:45 +02:00
parent 1227f1e7f4
commit 5056563f5d
5 changed files with 64 additions and 3 deletions

View file

@ -1,9 +1,10 @@
apply plugin: 'com.android.application' apply plugin: 'com.android.application'
apply from: '../gradle/outputfilename.gradle'
android { android {
compileSdkVersion 26 compileSdkVersion 26
defaultConfig { defaultConfig {
applicationId "de.saschawillems.vulkanTriangle" applicationId "de.saschawillems.VulkanTriangle"
minSdkVersion 19 minSdkVersion 19
targetSdkVersion 26 targetSdkVersion 26
versionCode 1 versionCode 1

View file

@ -5,10 +5,18 @@
*/ */
package de.saschawillems.vulkanSample; package de.saschawillems.vulkanSample;
import android.app.AlertDialog;
import android.app.NativeActivity; import android.app.NativeActivity;
import android.content.DialogInterface;
import android.content.pm.ApplicationInfo;
import android.os.Bundle; import android.os.Bundle;
import java.util.concurrent.Semaphore;
public class VulkanActivity extends NativeActivity { public class VulkanActivity extends NativeActivity {
VulkanActivity _activity;
static { static {
// Load native library // Load native library
System.loadLibrary("native-lib"); System.loadLibrary("native-lib");
@ -16,5 +24,36 @@ public class VulkanActivity extends NativeActivity {
@Override @Override
protected void onCreate(Bundle savedInstanceState) { protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
_activity = this;
}
// Use a semaphore to create a modal dialog
private final Semaphore semaphore = new Semaphore(0, true);
public void showAlert(final String message)
{
ApplicationInfo applicationInfo = _activity.getApplicationInfo();
final String applicationName = applicationInfo.nonLocalizedLabel.toString();
this.runOnUiThread(new Runnable() {
public void run() {
AlertDialog.Builder builder = new AlertDialog.Builder(_activity, AlertDialog.THEME_HOLO_DARK);
builder.setTitle(applicationName);
builder.setMessage(message);
builder.setPositiveButton("Close", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
semaphore.release();
}
});
builder.setCancelable(false);
AlertDialog dialog = builder.create();
dialog.show();
}
});
try {
semaphore.acquire();
}
catch (InterruptedException e) { }
} }
} }

View file

@ -11,6 +11,7 @@
#if defined(__ANDROID__) #if defined(__ANDROID__)
#include <android/log.h> #include <android/log.h>
#include <dlfcn.h> #include <dlfcn.h>
#include <android/native_window_jni.h>
android_app* androidApp; android_app* androidApp;
@ -292,6 +293,23 @@ namespace vks
vks::android::screenDensity = AConfiguration_getDensity(config); vks::android::screenDensity = AConfiguration_getDensity(config);
AConfiguration_delete(config); AConfiguration_delete(config);
} }
// Displays a native alert dialog using JNI
void showAlert(const char* message) {
JNIEnv* jni;
androidApp->activity->vm->AttachCurrentThread(&jni, NULL);
jstring jmessage = jni->NewStringUTF(message);
jclass clazz = jni->GetObjectClass(androidApp->activity->clazz);
// Signature has to match java implementation (arguments)
jmethodID methodID = jni->GetMethodID(clazz, "showAlert", "(Ljava/lang/String;)V");
jni->CallVoidMethod(androidApp->activity->clazz, methodID, jmessage);
jni->DeleteLocalRef(jmessage);
androidApp->activity->vm->DetachCurrentThread();
return;
}
} }
} }

View file

@ -26,6 +26,7 @@
#include <android_native_app_glue.h> #include <android_native_app_glue.h>
#include <android/configuration.h> #include <android/configuration.h>
#include <memory> #include <memory>
#include <string>
// Missing from the NDK // Missing from the NDK
namespace std namespace std
@ -169,6 +170,7 @@ namespace vks
void loadVulkanFunctions(VkInstance instance); void loadVulkanFunctions(VkInstance instance);
void freeVulkanLibrary(); void freeVulkanLibrary();
void getDeviceConfig(); void getDeviceConfig();
void showAlert(const char* message);
} }
} }

View file

@ -269,7 +269,8 @@ namespace vks
MessageBox(NULL, message.c_str(), NULL, MB_OK | MB_ICONERROR); MessageBox(NULL, message.c_str(), NULL, MB_OK | MB_ICONERROR);
} }
#elif defined(__ANDROID__) #elif defined(__ANDROID__)
LOGE("Fatal error: %s", message.c_str()); LOGE("Fatal error: %s", message.c_str());
vks::android::showAlert(message.c_str());
#endif #endif
std::cerr << message << "\n"; std::cerr << message << "\n";
exit(exitCode); exit(exitCode);