Skip to main content
Version: 7.2.1

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.

TypeScript
import Location from "@smartface/native/device/location";

Location.start("HIGH_ACCURACY", 1000);
Location.onLocationChanged = (event: {
latitude: number;
longitude: number;
}): void => {
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;

TypeScript
import Location from "@smartface/native/device/location";

//@ts-ignore
switch (Location.ios.getAuthorizationStatus()) {
//@ts-ignore
case Location.ios.authorizationStatus.Authorized:
/*code block*/
break;
//@ts-ignore
case Location.ios.authorizationStatus.Denied:
/*code block*/
break;
//@ts-ignore
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.

TypeScript
import Permission from "@smartface/native/device/permission";

const CAMERA_PERMISSION_CODE: number = 1002;
const CAMERA_PERMISSION = Permissions.camera;

function getPermission(permission: string, code: number): void {
let prevPermissionRationale =
Permission.android.shouldShowRequestPermissionRationale(permission);
Permission.android.onRequestPermissionsResult = function (e) {
if (e.requestCode != code) return;

let currentPermissionRationale =
Permission.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 (Permission.android.checkPermission(permission)) {
console.log("ALREADY GRANTED");
} else {
Permission.android.requestPermissions(code, permission);
}
}
TypeScript
import Permission from "@smartface/native/device/permission";
import { Permissions } from "@smartface/native/device/permission/permission";

Permission.android.requestPermissions(Permissions.android.phone).then((e) => {
// your code
});

module.exports = pagePermission;

Sample examples of permissions

import PgCallDetectionDesign from "generated/pages/pgCallDetection";
import { withDismissAndBackButton } from "@smartface/mixins";
import { Router, Route } from "@smartface/router";
import Application from "@smartface/native/application";
import CallDetection from "@smartface/native/device/calldetection";
import Permission from "@smartface/native/device/permission";
import {
PermissionResult,
Permissions,
} from "@smartface/native/device/permission/permission";

export default class PgCallDetection extends withDismissAndBackButton(
PgCallDetectionDesign
) {
constructor(private router?: Router, private route?: Route) {
super({});
}

async initCallStateListener() {
const results = await Permission.android.requestPermissions(
Permissions.camera
);
if (results[0] === PermissionResult.GRANTED) {
CallDetection.on("callStateChanged", (a) => console.info(a));
}
}

onShow() {
super.onShow();
this.initBackButton(this.router); //Addes a back button to the page headerbar.
this.initCallStateListener();
}

onLoad() {
super.onLoad();
}
}
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 Smartface IDE

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

Common

We have common permissions for both iOS and Android. You can find the common permission list below.

Common Permissions
microphone
storage
camera
location

Example for microphone permission:

import Permission from "@smartface/native/device/permission";
import { Permissions } from "@smartface/native/device/permission/permission";

Permission.requestPermission(Permissions.microphone)
.then((res) => alert("Permission Success: " + res))
.catch((err) => {
alert({
title: "Microphone Permission",
message: "Microphone permission is required to use this app",
});
console.error("Permission failed " + JSON.stringify(err));
});

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.

FeatureAndroid ManifestiOS Info.plistAndroid Run-time
Application.byteReceivedREAD_PHONE_STATEandroid.phone
Application.byteSentREAD_PHONE_STATEandroid.phone
Contacts.addWRITE_CONTACTS

NSContactsUsageDescription
${PRODUCT_NAME} Contact fetch

android.contact
Contacts.getAllREAD_CONTACTS

NSContactsUsageDescription
${PRODUCT_NAME} Contact fetch

android.contact
Location.start() *ACCESS_COARSE_LOCATION || ACCESS_FINE_LOCATION

NSLocationWhenInUseUsageDescription
${PRODUCT_NAME} WhenInUse Location

location.approximate || location.precise
Multimedia.pickMultipleFromGallery()

READ_EXTERNAL_STORAGE for API Level 32 and below

No permission required for API Level 33 and above.

NSPhotoLibraryUsageDescription
${PRODUCT_NAME} PhotoLibrary Usage

NSCameraUsageDescription
${PRODUCT_NAME} Camera Usage

storage on API Level 32 and below

No permission required on API Level 33 and above.

System.fingerPrintAvailableUSE_FINGERPRINT-
IO.File **

READ_EXTERNAL_STORAGE for API Level 32 and below

READ_MEDIA_IMAGES, READ_MEDIA_VIDEO, READ_MEDIA_AUDIO for API Level 33 and above.

storage
Net.Http ***ACCESS_NETWORK_STATE

NSAppTransportSecurity
NSAllowsArbitraryLoads

-
SpeechRecognizer.startRECORD_AUDIO

NSSpeechRecognitionUsageDescription
${PRODUCT_NAME} Speech Recognition Usage

NSMicrophoneUsageDescription
${PRODUCT_NAME} Microphone Usage

android.microphone
Device.Multimedia.startCameraCAMERA

NSCameraUsageDescription
$(PRODUCT_NAME) shoots contact picture

camera
sf-extension-smsreceiver

RECEIVE_SMS
READ_SMS

android.sms
Application.callCALL_PHONEandroid.phone
Device.System.VibrateVIBRATEVIBRATE
UI.MapViewMAPS_RECEIVEMAPS_RECEIVE

* 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

** For Android, all methods and properties under IO.File requires some permissions if the file is not under Path.DataDirectory. Android 12L (API Level 32) and below requires READ_EXTERNAL_STORAGE, Android 13 (API Level 33) and above requires granular media permissions (READ_MEDIA_IMAGES, READ_MEDIA_VIDEO, READ_MEDIA_AUDIO)

*** For Android, all methods under Net.Http requires ACCESS_NETWORK_STATE permission.

info

It is sufficient to add only one to AndroidManifest in group permissions. For example, if you add READ_SMS permission, you do not need to add RECEIVE_SMS permissions.