Asking for BlackBerry application permissions upfront – Tutorial

Posted by

Introduction

This tutorial will show you how to ask a user (of your BlackBerry app) for permissions that are required in order for your app to function properly. There are many APIs in the RIM API that will cause a prompt to be displayed in the BlackBerry UI that will require a user to provide explicit permission to access certain API functionality or access to certain hardware features or data on the device. Instead of interrupting the UI, it’s possible to ask the user for all of these permissions at the very beginning. By the way, if the user does not grant permissions when this popup appears, then an exception will be thrown which you have to deal with.

To learn more about the basics on permissions, read this how-to. This tutorial gives you a sneak peek into the use of this API, to explore these (and many other advanced features) in-depth we provide excellent BlackBerry Training Programs.

Asking for permissions upfront

The ApplicationPermissionsManager class can be used to hook into BlackBerry’s ability to grant all permissions upfront. You can ask for however many permissions you need granted at a time, and you can decide what to do if they get granted or not. The following code shows this in action; this code can be called at any time (even before you UIApplication has entered the EDT).

public class PermissionsApp extends UiApplication {
// main method
public static void main(String[] args) {

  _assertHasPermissions();

  PermissionsApp theApp = new PermissionsApp();
  UiApplication.getUiApplication().pushScreen(new MyScreen());
  theApp.enterEventDispatcher();

}

// ASK FOR PERMISSIONS
private static void _assertHasPermissions() {

// Capture the current state of permissions and check against the requirements.
ApplicationPermissionsManager apm = ApplicationPermissionsManager.getInstance();
ApplicationPermissions original = apm.getApplicationPermissions();

// Set up and attach a reason provider
apm.addReasonProvider(ApplicationDescriptor.currentApplicationDescriptor(), new ReasonProvider() {
  public String getMessage(int i) {
    String msg = "I need the permissions in order to work properly.";

    switch (i) {
      case ApplicationPermissions.PERMISSION_LOCATION_DATA:
        msg = "Needed for location based services.";
        break;
      case ApplicationPermissions.PERMISSION_ORGANIZER_DATA:
        msg = "Needed for accessing your contacts.";
        break;
      case ApplicationPermissions.PERMISSION_EMAIL:
        msg = "Needed for sending email.";
        break;
      case ApplicationPermissions.PERMISSION_FILE_API:
        msg = "Needed for accessing pictures on your device.";
        break;
      case ApplicationPermissions.PERMISSION_INTERNET:
        msg = "Needed to connect to the cellular data network.";
        break;
      case ApplicationPermissions.PERMISSION_RECORDING:
        msg = "Needed to access the camera.";
        break;
      case ApplicationPermissions.PERMISSION_WIFI:
        msg = "Needed to access WiFi.";
        break;
    }

    return msg;
  }
});

boolean permissionsOk = false;

if (
    original.getPermission(ApplicationPermissions.PERMISSION_LOCATION_DATA) ==
    ApplicationPermissions.VALUE_ALLOW
    &&
    original.getPermission(ApplicationPermissions.PERMISSION_ORGANIZER_DATA) ==
    ApplicationPermissions.VALUE_ALLOW
    &&
    original.getPermission(ApplicationPermissions.PERMISSION_EMAIL) ==
    ApplicationPermissions.VALUE_ALLOW
    &&
    original.getPermission(ApplicationPermissions.PERMISSION_FILE_API) ==
    ApplicationPermissions.VALUE_ALLOW
    &&
    original.getPermission(ApplicationPermissions.PERMISSION_INTERNET) ==
    ApplicationPermissions.VALUE_ALLOW
    &&
    original.getPermission(ApplicationPermissions.PERMISSION_RECORDING) ==
    ApplicationPermissions.VALUE_ALLOW
    &&
    original.getPermission(ApplicationPermissions.PERMISSION_WIFI) ==
    ApplicationPermissions.VALUE_ALLOW
    )
{
  permissionsOk = true;
}
else {
  // Create a permission request for each of the permissions your application
  // needs. Note that you do not want to list all of the possible permission
  // values since that provides little value for the application or the user.
  // Please only request the permissions needed for your application.
  ApplicationPermissions permRequest = new ApplicationPermissions();
  permRequest.addPermission(ApplicationPermissions.PERMISSION_LOCATION_DATA);
  permRequest.addPermission(ApplicationPermissions.PERMISSION_ORGANIZER_DATA);
  permRequest.addPermission(ApplicationPermissions.PERMISSION_EMAIL);
  permRequest.addPermission(ApplicationPermissions.PERMISSION_FILE_API);
  permRequest.addPermission(ApplicationPermissions.PERMISSION_INTERNET);
  permRequest.addPermission(ApplicationPermissions.PERMISSION_RECORDING);
  permRequest.addPermission(ApplicationPermissions.PERMISSION_WIFI);

  permissionsOk = apm.invokePermissionsRequest(permRequest);

}

if (permissionsOk) {

  // do nothing

}
else {

  // exit
  System.exit(0);

}

}

}

// SCREEN ... 

public class MyScreen extends MainScreen {

  // CONSTRUCTOR
  public MyScreen(){

    // create a label
    LabelField body1 = new LabelField("Body1...",
                                      LabelField.ELLIPSIS | LabelField.USE_ALL_WIDTH);

    VerticalFieldManager vfm = new VerticalFieldManager(Field.FIELD_VCENTER);
    vfm.add(body1);
    add(vfm);

  }

}

This is what’s happening in the code above:

  1. In the main() method of your app, you can ask for permissions to be granted right away before anything begins. In this example, permissions aren’t granted, then the app will not run (System.exit(0)) is called. If permissions are granted, then the MyScreen is created and shown.
  2. The first part of the _assertHasPermissions() method deals with seeing what permissions are currently granted to the app by default. If these permissions in original object match the app’s requirements, then there’s no need to ask for permissions.
  3. Then a reason provider implementation is provided that shows the user custom messages, if they try and find out what these permissions are required by the app for. This will not be displayed in the global screen that asks for permissions. However, if the IT policy on the BlackBerry prevents this screen from being displayed, and individual permissions are required to be authorized by the user, then these messages come in handy, when a prompt appears before an API call is made that requires a permission.
  4. If the original permissions don’t match the required permissions then the invokePermissionsRequest() is called with the requested permissions. This will cause a global screen to be displayed. Finally, if all the permissions are granted then true is returned, otherwise false is returned. This is an all or nothing implementation. If you’re requirements are different, then you should tweak this code before using it.
  5. In this code example, almost all available permissions are requirement. If your app doesn’t require all of them then you shouldn’t ask for them, and create reason providers for them.

Learning more

If you need coaching on how to use these features in-depth, and other advanced features of the BlackBerry API, then contact us for our BlackBerry Training Programs.

Feedback and comments

To leave your thoughts and comments on this tutorial, click here.