Application Permission Management

Why permissions are required ?

Users must grant permission for an app to access sensitive information, including the current location, calendar, contact information, reminders and photos. Although people appreciate the convenience of using an app that has access to this information, they also expect to have control over their privacy.

Implementation Requirement

Permission management requires OS-specific development since permission structures are totally separate in iOS and Android.

IOS

Smartface iOS Framework handles permissions automatically for the user. Developer does not need to handle permission management.

JavaScript
JavaScript
const Location = require('sf-core/device/location');
Location.start();
Location.onLocationChanged = function(event) {
console.log("Location latitude: " + event.latitude + " Longitude: " + event.longitude);
};

In addition, there are also some convenient functions that check the status of related permission. Location permission status example like below;

JavaScript
JavaScript
const Location = require('sf-core/device/location');
switch(Location.ios.getAuthorizationStatus()) {
case Location.ios.authorizationStatus.Authorized:
/*code block*/
break;
case Location.ios.authorizationStatus.Denied:
/*code block*/
break;
case Location.ios.authorizationStatus.NotDetermined:
/*code block*/
break;
default:
/*code block*/
}

Android

In the JavaScript side, there are some methods which are necessary for managing permissions.

JavaScript
JavaScript
const Application = require("sf-core/application");
const CAMERA_PERMISSION_CODE = 1002;
const CAMERA_PERMISSION = Application.Android.Permissions.CAMERA;
getPermission(CAMERA_PERMISSION, CAMERA_PERMISSION_CODE);
function getPermission(permission, code) {
let prevPermissionRationale = Application.android.shouldShowRequestPermissionRationale(permission);
Application.android.onRequestPermissionsResult = function(e) {
if (e.requestCode != code)
return;
let currentPermissionRationale = Application.android.shouldShowRequestPermissionRationale(permission);
if (e.result) {
console.log("GRANTED");
}
else if (!currentPermissionRationale) {
if (prevPermissionRationale) {
console.info("NEVER ASK AGAIN");
}
else {
console.info("COULD NOT ASK");
}
}
else {
console.log("DENIED");
}
};
if (Application.android.checkPermission(permission)) {
console.log("ALREADY GRANTED");
}
else {
Application.android.requestPermissions(code, permission);
}
}

PermissionUtil Extension

Used for permission operations. It works for android and ios. To install the extension into your workspace, visit sf-extension-utils page.

PermissionUtil.getPermission returns true always on IOS devices.

Permission Request Result

PermissionUtil.getPermission takes two arguments. First argument is a permission, second argument is a callback when triggers on permission result. To handle permission request result, pass the second parameter as a function.

JavaScript
JavaScript
const PermissionUtil = require("sf-extension-utils").permission;
const Contacts = require("sf-core/device/contacts");
const Application = require("sf-core/application");
PermissionUtil.getPermission(Application.android.Permissions.READ_CONTACTS,
function(result) {
alert("READ_CONTACTS permission result: " + result);
});
module.exports = pagePermission;

Permission Prompts

The permission prompt dialogs cannot be customized or localized. They are fully managed by the operating system for security purposes.

Publishing Binaries from Cloud IDE

For required permission operations, you must add permissions to config/AndroidManifest.xml on Cloud IDE.

Which permission you should use with Smartface Native Framework?

Some features requires specific permission both iOS and Android. For example, when you want to access user's location, you need Location permission. In this section, you can find which Smartface Native Framework feature requires which permission.

Feature

Android Manifest

iOS Info.plist

Android Run-time

Application.byteReceived

READ_PHONE_STATE

READ_PHONE_STATE

Application.byteSent

READ_PHONE_STATE

READ_PHONE_STATE

Application.checkUpdate

WRITE_EXTERNAL_STORAGE

WRITE_EXTERNAL_STORAGE

Device.Contacts.add

WRITE_CONTACTS

NSContactsUsageDescription ${PRODUCT_NAME} Contact fetch

WRITE_CONTACTS

Device.Contacts.getAll

READ_CONTACTS

NSContactsUsageDescription ${PRODUCT_NAME} Contact fetch

READ_CONTACTS

Device.Hardware.IMEI

READ_PHONE_STATE

READ_PHONE_STATE

Device.Hardware.UID

READ_PHONE_STATE

READ_PHONE_STATE

Device.Location.start() 1

ACCESS_COARSE_LOCATION || ACCESS_FINE_LOCATION

NSLocationWhenInUseUsageDescription ${PRODUCT_NAME} WhenInUse Location

ACCESS_COARSE_LOCATION || ACCESS_FINE_LOCATION

Device.Multimedia.getAllGalleryItems()

READ_EXTERNAL_STORAGE

NSPhotoLibraryUsageDescription ${PRODUCT_NAME} PhotoLibrary Usage NSCameraUsageDescription ${PRODUCT_NAME} Camera Usage

READ_EXTERNAL_STORAGE

Device.System.fingerPrintAvailable

USE_FINGERPRINT

-

IO.File 2

READ_EXTERNAL_STORAGE

READ_EXTERNAL_STORAGE

Net.Http 3

ACCESS_NETWORK_STATE

NSAppTransportSecurity NSAllowsArbitraryLoads

-

SpeechRecognizer.start

RECORD_AUDIO

NSSpeechRecognitionUsageDescription ${PRODUCT_NAME} Speech Recognition Usage NSMicrophoneUsageDescription ${PRODUCT_NAME} Microphone Usage

RECORD_AUDIO

Device.Multimedia.startCamera

CAMERA

NSCameraUsageDescription $(PRODUCT_NAME) shoots contact picture

CAMERA

sf-extension-smsreceiver

RECEIVE_SMS READ_SMS

RECEIVE_SMS READ_SMS

Application.call

CALL_PHONE

CALL_PHONE

Device.System.Vibrate

VIBRATE

VIBRATE

UI.MapView

MAPS_RECEIVE

MAPS_RECEIVE

1 For Android, based on Provider; you can use ACCESS_COARSE_LOCATION for Location.Android.Provider.NETWORK, ACCESS_FINE_LOCATION for Location.Android.Provider.GPS and Location.Android.Provider.AUTO 2 For Android, all methods and properties under IO.File requires READ_EXTERNAL_STORAGE permission if the file is not under Path.DataDirectory. 3 For Android, all methods under Net.Http requires ACCESS_NETWORK_STATE permission.