diff --git a/android/examples/triangle/build.gradle b/android/examples/triangle/build.gradle index 6c207bd8..3d36cbc6 100644 --- a/android/examples/triangle/build.gradle +++ b/android/examples/triangle/build.gradle @@ -1,9 +1,10 @@ apply plugin: 'com.android.application' +apply from: '../gradle/outputfilename.gradle' android { compileSdkVersion 26 defaultConfig { - applicationId "de.saschawillems.vulkanTriangle" + applicationId "de.saschawillems.VulkanTriangle" minSdkVersion 19 targetSdkVersion 26 versionCode 1 diff --git a/android/examples/triangle/src/main/java/de/saschawillems/vulkanSample/VulkanActivity.java b/android/examples/triangle/src/main/java/de/saschawillems/vulkanSample/VulkanActivity.java index f9500cd4..a13088db 100644 --- a/android/examples/triangle/src/main/java/de/saschawillems/vulkanSample/VulkanActivity.java +++ b/android/examples/triangle/src/main/java/de/saschawillems/vulkanSample/VulkanActivity.java @@ -5,10 +5,18 @@ */ package de.saschawillems.vulkanSample; +import android.app.AlertDialog; import android.app.NativeActivity; +import android.content.DialogInterface; +import android.content.pm.ApplicationInfo; import android.os.Bundle; +import java.util.concurrent.Semaphore; + public class VulkanActivity extends NativeActivity { + + VulkanActivity _activity; + static { // Load native library System.loadLibrary("native-lib"); @@ -16,5 +24,36 @@ public class VulkanActivity extends NativeActivity { @Override protected void onCreate(Bundle 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) { } } } diff --git a/base/VulkanAndroid.cpp b/base/VulkanAndroid.cpp index aba260ae..a0aa2b8c 100644 --- a/base/VulkanAndroid.cpp +++ b/base/VulkanAndroid.cpp @@ -11,6 +11,7 @@ #if defined(__ANDROID__) #include #include + #include android_app* androidApp; @@ -292,6 +293,23 @@ namespace vks vks::android::screenDensity = AConfiguration_getDensity(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; + } } } diff --git a/base/VulkanAndroid.h b/base/VulkanAndroid.h index 372b36ef..f3a2d68c 100644 --- a/base/VulkanAndroid.h +++ b/base/VulkanAndroid.h @@ -26,6 +26,7 @@ #include #include #include +#include // Missing from the NDK namespace std @@ -169,6 +170,7 @@ namespace vks void loadVulkanFunctions(VkInstance instance); void freeVulkanLibrary(); void getDeviceConfig(); + void showAlert(const char* message); } } diff --git a/base/VulkanTools.cpp b/base/VulkanTools.cpp index 12f6c101..3dd28bbf 100644 --- a/base/VulkanTools.cpp +++ b/base/VulkanTools.cpp @@ -268,8 +268,9 @@ namespace vks if (!errorModeSilent) { MessageBox(NULL, message.c_str(), NULL, MB_OK | MB_ICONERROR); } -#elif defined(__ANDROID__) - LOGE("Fatal error: %s", message.c_str()); +#elif defined(__ANDROID__) + LOGE("Fatal error: %s", message.c_str()); + vks::android::showAlert(message.c_str()); #endif std::cerr << message << "\n"; exit(exitCode);