android_file_dialog.c 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105
  1. #include "android_file_dialog.h"
  2. #include "android_native_app_glue.h"
  3. #include <iron_system.h>
  4. #include <jni.h>
  5. #include <stdlib.h>
  6. #include <string.h>
  7. #include <sys/stat.h>
  8. #include <sys/types.h>
  9. extern char android_title[1024];
  10. ANativeActivity *iron_android_get_activity(void);
  11. jclass iron_android_find_class(JNIEnv *env, const char *name);
  12. JNIEXPORT void JNICALL Java_org_armory3d_IronActivity_onAndroidFilePicked(JNIEnv *env, jobject jobj, jstring jstr) {
  13. if (jstr == NULL)
  14. return;
  15. const char *str = (*env)->GetStringUTFChars(env, jstr, 0);
  16. iron_internal_drop_files_callback(str);
  17. (*env)->ReleaseStringUTFChars(env, jstr, str);
  18. }
  19. JNIEXPORT jstring JNICALL Java_org_armory3d_IronActivity_getMobileTitle(JNIEnv *env, jobject jobj) {
  20. jstring result = (*env)->NewStringUTF(env, android_title);
  21. return result;
  22. }
  23. void AndroidFileDialogOpen() {
  24. ANativeActivity *activity = iron_android_get_activity();
  25. JNIEnv *env;
  26. JavaVM *vm = iron_android_get_activity()->vm;
  27. (*vm)->AttachCurrentThread(vm, &env, NULL);
  28. jclass ironActivityClass = iron_android_find_class(env, "org.armory3d.IronActivity");
  29. (*env)->CallStaticVoidMethod(env, ironActivityClass, (*env)->GetStaticMethodID(env, ironActivityClass, "pickFile", "()V"));
  30. (*vm)->DetachCurrentThread(vm);
  31. }
  32. wchar_t *AndroidFileDialogSave() {
  33. // iron_android_get_activity()->externalDataPath; // /storage/emulated/0/Android/data/org.armorpaint/files
  34. mkdir("/storage/emulated/0/Pictures/ArmorPaint", 0777);
  35. return L"/storage/emulated/0/Pictures/ArmorPaint/untitled";
  36. }
  37. jstring android_permission_name(JNIEnv *env, const char *perm_name) {
  38. jclass ClassManifestpermission = (*env)->FindClass(env, "android/Manifest$permission");
  39. jfieldID lid_PERM = (*env)->GetStaticFieldID(env, ClassManifestpermission, perm_name, "Ljava/lang/String;");
  40. jstring ls_PERM = (jstring)((*env)->GetStaticObjectField(env, ClassManifestpermission, lid_PERM));
  41. return ls_PERM;
  42. }
  43. bool android_has_permission(struct android_app *app, const char *perm_name) {
  44. ANativeActivity *activity = iron_android_get_activity();
  45. JNIEnv *env;
  46. JavaVM *vm = iron_android_get_activity()->vm;
  47. (*vm)->AttachCurrentThread(vm, &env, NULL);
  48. bool result = false;
  49. jstring ls_PERM = android_permission_name(env, perm_name);
  50. jint PERMISSION_GRANTED = (jint)(-1);
  51. {
  52. jclass ClassPackageManager = (*env)->FindClass(env, "android/content/pm/PackageManager");
  53. jfieldID lid_PERMISSION_GRANTED = (*env)->GetStaticFieldID(env, ClassPackageManager, "PERMISSION_GRANTED", "I");
  54. PERMISSION_GRANTED = (*env)->GetStaticIntField(env, ClassPackageManager, lid_PERMISSION_GRANTED);
  55. }
  56. {
  57. jobject activity = app->activity->clazz;
  58. jclass ClassContext = (*env)->FindClass(env, "android/content/Context");
  59. jmethodID MethodcheckSelfPermission = (*env)->GetMethodID(env, ClassContext, "checkSelfPermission", "(Ljava/lang/String;)I");
  60. jint int_result = (*env)->CallIntMethod(env, activity, MethodcheckSelfPermission, ls_PERM);
  61. result = (int_result == PERMISSION_GRANTED);
  62. }
  63. (*vm)->DetachCurrentThread(vm);
  64. return result;
  65. }
  66. void android_request_file_permissions(struct android_app *app) {
  67. ANativeActivity *activity = iron_android_get_activity();
  68. JNIEnv *env;
  69. JavaVM *vm = iron_android_get_activity()->vm;
  70. (*vm)->AttachCurrentThread(vm, &env, NULL);
  71. jobjectArray perm_array = (*env)->NewObjectArray(env, 1, (*env)->FindClass(env, "java/lang/String"), (*env)->NewStringUTF(env, ""));
  72. (*env)->SetObjectArrayElement(env, perm_array, 0, android_permission_name(env, "READ_MEDIA_IMAGES")); // MANAGE_EXTERNAL_STORAGE
  73. jobject jactivity = app->activity->clazz;
  74. jclass ClassActivity = (*env)->FindClass(env, "android/app/Activity");
  75. jmethodID MethodrequestPermissions = (*env)->GetMethodID(env, ClassActivity, "requestPermissions", "([Ljava/lang/String;I)V");
  76. (*env)->CallVoidMethod(env, jactivity, MethodrequestPermissions, perm_array, 0);
  77. (*vm)->DetachCurrentThread(vm);
  78. }
  79. void android_check_permissions() {
  80. ANativeActivity *activity = iron_android_get_activity();
  81. struct android_app *app = (struct android_app *)activity->instance;
  82. bool hasPermissions = android_has_permission(app, "READ_MEDIA_IMAGES"); // MANAGE_EXTERNAL_STORAGE
  83. if (!hasPermissions)
  84. android_request_file_permissions(app);
  85. JNIEnv *env;
  86. JavaVM *vm = iron_android_get_activity()->vm;
  87. (*vm)->AttachCurrentThread(vm, &env, NULL);
  88. jclass ironActivityClass = iron_android_find_class(env, "org.armory3d.IronActivity");
  89. JNINativeMethod methodTable[] = {{"onAndroidFilePicked", "(Ljava/lang/String;)V", (void *)Java_org_armory3d_IronActivity_onAndroidFilePicked},
  90. {"getMobileTitle", "()Ljava/lang/String;", (void *)Java_org_armory3d_IronActivity_getMobileTitle}};
  91. int methodTableSize = sizeof(methodTable) / sizeof(methodTable[0]);
  92. (*env)->RegisterNatives(env, ironActivityClass, methodTable, methodTableSize);
  93. (*vm)->DetachCurrentThread(vm);
  94. }