How may I add permission requests?

Hello everybody,

I hope you're all doing well while following your local safety guidelines. Many may have this issue as well, I'm not sure, but I was wondering if there's a way to add permissions once and that's it. For example...

interface PermissionInterface {
  public void permissionGranted(Runnable task);
}

public class LocalInterface implements PermissionInterface {
  public LocalInterface() {}
		
  @Override
  public void permissionGranted(Runnable task) {
    READ_EXTERNAL_STORAGE = true;
    new Thread(task).start();
  }
}

public void AskForReadPermission(final Runnable task, final String taskName) {
  form.askPermission("android.permission.READ_EXTERNAL_STORAGE", new  PermissionResultHandler() {
    @Override
      public void HandlePermissionResponse(String permission, boolean granted) {
        if (granted) {
          PermissionInterface permissionInterface = new LocalInterface();
          permissionInterface.permissionGranted(task);
        } else {
          form.dispatchPermissionDeniedEvent(me, taskName,  "android.permission.READ_EXTERNAL_STORAGE");
        }
    }
  });

  return;
}

From the block, I am using...

// Located inside of `CensoredClassName extends AndroidNonvisibleComponent` before `public CensoredClassName() {}`
... private ComponentContainer container;
... private CensoredClassName me = this;

// ---
@SimpleFunction()
public String CensoredMethodName(final String param1, final String param2) {
  if (!READ_EXTERNAL_STORAGE) {
    // Permission not granted
    final Runnable r = new Runnable() {
      @Override
      public void run() {
        me.CensoredMethodName(param1, param2);
      }
    };

    AskForReadPermission(r, "CensoredMethodName");
  } else {
    // READ_EXTERNAL_STORAGE is granted
    return "a result if permission granted";
  }

  // Nothing is being returned from above, permission denied
  return "";
}

It asks for the permission, but after granting the permission, I have to click on my demo button a second time to get the new result or reload my test app and click the button once if the permission is granted already. Is there any way to fix this? Or am I doing something wrong?

@ewpatton

Because blocks run on the main UI thread, you can't block while asking for permission because the UI needs to be responsive for the user to interact with the dialog. The only way to do this is to have a method/event pair where the event fires when the operation completes (e.g., File's ReadFrom block). Then in your handler that responds to the permission being granted you re-invoke the initial call, which calls the event when it is complete.

3 Likes

Try this..

That's not what I was looking for.

Anyway @ewpatton, this is my new code and it works...

interface PermissionListener {
  public void onPermissionGranted();
}

public void AskForReadPermission(final PermissionListener permissionListener) {
  if (!READ_EXTERNAL_STORAGE) {
    form.askPermission("android.permission.READ_EXTERNAL_STORAGE", new  PermissionResultHandler()  {	
      @Override
        public void HandlePermissionResponse(String permission, boolean granted) {
          if (granted) {
            READ_EXTERNAL_STORAGE = true;

            if (permissionListener != null) {
              permissionListener.onPermissionGranted();
            }
          } else {
            form.dispatchPermissionDeniedEvent(me, "$AskForReadPermission",  "android.permission.READ_EXTERNAL_STORAGE");
          }
        }
    });
  } else {
    if (permissionListener != null) {
      permissionListener.onPermissionGranted();
    }
  }

  return;
}

@SimpleEvent()
public void EventName(String param1, String param2, String param3, String param4) {
  EventDispatcher.dispatchEvent(this, "EventName", param1, param2, param3, param4);
}

// Example function using new method, any function that does not require
// a permission is used as a `return` statement by it's respective type
// @SimpleFunction()
// public returnType CensoredMethodName2() {
//  // Does not require permission, below you can see a method showing the difference
//   return true || "string" || 0;
// }
@SimpleFunction()
public void CensoredMethodName(final String param1, final String param2) {
  if (READ_EXTERNAL_STORAGE) {
    // Permission granted
    EventName("CensoredMethodName", param1, param2, String.valueOf(result));
  } else {
    // READ_EXTERNAL_STORAGE not granted
    AskForReadPermission(new PermissionListener() {
      @Override
      public void onPermissionGranted() {
        // Loop back around to check if READ_EXTERNAL_STORAGE was granted
        // and send a result to the event
        me.CensoredMethodName(param1, param2);
      }
    });
  }
}
1 Like