'Permission Management in ANativeActivity

I have my app written entirely in Native via ANativeActivity and need to request permissions from the user.

To check whether the app has the permissions or not, I have the following.

bool NativeActivityHelper::hasPermission(const std::string &permission) {
  JNIEnv *env = 0;
  mApp->activity->vm->AttachCurrentThread(&env, NULL); /* struct android_app *mApp */

  jclass ClassManifestpermission = env->FindClass("android/Manifest$permission");
  jfieldID FieldPermission = env->GetStaticFieldID(ClassManifestpermission, permission.c_str(), "Ljava/lang/String;");
  jstring StringPermission = (jstring)env->GetStaticObjectField(ClassManifestpermission, FieldPermission));

  jclass ClassPackageManager = env->FindClass("android/content/pm/PackageManager");
  jfieldID FieldPermissionGranted = env->GetStaticFieldID(ClassPackageManager, "PERMISSION_GRANTED", "I");
  jint IntPermissionGranted = env->GetStaticIntField(ClassPackageManager, FieldPermissionGranted);

  jclass ClassContext = env->FindClass("android/content/Context");
  jmethodID MethodcheckSelfPermission = env->GetMethodID(ClassContext, "checkSelfPermission", "(Ljava/lang/String;)I");
  bool ret = (IntPermissionGranted == env->CallIntMethod(mApp->activity->clazz, MethodcheckSelfPermission, StringPermission));

  mApp->activity->vm->DetachCurrentThread();
  return ret;
}

And to request I have the following

void NativeActivityHelper::requestPermission(const std::string &permission, std::function<void(const std::string &permission, bool status)> onRequestDone) {
  if (!hasPermission(permission)) {
    async = std::thread([=]{
    JNIEnv *env = 0;
    mApp->activity->vm->AttachCurrentThread(&env, NULL);
  jobjectArray ArrayPermissions = env->NewObjectArray(1, env->FindClass("java/lang/String"), env->NewStringUTF(""));

    jclass ClassManifestpermission = env->FindClass("android/Manifest$permission");
    jfieldID FieldPermission = env->GetStaticFieldID(ClassManifestpermission, permission.c_str(), "Ljava/lang/String;");
    jstring StringPermission = (jstring)(env->GetStaticObjectField(ClassManifestpermission, FieldPermission));

    env->SetObjectArrayElement(ArrayPermissions, 0, StringPermission);
    jclass ClassActivity = env->FindClass("android/app/Activity");
  jmethodID MethodrequestPermissions = env->GetMethodID(ClassActivity, "requestPermissions", "([Ljava/lang/String;I)V");

    /* TODO: How to create a native callback for a Java class for last argument (0) */
    env->CallVoidMethod(mApp->activity->clazz, MethodrequestPermissions, ArrayPermissions, 0);

    mApp->activity->vm->DetachCurrentThread();
    });
  }
}

The requestPermissions API has a callback onRequestPermissionsResult notifying about the user's choice. How do I provide this callback in native code?

Thanks!



Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source