Giter VIP home page Giter VIP logo

nativescript-permissions's Introduction

nativescript-permissions's People

Contributors

17number avatar hdeshev avatar hypery2k avatar nathanaela avatar pbartrina avatar zweimal avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar

nativescript-permissions's Issues

java.lang.NullPointerException: Attempt to invoke virtual method 'int error

I'm getting this error from ".catch(function(result)" result:

Error: java.lang.NullPointerException: Attempt to invoke virtual method 'int android.content.Context.checkPermission(java.lang.String, int, int)' on a null object reference
android.support.v4.content.ContextCompat.checkSelfPermission(ContextCompat.java:387)
com.tns.Runtime.callJSMethodNative(Native Method)
com.tns.Runtime.dispatchCallJSMethodNative(Runtime.java:861)
com.tns.Runtime.callJSMethodImpl(Runtime.java:726)
com.tns.Runtime.callJSMethod(Runtime.java:712)
com.tns.Runtime.callJSMethod(Runtime.java:693)
com.tns.Runtime.callJSMethod(Runtime.java:683)
com.tns.NativeScriptActivity.onCreate(NativeScriptActivity.java:13)
android.app.Activity.performCreate(Activity.java:6237)
android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1107)
android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2369)
android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2476)
android.app.ActivityThread.-wrap11(ActivityThread.java)
android.app.ActivityThread$H.handleMessage(ActivityThread.java:1344)
android.os.Handler.dispatchMessage(Handler.java:102)
android.os.Looper.loop(Looper.java:148)
android.app.ActivityThread.main(ActivityThread.java:5417)
java.lang.reflect.Method.invoke(Native Method)
com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)

And then comes my permission denied catch console comment.
Same happens on Android N and Android M emulators.
There's no other plugin running at the current view, where I ask these permissions.

Behavior on IOS

I have installed the plugin using the command:
$ tns plugin add @master.technology/permissions
And used it as follow:

permissions
      .requestPermission(
        permissions.PERMISSIONS.CAMERA,
        "why not the permission"
      )
      .then(() => {
        console.log("Woo Hoo, I have the power!");
      })
      .catch(() => {
        console.log("Uh oh, no permissions - plan B time!");
      });

To the info.plist I have added the following key:

<key>NSCameraUsageDescription</key>
<string>Required for make images of documents that need to be uploaded</string>

When the code is executed, both functions are not executed, I only get the following block logged to the console:

CONSOLE LOG: Getting ios.CAMERA
(UIKitCore) [com.apple.UIKit:PointerLockState] preferredPointerLockStatus updated: scene: <UIWindowScene: 0x7f853f02bd50; sceneIdentifier: "sceneID:org.nativescript.VOISMGOV-default">; viewController: <UIViewControllerImpl: 0x7f853f573ff0>; preferredPointerLockStatus: _UIPointerLockStatusUnlocked

I am using:

"typescript": "~4.3.5"
"@nativescript/angular": "^12.2.0",
tns: 8.1.5

Exported external package typings file index.d.ts is not a module

I am getting this error when building:

"error TS2656: Exported external package typings file '/........../........../node_modules/nativescript-permissions/index.d.ts' is not a module. Please contact the package author to update the package definition."

Any suggestions on how to resolve this? I commented out the module declaration and was able to move past the problem but is there a better way?

[iOS] Permissions Merge

I've been working on a port of https://github.com/dpa99c/cordova-diagnostic-plugin to nativescript.

Here's the iOS implementation:

// 

import * as platform from 'platform'
import {openUrl} from 'utils/utils'
import {find, isString, isFinite} from 'lodash'
declare var ABAddressBookGetAuthorizationStatus: any
declare var ABAuthorizationStatus: any
declare var ABAddressBookRequestAccessWithCompletion: any
declare var ABAddressBookCreateWithOptions: any
declare var UIApplicationOpenSettingsURLString: any
declare var CLLocationManager: any
declare var CLAuthorizationStatus: any
declare var NSObject: any
declare var CLLocationManagerDelegate: any
declare var locationManagerDidUpdateToLocationFromLocation: any
declare var UIImagePickerController: any
declare var UIImagePickerControllerSourceType: any
declare var UIImagePickerControllerCameraDevice: any
declare var PHAuthorizationStatus: any
declare var AVAuthorizationStatus: any
declare var AVCaptureDevice: any
declare var AVMediaTypeVideo: any
declare var PHPhotoLibrary: any
declare var UIApplication: any
declare var UIUserNotificationSettings: any
declare var UIUserNotificationType: any
declare var UIBackgroundRefreshStatus: any
declare var AVAudioSession: any
declare var AVAudioSessionRecordPermission: any
declare var EKAuthorizationStatus: any
declare var EKEventStore: any
declare var EKEntityTypeEvent: any



class LocationListener extends NSObject implements CLLocationManagerDelegate {

    public static ObjCProtocols = [CLLocationManagerDelegate]
    private _resolves: any // something weird is going on here that i cant initialize this with an empty array []
    private _didSetup: boolean

    private locationManagerDidChangeAuthorizationStatus(manager: any, status: number): void {
        if (!this._didSetup) { // returns status immedietely after new LocationListener()
            this._didSetup = true
            return
        }
        let i, len = this._resolves.length
        for (i = 0; i < len; i++) {
            this._resolves[i](status)
        }
    }

    public setupPromise(resolve: () => void): void {
        if (this._resolves == undefined) {
            this._resolves = []
        }
        this._resolves.push(resolve)
    }

}

class Permissions2 {

    public status: any = {}
    private addressBook: any = ABAddressBookCreateWithOptions(null, null)
    private osVersion: number = parseFloat(platform.device.osVersion) // parses the first decimal place
    private _eventStore: any = null
    private _locationListener: any = null
    private _locationManager: any = null

    constructor() {

        this.mapStatus('BackgroundRefresh', UIBackgroundRefreshStatus)
        this.mapStatus('Contacts', ABAuthorizationStatus)
        this.mapStatus('Camera', AVAuthorizationStatus)
        this.mapStatus('Pictures', PHAuthorizationStatus)
        this.mapStatus('Location', CLAuthorizationStatus)
        this.mapStatus('Microphone', AVAudioSessionRecordPermission)
        this.mapStatus('Calendar', EKAuthorizationStatus)
        // global.tnsconsole.dump('this.status', this.status)

    }

    /*===============================
    =            HELPERS            =
    ===============================*/

    private mapStatus(key: string, obj: any): any {
        this.status[key] = {}
        let statuses = ['NotDetermined', 'Restricted', 'Denied', 'Authorized', 'Available', 'AuthorizedAlways', 'AuthorizedWhenInUse', 'Undetermined', 'Granted']
        let i, len = statuses.length
        for (i = 0; i < len; i++) {
            let index = find(obj, function(vv, ii) {
                if (isString(ii) && ii.indexOf(statuses[i]) != -1) {
                    return true
                }
            })
            if (isFinite(index)) {
                this.status[key][statuses[i]] = obj[obj[index]]
                this.status[key][obj[obj[index]]] = statuses[i]
            }
        }
    }

    /*=================================
    =            UTILITIES            =
    =================================*/

    public switchToSettings(): void {
        openUrl(UIApplicationOpenSettingsURLString)
    }

    /*================================
    =            LOCATION            =
    ================================*/

    public isLocationEnabled(): boolean {
        return CLLocationManager.locationServicesEnabled()
    }

    public getLocationAuthorizationStatus(): number {
        return CLLocationManager.authorizationStatus()
    }

    public isLocationAuthorized(): boolean {
        let status: number = this.getLocationAuthorizationStatus()
        return (
            status == this.status['Location']['AuthorizedAlways']
            ||
            status == this.status['Location']['AuthorizedWhenInUse']
        )
    }

    public isLocationAvailable(): boolean {
        return this.isLocationEnabled() && this.isLocationAuthorized()
    }

    public requestLocationAuthorization(type: string = 'WhenInUse'): Promise<any> {
        let status: number = this.getLocationAuthorizationStatus()
        if (status != this.status['Location']['NotDetermined']) {
            return Promise.resolve(status)
        }

        if (this._locationListener == null) {
            this._locationListener = new LocationListener()
        }
        if (this._locationManager == null) {
            this._locationManager = new CLLocationManager()
            this._locationManager.delegate = this._locationListener
        }

        if (type == 'WhenInUse') {
            this._locationManager.requestWhenInUseAuthorization()
        } else {
            this._locationManager.requestAlwaysAuthorization()
        }

        return new Promise((resolve, reject) => {
            this._locationListener.setupPromise(resolve)
        })
    }

    /*==============================
    =            CAMERA            =
    ==============================*/

    public isCameraPresent(): boolean {
        return UIImagePickerController.isSourceTypeAvailable(UIImagePickerControllerSourceType['UIImagePickerControllerSourceTypeCamera'])
    }

    public isFrontCameraPresent(): boolean {
        return UIImagePickerController.isCameraDeviceAvailable(UIImagePickerControllerCameraDevice['UIImagePickerControllerCameraDeviceFront'])
    }

    public isRearCameraPresent(): boolean {
        return UIImagePickerController.isCameraDeviceAvailable(UIImagePickerControllerCameraDevice['UIImagePickerControllerCameraDeviceRear'])
    }

    public getCameraAuthorizationStatus(): number {
        return AVCaptureDevice.authorizationStatusForMediaType(AVMediaTypeVideo)
    }

    public isCameraAuthorized(): boolean {
        return this.getCameraAuthorizationStatus() == this.status['Camera']['Authorized']
    }

    public isCameraAvailable(): boolean {
        return this.isCameraPresent() && this.isCameraAuthorized()
    }

    public requestCameraAuthorization(): Promise<any> {
        return new Promise(function(resolve) {
            AVCaptureDevice.requestAccessForMediaTypeCompletionHandler(AVMediaTypeVideo, resolve)
        })
    }

    /*================================
    =            PICTURES            =
    ================================*/

    public getPicturesAuthorizationStatus(): number {
        return PHPhotoLibrary.authorizationStatus()
    }

    public isPicturesAuthorized(): boolean {
        return this.getPicturesAuthorizationStatus() == this.status['Pictures']['Authorized']
    }

    public requestPicturesAuthorization(): Promise<any> {
        return new Promise((resolve) => {
            PHPhotoLibrary.requestAuthorization((status) => {
                return resolve(status == this.status['Pictures']['Authorized'])
            })
        })
    }

    /*=====================================
    =            NOTIFICATIONS            =
    =====================================*/

    public isRemoteNotificationsEnabled(): boolean {
        let sharedApp = UIApplication.sharedApplication()
        // if (sharedApp.respondsToSelector('registerUserNotificationSettings:')) {
        if (this.osVersion >= 8) {
            // iOS8+
            let enabled: boolean = sharedApp.isRegisteredForRemoteNotifications()
            let types: number = sharedApp.currentUserNotificationSettings().types
            return enabled && types != UIUserNotificationType['UIUserNotificationTypeNone']
        } else {
            // iOS7 and below
            let types: number = sharedApp.enabledRemoteNotificationTypes
            return types != UIUserNotificationType['UIUserNotificationTypeNone']
        }
    }

    public isRegisteredForRemoteNotifications(): boolean {
        let sharedApp = UIApplication.sharedApplication()
        if (this.osVersion >= 8) {
            // iOS8+
            return sharedApp.isRegisteredForRemoteNotifications()
        } else {
            // iOS7 and below
            return sharedApp.enabledRemoteNotificationTypes != UIUserNotificationType['UIUserNotificationTypeNone']
        }
    }

    /*=====  THIS NEEDS TESTING  ======*/
    public getRemoteNotificationTypes(): any {
        let enables: any = []
        let sharedApp = UIApplication.sharedApplication()
        if (this.osVersion >= 8) {
            // iOS8+
            let types: number = sharedApp.currentUserNotificationSettings().types
            if (types == UIUserNotificationType['UIUserNotificationTypeNone']) {
                enables.push('none')
            }
            if (types & UIUserNotificationType['UIUserNotificationTypeAlert']) { // bitwise &
                enables.push('alert')
            }
            if (types & UIUserNotificationType['UIUserNotificationTypeBadge']) {
                enables.push('badge')
            }
            if (types & UIUserNotificationType['UIUserNotificationTypeSound']) {
                enables.push('sound')
            }
        } else {
            // iOS7 and below
            let types: number = sharedApp.enabledRemoteNotificationTypes
            if (types == UIUserNotificationType['UIUserNotificationTypeNone']) {
                enables.push('none')
            }
            if (types & UIUserNotificationType['UIUserNotificationTypeAlert']) {
                enables.push('alert')
            }
            if (types & UIUserNotificationType['UIUserNotificationTypeBadge']) {
                enables.push('badge')
            }
            if (types & UIUserNotificationType['UIUserNotificationTypeSound']) {
                enables.push('sound')
            }
        }
        return enables
    }

    /*==========================================
    =            BACKGROUND REFRESH            =
    ==========================================*/

    public getBackgroundRefreshStatus(): number {
        let sharedApp = UIApplication.sharedApplication()
        return sharedApp.backgroundRefreshStatus
    }

    public isBackgroundRefreshAuthorized(): boolean {
        return this.getBackgroundRefreshStatus() == UIBackgroundRefreshStatus['UIBackgroundRefreshStatusAvailable']
    }

    /*================================
    =            CONTACTS            =
    ================================*/

    public getContactsAuthorizationStatus(): number {
        return ABAddressBookGetAuthorizationStatus()
    }

    public isContactsAuthorized(): boolean {
        return this.getContactsAuthorizationStatus() == this.status['Contacts']['Authorized']
    }

    public requestContactsAuthorization(): Promise<any> {
        return new Promise((resolve, reject) => {
            ABAddressBookRequestAccessWithCompletion(this.addressBook, function(status, error) {
                if (error) {
                    return reject(new Error(error))
                } else {
                    return resolve(status)
                }
            })
        })
    }

    /*==================================
    =            MICROPHONE            =
    ==================================*/

    public getMicrophoneAuthorizationStatus(): number {
        let session = AVAudioSession.sharedInstance()
        return session.recordPermission()
    }

    public isMicrophoneAuthorized(): boolean {
        return this.getMicrophoneAuthorizationStatus() == this.status['Microphone']['Granted']
    }

    public requestMicrophoneAuthorization(): Promise<any> {
        let session = AVAudioSession.sharedInstance()
        return new Promise(function(resolve) {
            session.requestRecordPermission(function(status) {
                return resolve(status)
            })
        })
    }

    /*================================
    =            CALENDAR            =
    ================================*/

    public getCalendarAuthorizationStatus(): number {
        return EKEventStore.authorizationStatusForEntityType(EKEntityTypeEvent)
    }

    public isCalendarAuthorized(): boolean {
        return this.getCalendarAuthorizationStatus() == this.status['Calendar']['Authorized']
    }

    public requestCalendarAuthorization(): Promise<any> {
        if (this._eventStore == null) {
            this._eventStore = new EKEventStore()
        }
        return new Promise((resolve, reject) => {
            this._eventStore.requestAccessToEntityTypeCompletion(EKEntityTypeEvent, function(status, error) {
                if (error) {
                    return reject(new Error(error))
                } else {
                    return resolve(status)
                }
            })
        })
    }

}

export default new Permissions2()

I don't know how to get in touch with you or how you'd like this to be implemented with your code.

Can't resolve '@master.technology/permissions' in version 1.3.12

After cleaning and rebuilding my mobile app I'm getting the following error:

ERROR in ../node_modules/nativescript-permissions/permissions.js
Module not found: Error: Can't resolve '@master.technology/permissions' in '/mobile-app/booking/node_modules/nativescript-permissions'
 @ ../node_modules/nativescript-permissions/permissions.js 13:17-58
 @ ../node_modules/@nativescript/geolocation/index.js
 @ ./modules/club/components/search/search.component.ts
 @ ./modules/scores/pages/form/form.component.ts
 @ ./modules/scores/pages/index.ts
 @ ./modules/scores/scores.module.ts
 @ ./routing/app.routing.ts
 @ ./app.module.ts
 @ ./main.ts
Executing webpack failed with exit code 2.

Let me know if there are any other details I can provide to help resolve this, thanks!

Unable to request 'android.permission.BIND_DEVICE_ADMIN'

I have android.permission.BIND_DEVICE_ADMIN within my AndroidManifest.xml as per my other permissions but currently I'm unable to request permission for it. There's no "toast" notification to accept/deny as with the other permissions.

The request permissions code is as follows

requestPermission(android.Manifest.permission.BIND_DEVICE_ADMIN, 'needed for kiosk mode').then(function () {
				console.log("permission for BIND_DEVICE_ADMIN");
			})
			.catch(function () {
				console.log("no perms for BIND_DEVICE_ADMIN");
			});

requestPermission fails for android.permission.BIND_ACCESSIBILITY_SERVICE

I'm trying to get a permission for android.permission.BIND_ACCESSIBILITY_SERVICE but it always returns {"android.permission.BIND_ACCESSIBILITY_SERVICE":false}.

var permissions = require('nativescript-permissions');
readAccessibility()
.catch(function(error) {
   console.log(JSON.stringify(error)); // {"android.permission.BIND_ACCESSIBILITY_SERVICE":false}
});
function readAccessibility() {
    permissions.requestPermission(
        android.Manifest.permission.BIND_ACCESSIBILITY_SERVICE,
        'Need permission to read USSD'
    );
}

Additionally, I've <uses-permission android:name="android.permission.BIND_ACCESSIBILITY_SERVICE" /> under AndroidManifest.xml

Any idea why it does not work?

Permissions problem on android

Hi
I think I have a problem with the plugin. The issue is exactly like #5 .
I am using android 6.0.1 and latest version of your awesome plugin. It used to work perfectly but then i started getting the java permissions error in my main (Attempt to invoke virtual method 'int android.content.Context.checkPermission(java.lang.String, int, int)')

I created brand new test app via "tns create --ng"

My code:

`import {nativeScriptBootstrap} from "nativescript-angular/application";
import {AppComponent} from "./app.component";

var permissions = require("nativescript-permissions");
declare var android;

permissions.requestPermission(android.Manifest.permission.ACCESS_FINE_LOCATION, "I need these permissions because I'm cool")
.then(function () {

nativeScriptBootstrap(AppComponent);
})
.catch(function (err) {
console.log(err);
});
`

Manifest has the permissions...

demo\platforms\android\src\main\AndroidManifest.xml
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/> <uses-permission android:name="android.permission.INTERNET"/>

Thanks for your help

Compile Time Error for 1.3.12

Hey Nathanael,

Our CI patched this plugin and failed during build. Rolling back to 1.3.11 fixed the issue.

Error code:

ERROR in ../node_modules/@master.technology/permissions/permissions.js 67:46
Module parse failed: Unexpected token (67:46)
You may need an appropriate loader to handle this file type, currently no loaders are configured to process this file. See https://webpack.js.org/concepts#loaders
|                     // We will get a Status=0 before we get the first real status...
|                     if (status === 0) { return; }
>                     const owner = this._owner?.get();
|                     if (owner) {
|                         if (LOCATION.has()) {
 @ ../node_modules/nativescript-permissions/permissions.js 13:17-58

Thanks

Issue with android.Manifest.permission.READ_CONTACTS since 2.2.0 NativeScript upgrade

Hey Nathanael,

I've been getting great use of your plugin, thanks for your hard work on it. Unfortunately since upgrading to 2.2.0 I am now getting an issue with android.Manifest.permission.READ_CONTACTS

The code below results in this error message: {"android.permission.READ_CONTACTS":false}

let perm = permissions.requestPermission(android.Manifest.permission.READ_CONTACTS,
                'Please click allow to fetch contacts from your phone');
            perm.then(() => {
                this.getAllContacts();
            }, (err) => {
                console.log("Error: " + JSON.stringify(err));
            })

Let me know if you need any other details, hope this wasn't a silly mistake on my part.

WRITE_SETTINGS permission

Hey there,

I'm trying to set some sytem settings in my app, and therefore i was hoping to use this plugin to handle the permissions. Unfortunately, when I'm trying to request the permission it simply fails.
I found a solution by manually asking with this code:

if (android.provider.Settings.System.canWrite(application.android.context)) {
  // permission granted
} else {
  const intent = new android.content.Intent(android.provider.Settings.ACTION_MANAGE_WRITE_SETTINGS);
  intent.setData(android.net.Uri.parse("package:" + application.android.foregroundActivity.getPackageName()));
  intent.addFlags(android.content.Intent.FLAG_ACTIVITY_NEW_TASK);
  application.android.foregroundActivity.startActivity(intent);
}

Maybe something like this could be added to this plugin?

Android Permissions are firing weirdly

I have written a plugin that basically acts as a thin wrap around your plugin and adds IOS Permission requesting... (while attempting to keep a consistent API between the two, so some 'vanity' methods have been added)

you can see it here: https://www.npmjs.com/package/@spartadigital/nativescript-permissions

we've noticed some strange behaviour from the promises, it seems that they are being fired twice, once when the dialog is opened and once when the permission is granted/rejected, and i believe that the issue is with your plugin

Here is the implementation script

let hasLocationPermissionsI = false;
let hasCameraPermissionsI = false;

let amountOfTimesFired = 0;

console.log('Requesting Location Permissions');
Permissions.requestLocationPermission().then((isLocationEnabled) => {
  hasLocationPermissionsI = isLocationEnabled;

  console.log('Requesting Camera Permissions');
  return Permissions.requestCameraPermission();
}).then((isCameraEnabled: boolean) => {
  hasCameraPermissionsI = isCameraEnabled;

  return Promise.resolve([hasLocationPermissionsI, hasCameraPermissionsI])
}).then(([hasLocationPermissions, hasCameraPermissions]) => {
  console.log(` hasLocationPermission: ${hasLocationPermissions ? 'Yes': 'No'} `);
  console.log(` hasCameraPermissions: ${hasCameraPermissions ? 'Yes': 'No'} `);
  amountOfTimesFired++;
  console.log(`Amount of Times this has been fired: ${amountOfTimesFired}`);

  const promises = [];

  if (!hasLocationPermissions) {
    promises.push(this.dialog.alert('You cannot use this app without location access', 'Access to Location is Required!'));
  }

  if (!hasCameraPermissions) {
    promises.push(this.dialog.alert('Access to the Camera is required to use this application, Please go to your settings and enable Camera Permissions', 'Access to the Camera is Required!'));
  }

  if (hasLocationPermissions && hasCameraPermissions) {
    resolve(true);
  } else {
    Promise.all(promises).then(() => {
      this.store.dispatch(new AuthActions.LogoutAction());
      Permissions.openAppSettings();
      resolve(false);
    });
  }
});

which results in the following log

JS: Requesting Location Permissions // first request
JS: [@SpartaDigital/nativescript-permissions]  #requestLocationPermission failed
JS: [@SpartaDigital/nativescript-permissions]  -- Has Args?  true
JS: [@SpartaDigital/nativescript-permissions]  -- {
JS:     "android.permission.ACCESS_FINE_LOCATION": false
JS: }
JS: Requesting Camera Permissions
JS: [@SpartaDigital/nativescript-permissions]  #requestCameraPermission failed
JS: [@SpartaDigital/nativescript-permissions]  -- Has Args? true
JS: [@SpartaDigital/nativescript-permissions]  -- {
JS:     "android.permission.CAMERA": false
JS: }
JS:  hasLocationPermission: No
JS:  hasCameraPermissions: No
JS: Amount of Times this has been fired: 1
JS: [@SpartaDigital/nativescript-permissions]  #requestLocationPermission success
JS: [@SpartaDigital/nativescript-permissions]  -- Has Args?  true
JS: [@SpartaDigital/nativescript-permissions]  -- {
JS:     "android.permission.ACCESS_FINE_LOCATION": true
JS: }
JS: Requesting Camera Permissions
ActivityManager: START u0 {act=android.content.pm.action.REQUEST_PERMISSIONS pkg=com.google.android.packageinstaller cmp=com.google.android.packageinstaller/com.android.packageinstaller.permission.ui.GrantPermissionsActivity (has extras)} from uid 10491 pid 17880
JS: [@SpartaDigital/nativescript-permissions]  #requestCameraPermission success
JS: [@SpartaDigital/nativescript-permissions]  -- Has Args? true
JS: [@SpartaDigital/nativescript-permissions]  -- {
JS:     "android.permission.CAMERA": true
JS: }
JS:  hasLocationPermission: Yes
JS:  hasCameraPermissions: Yes
JS: Amount of Times this has been fired: 1 // <-- Apparently the first time its been called again? 

Any Ideas?

Where is this 'android' object coming from?

I have been trying to figure out how to get permissions into my nativescript app and came across your plugin.

When looking through the source code of it, I see numerous references to an 'android' object. Where is this coming from since 'application' is the only thing that is being imported?

Below is an example of what I mean:
var hasPermission = android.content.pm.PackageManager.PERMISSION_GRANTED == android.support.v4.content.ContextCompat.checkSelfPermission(application.android.foregroundActivity, perm);

Cant request 'ANSWER_PHONE_CALLS'

Does not work with this permission.

I'm very new to Nativescript so i might be wrong.

hasPermission method crashed, and requestPermission does nothing.

Using Android 8.0 on OnePlus 3T

Android error if request more than once for permissions

I have this app that tracks user location, so I deny permission the first time it asked me on screen X, then I went to some other screen Y and came back to screen X and it asked for permissions again but after selecting "Deny" this second time it throw an error on this line:

if (typeof promises.granted !== 'function') { return; }

Basically the error says that "promises" is undefined, so it cannot read "granted", does not matter if granted was there or not, promises is undefined...

Using NS 2.3.0 and plugin version 1.2.0

Thanks!

nativeException: "constructor": "constructor()function () { [native code] }" }

@NathanaelA , nice simple plugin. I put it on the real situation. For example, create a app where the main page require to access the calllog. So i add some code your demo main-view-model.js as

  function HelloWorldModel() {
        _super.call(this);

        var cursor = appModule.android.context.getContentResolver().query(
            android.provider.CallLog.Calls.CONTENT_URI,
            null, null, null, null);
        if (cursor && cursor.getCount() > 0) {
            while (cursor.moveToNext()) { }
            cursor.close();
        }

        this.set("message", "Click to see if I have permissions!");
    }

Now, I want to settle to the permission before go to main page. So I think i should request on app.ts.

var application = require("application");
var permissions = require("nativescript-permissions");


console.log("Requested permissions:", [
    android.Manifest.permission.CAMERA,
    android.Manifest.permission.READ_CALL_LOG,
    android.Manifest.permission.ACCESS_FINE_LOCATION,
    android.Manifest.permission.READ_EXTERNAL_STORAGE,
    android.Manifest.permission.WRITE_EXTERNAL_STORAGE]
);
permissions.requestPermission([
    android.Manifest.permission.CAMERA,
    android.Manifest.permission.READ_CALL_LOG,
    android.Manifest.permission.ACCESS_FINE_LOCATION,
    android.Manifest.permission.READ_EXTERNAL_STORAGE,
    android.Manifest.permission.WRITE_EXTERNAL_STORAGE],
    "I really need all the permissions in the world!")
    .then(function (result) {
        console.log("WooHoo you granted me all the permissions!");

        application.start({ moduleName: "main-page" });
    })
    .catch(function (result) {
        var count = 0;
        console.dump(result);
        for (var res in result) {
            if (!result.hasOwnProperty(res)) { continue; }
            if (result[res] === true) { count++; }

        }
        console.log("Oops, I'm so sad, I was only granted " + count + " of 4 permissions!");
    });

However, I got below exception

JS: Requested permissions: android.permission.CAMERA,android.permission.READ_CALL_LOG,android.permission.ACCESS_FINE_LOCATION,android.permission.READ_EXTERNAL_STORAGE,android.permission.WRITE_EXTERNAL_STORAGE
JS: === dump(): dumping members ===
JS: {
JS:     "nativeException": {
JS:         "constructor": "constructor()function () { [native code] }"
JS:     }
JS: }
JS: === dump(): dumping function and properties names ===
JS: === dump(): finished ===

I got 2 questions.
#1. In above situation, is it too early to invoke requestPermission? Where is the early places to invoke requestPermission before goes to main screen.
#2. Let's say if I register application.uncaughtErrorEvent, once the permission throw exception, the uncaughtErrorEvent catch above permission deny but how we could invoke requestPermission again and navigate back to main page.

java.lang.IllegalArgumentException: permission is null

When I try permissions.hasPermission, this error happens

An uncaught Exception occurred on "main" thread.
com.tns.NativeScriptException: 
Calling js method onClick failed

Error: java.lang.IllegalArgumentException: permission is null
    android.support.v4.content.ContextCompat.checkSelfPermission(ContextCompat.java:450)
    com.tns.Runtime.callJSMethodNative(Native Method)
    com.tns.Runtime.dispatchCallJSMethodNative(Runtime.java:1088)
    com.tns.Runtime.callJSMethodImpl(Runtime.java:970)
    com.tns.Runtime.callJSMethod(Runtime.java:957)
    com.tns.Runtime.callJSMethod(Runtime.java:941)
    com.tns.Runtime.callJSMethod(Runtime.java:933)
    com.tns.gen.java.lang.Object_button_19_32_ClickListenerImpl.onClick(Object_button_19_32_ClickListenerImpl.java:12)
    android.view.View.performClick(View.java:5205)
    android.view.View$PerformClick.run(View.java:21164)
    android.os.Handler.handleCallback(Handler.java:739)
    android.os.Handler.dispatchMessage(Handler.java:95)
    android.os.Looper.loop(Looper.java:148)
    android.app.ActivityThread.main(ActivityThread.java:5417)
    java.lang.reflect.Method.invoke(Native Method)
    com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
    com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
File: "file:///data/data/org.nativescript.Browse/files/app/tns_modules/nativescript-permissions/permissions.js, line: 112, column: 43

StackTrace: 
	Frame: function:'hasPermission', file:'file:///data/data/org.nativescript.Browse/files/app/tns_modules/nativescript-permissions/permissions.js', line: 112, column: 44
	Frame: function:'flash', file:'file:///data/data/org.nativescript.Browse/files/app/page2.js', line: 10, column: 21
	Frame: function:'Observable.notify', file:'file:///data/data/org.nativescript.Browse/files/app/tns_modules/tns-core-modules/data/observable/observable.js', line: 110, column: 23
	Frame: function:'Observable._emit', file:'file:///data/data/org.nativescript.Browse/files/app/tns_modules/tns-core-modules/data/observable/observable.js', line: 127, column: 18
	Frame: function:'ClickListenerImpl.onClick', file:'file:///data/data/org.nativescript.Browse/files/app/tns_modules/tns-core-modules/ui/button/button.js', line: 26, column: 23


	at com.tns.Runtime.callJSMethodNative(Native Method)
	at com.tns.Runtime.dispatchCallJSMethodNative(Runtime.java:1088)
	at com.tns.Runtime.callJSMethodImpl(Runtime.java:970)
	at com.tns.Runtime.callJSMethod(Runtime.java:957)
	at com.tns.Runtime.callJSMethod(Runtime.java:941)
	at com.tns.Runtime.callJSMethod(Runtime.java:933)
	at com.tns.gen.java.lang.Object_button_19_32_ClickListenerImpl.onClick(Object_button_19_32_ClickListenerImpl.java:12)
	at android.view.View.performClick(View.java:5205)
	at android.view.View$PerformClick.run(View.java:21164)
	at android.os.Handler.handleCallback(Handler.java:739)
	at android.os.Handler.dispatchMessage(Handler.java:95)
	at android.os.Looper.loop(Looper.java:148)
	at android.app.ActivityThread.main(ActivityThread.java:5417)
	at java.lang.reflect.Method.invoke(Native Method)
	at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
	at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
Caused by: java.lang.IllegalArgumentException: permission is null
	at android.support.v4.content.ContextCompat.checkSelfPermission(ContextCompat.java:450)
	... 16 more

Does this work with Angular?

I have started a new project using the tns for an angular project, and I have copied your example code almost verbatim, but when I go to request the permission, it automatically fails without prompting the user at all. Here goes the code:

In app.component.ts:

import {Component, OnInit} from "@angular/core";
var permissions = require('nativescript-permissions');

declare var android: any;

@Component({
    selector: "my-app",
    templateUrl: "app.component.html",
})
export class AppComponent implements OnInit {
    ngOnInit() {
    }

    public counter: number = 16;

    public get message(): string {
        if (this.counter > 0) {
            return this.counter + " taps left";
        } else {
            return "Hoorraaay! \nYou are ready to start building!";
        }
    }

    public onTap() {
        this.counter--;
        this.handleRequestForPermissions();
    }

    public handleRequestForPermissions() {
        permissions.requestPermission(android.Manifest.permission.READ_CONTACTS, "I need these permissions because I'm cool")
            .then(function () {
                console.log("Woo Hoo, I have the power!");
            })
            .catch(function (e) {
                console.log("Uh oh, no permissions - plan B time!",JSON.stringify(e) );
            });
    }
}

And in my android manifest file:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="__PACKAGE__"
    android:versionCode="1"
    android:versionName="1.0">

    <supports-screens
        android:smallScreens="true"
        android:normalScreens="true"
        android:largeScreens="true"
        android:xlargeScreens="true"/>

    <uses-sdk
        android:minSdkVersion="17"
        android:targetSdkVersion="23"/>

    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
    <uses-permission android:name="android.permission.READ_CONTACTS"/>
    <uses-permission android:name="android.permission.INTERNET"/>

    <application
        android:name="com.tns.NativeScriptApplication"
        android:allowBackup="true"
        android:icon="@drawable/icon"
        android:label="@string/app_name"
        android:theme="@style/AppTheme">

        <activity
            android:name="com.tns.NativeScriptActivity"
            android:label="@string/title_activity_kimera"
            android:configChanges="keyboardHidden|orientation|screenSize"
            android:theme="@style/LaunchScreenTheme">

            <meta-data android:name="SET_THEME_ON_LAUNCH" android:resource="@style/AppTheme" />

            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        <activity android:name="com.tns.ErrorReportActivity"/>
    </application>
</manifest>

The error message:

JS: Uh oh, no permissions - plan B time! {"android.permission.READ_CONTACTS":false}

Am I missing something obvious here?

Cant request for READ_PRIVILEGED_PHONE_STATE permission

HI i encountered problem while testing in my physical device with os version android 10

Error: java.lang.IllegalArgumentException: permission is null

I'm asking for permission READ_PRIVILEGED_PHONE_STATE to get imei of device

App to app permissions

Hi Nathaneal,

We used most of your plugins more than 25 in our app , all are useful ,but beyond that we need some plugins for app to app permissions to fetch data from their apps like (Fitbit,Garmin) to our app ,but we achieved for one device named as googlefit(Apple Healthkit) and got a output successfully, in the same way we are looking for fitbit,garmin and some devices,,can you have any idea on how to do this??

Note:
how can a plugin can be written by own ?? for our business logic needs can we write a own plugin??is it achievable

Property 'Manifest' does not exist on type 'typeof android'

This must be something obvious, but I don't know what to do. I have added platform references per NS documentation and android.Manifest isn't defined there. What do you use?

I am trying to use this plugin along with the nativescript-contacts one to hack together a quick proof of concept. Currently the contants plugin fails with a permission error on Android 7.1 but works on 4.4, hence my interest in the permissions plugin.

import { Observable } from 'data/observable';
var app = require("application");
var contacts = require("nativescript-contacts");
var permissions = require("nativescript-permissions");

export class HelloWorldModel extends Observable {

   // tap first
    onTap2() {
        permissions.requestPermission(android.Manifest.permission.READ_CONTACTS, "I need these permissions because I'm cool")
            .then(function () {
                console.log("Woo Hoo, I have the power!");
            })
            .catch(function () {
                console.log("Uh oh, no permissions - plan B time!");
            });
    }

   // tap second
    public onTap() {
        contacts.getContact().then(function (args) {
            /// Returns args: 
            /// args.data: Generic cross platform JSON object 
            /// args.reponse: "selected" or "cancelled" depending on wheter the user selected a contact.  
            console.log('args.response ' + args.response);

            if (args.response === "selected") {
                var contact = args.data; //See data structure below 

                // lets say you wanted to grab first name and last name 
                console.log(contact.name.given + " " + contact.name.family);

                //lets say you want to get the phone numbers 
                contact.phoneNumbers.forEach(function (phone) {
                    console.log(phone.value);
                });

                //lets say you want to get the addresses 
                contact.postalAddresses.forEach(function (address) {
                    console.log(address.location.street);
                });
            }
        });
    }
}
$ tns info
All NativeScript components versions information
┌──────────────────┬─────────────────┬────────────────┬─────────────┐
│ Component        │ Current version │ Latest version │ Information │
│ nativescript     │ 3.0.3           │ 3.0.3          │ Up to date  │
│ tns-core-modules │ 3.0.1           │ 3.0.1          │ Up to date  │
│ tns-android      │ 3.0.1           │ 3.0.1          │ Up to date  │
│ tns-ios          │ 3.0.1           │ 3.0.1          │ Up to date  │
└──────────────────┴─────────────────┴────────────────┴─────────────┘
$ cat package.json 
{
  "description": "NativeScript Application",
  "license": "SEE LICENSE IN <your-license-filename>",
  "readme": "NativeScript Application",
  "repository": "<fill-your-repository-here>",
  "nativescript": {
    "id": "org.nativescript.ContactBrowingTest",
    "tns-ios": {
      "version": "3.0.1"
    },
    "tns-android": {
      "version": "3.0.1"
    }
  },
  "dependencies": {
    "nativescript-contacts": "git+https://github.com/sserdyuk/nativescript-contacts.git",
    "nativescript-permissions": "^1.2.3",
    "nativescript-theme-core": "~1.0.2",
    "tns-core-modules": "~3.0.0"
  },
  "devDependencies": {
    "babel-traverse": "6.24.1",
    "babel-types": "6.24.1",
    "babylon": "6.17.2",
    "lazy": "1.0.11",
    "nativescript-dev-android-snapshot": "^0.*.*",
    "nativescript-dev-typescript": "~0.4.0",
    "tns-platform-declarations": "^3.0.1",
    "typescript": "~2.2.1"
  }
}

Can't request permission ACTIVITY_RECOGNITION

I'm trying to request permission for com.google.android.gms.permission.ACTIVITY_RECOGNITION but when I write this

permissions.requestPermission(com.google.android.gms.permission.ACTIVITY_RECOGNITION, "bla")
.then(function() {
	// ...
});

I get the error: Cannot read property ACTIVITY_RECOGNITION of undefined

Promises is undefined

Hi,
I'm trying to use this plugin and got the following error:

JS: ORIGINAL EXCEPTION: TypeError: Cannot read property 'failed' of undefined
JS: ORIGINAL STACKTRACE:
JS: TypeError: Cannot read property 'failed' of undefined
JS:     at Object.callback (/data/data/org.nativescript.sParks/files/app/tns_modules/nativescript-permissions/permissions.js:49:11)
JS:     at AndroidApplication.Observable.notify (/data/data/org.nativescript.sParks/files/app/tns_modules/data/observable/observable.js:155:23)
JS:     at NativeScriptActivity.onRequestPermissionsResult (/data/data/org.nativescript.sParks/files/app/tns_modules/ui/frame/frame.js:662:29)
JS:     at enableLocationRequestCore (/data/data/org.nativescript.sParks/files/app/tns_modules/nativescript-geolocation/nativescript-geolocation.js:224:51)
JS:     at Object.enableLocationRequest (/data/data/org.nativescript.sParks/files/app/tns_modules/nativescript-geolocation/nativescript-geolocation.js:145:5)
JS:     at AppComponent.enableLocation (/data/data/org.nativescript.sParks/files/app/app.component.js:80:25)
JS:     at AppComponent.onMapReady (/data/data/org.nativescript.sParks/files/app/app.component.js:59:14)
JS:     at DebugAppView._View_AppComponent0._handle_mapReady_2_0 (AppComponent.template.js:605:28)
JS:     at Object.<anonymous> (/data/data/org.nativescript.sParks/files/app/tns_modules/@angular/core/src/linker/view.js:316:24)
JS:     at ZoneDelegate.invoke (/data/data/org.nativescript.sParks/files/app/tns_modules/zone.js/dist/zone-node.js:281:29)
JS: ERROR CONTEXT:
JS: [object Object]

The line 49 is using promises which seems to be undefined. Here is the incriminated function:

application.android.on(application.AndroidApplication.activityRequestPermissionsEvent, function(args) {

  // get current promise set
  var promises = pendingPromises[args.requestCode];

  // Delete it
  delete pendingPromises[args.requestCode];

  // Check the status of the permission
  if (args.grantResults.length > 0) {
    if (args.grantResults[0] === android.content.pm.PackageManager.PERMISSION_GRANTED) {
      promises.granted();
      return;
    }
  }
  promises.failed();

});

Why is promises undefined ?
I'm using the plugin exactly as the README suggests it.

"no v4 support" when requesting permission

We have a problem where we can't request any permissions on Android because all we get are "no v4 support" errors every time you try, there is not even a popup where you can confirm/deny access. This goes for location, phone access, you name it.

This happened without using this plugin so we thought we'd use this plugin to fix it, however the issue remains.

We are doing this:

declare var android: any;

import { requestPermission } from 'nativescript-permissions';

...
myFn() {
    requestPermission(android.Manifest.permission.CALL_PHONE, "I need these permissions because I'm cool").then(() => console.log('success')).catch((e) => console.log(e));
}

Another strange thing here is that success is being logged despite the fact that there is an error occurring when requesting permission.

What should we do to fix this?

Webpack: Android is not defined

Hi,

on the latest version, I'm facing the issue android is not defined when I want to bundle a release version that I've trailed down to this specific line

if (!android.support || !android.support.v4 || !android.support.v4.content || !android.support.v4.content.ContextCompat || !android.support.v4.content.ContextCompat.checkSelfPermission) {

Tried to add guard clause on android property, but not working either
if (!android || !android.support || !android.support.v4

I've search for a couple of days to fix that, any idea why it's happening?

Issue for ios, Android var is not found

If I require the plugin at the top of my js file, then it would crash on ios, basically saying that "android" is not found or undefined, line 17

// If this isn't a Android platform we will exit and do nothing.
if (!android) {
    return;
}

But instead it crashes.

Nice plugin!

Thanks

Issue with Manifest

For some reason, android.Manifest does not exist. I'm testing like so:

    var permissions = require("nativescript-permissions");

console.log(JSON.stringify(android.Manifest));

    permissions.requestPermission(android.Manifest.permission.CAMERA, "I need access to your camera!")
    .then(function() {
        console.log("Woo Hoo, I have the power!");
        //todo - enable button
    })
    .catch(function() {
        console.log("Uh oh, no permissions - plan B time!");
    });

And I never get the request. This is in ngOnInit.

iOS Returns True for Compatibility

I was thinking, for cross-platform compatibility, instead of

if (!global.android) {
    return;
}

maybe just return true for iOS?

function hasPermission(perm) {
    if (!hasSupportVersion4()) return true;
    if (!global.android) return true;

    var hasPermission = android.content.pm.PackageManager.PERMISSION_GRANTED ==
        android.support.v4.content.ContextCompat.checkSelfPermission(application.android.foregroundActivity, perm);
    return (hasPermission);
}

Thoughts?

I just saw this issue, #7

Permissions catching error when trying to use camera or video recorder

Hello, I'm trying to use videorecorder plugin which has your dependency.

I tracked down the issue that the permissions are not being granted and catching error

I made sure that in the Manifest I gave all the permissions needed but when I'm logging out the error this is what I'm getting

JS: === dump(): dumping members ===
JS: {
JS:     "nativeException": {
JS:         "constructor": "constructor()function () { [native code] }"
JS:     }
JS: }
JS: === dump(): dumping function and properties names ===
JS: === dump(): finished ===
JS: Oops, I'm so sad, I was only granted 0 of 4 permissions!
JS: === dump(): dumping members ===
JS: {
JS:     "event": "camera permission needed"
JS: }
JS: === dump(): dumping function and properties names ===
JS: === dump(): finished ===

Do you think we can fix this issue?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.