Requesting android permissions in Ionic React app using Capacitor - android

I have an Ionic React project that builds and runs successfully on a One Plus 7 Pro running android 11. I am having trouble implementing all of the permission requests that the app needs to function properly. I'm using the android permissions plugin to trigger the permission requests and some requests are working but none of the bluetooth related permissions are. Specifically the camera and access_fine_location permission requests are properly prompting the user to accept/decline but any bluetooth permissions don't prompt the user. Before I request each permission I perform a check to see if the permission has already been granted or not. Of the four bluetooth permissions I am trying to use, two report that they have already been granted (BLUETOOTH & BLUETOOTH_ADMIN) and two report that they haven't been granted (BlUETOOTH_CONNECT & BLUETOOTH_SCAN). But when I check permissions in app info it shows that the only permissions granted are the camera and access_fine_location, both of which I'm not having any trouble with. Can anyone tell me why none of my bluetooth permission requests are working?
Link to the android permissions plugin I am using:
https://ionicframework.com/docs/native/android-permissions
PermissionServices.tsx file with my functions that handle permission requests:
import { Capacitor } from '#capacitor/core';
import { AndroidPermissions } from '#ionic-native/android-permissions';
const permissions =
{
//Working
requestCameraPermission() {
if (Capacitor.isNativePlatform()) {
AndroidPermissions.checkPermission(AndroidPermissions.PERMISSION.CAMERA).then(
result => {
if (result.hasPermission) {
//alert('you already have this permission')
alert('camera permission already granted');
} else {
//alert('please implement permission request')
AndroidPermissions.requestPermission(AndroidPermissions.PERMISSION.CAMERA);
}
}
)
}
else {
console.log('Capacitor not detected, this button will do nothing :(')
}
},
//NOT WORKING | App thinks request is already granted
requestBluetooth() {
if (Capacitor.isNativePlatform()) {
AndroidPermissions.checkPermission(AndroidPermissions.PERMISSION.BLUETOOTH).then(
result => {
if (result.hasPermission) {
alert('bluetooth permission already granted');
} else {
alert('bluetooth permission not granted');
AndroidPermissions.requestPermission(AndroidPermissions.PERMISSION.BLUETOOTH);
}
}
)
}
else {
console.log('Capacitor not detected, this button will do nothing :(')
}
},
//NOT WORKING | App thinks request is already granted
requestBluetoothAdmin() {
if (Capacitor.isNativePlatform()) {
AndroidPermissions.checkPermission(AndroidPermissions.PERMISSION.BLUETOOTH_ADMIN).then(
result => {
if (result.hasPermission) {
alert('bluetooth permission already granted');
} else {
alert('bluetooth permission not granted');
AndroidPermissions.requestPermission(AndroidPermissions.PERMISSION.BLUETOOTH_ADMIN);
}
}
)
}
else {
console.log('Capacitor not detected, this button will do nothing :(')
}
},
//NOT WORKING | permission not granted | request not working
requestBluetoothConnect() {
if (Capacitor.isNativePlatform()) {
AndroidPermissions.checkPermission(AndroidPermissions.PERMISSION.BLUETOOTH_CONNECT).then(
result => {
if (result.hasPermission) {
alert('bluetooth permission already granted');
} else {
alert('bluetooth permission not granted');
AndroidPermissions.requestPermission(AndroidPermissions.PERMISSION.BLUETOOTH_CONNECT);
}
}
)
}
else {
console.log('Capacitor not detected, this button will do nothing :(')
}
},
//NOTWORKING | permission not granted | request not working
requestBluetoothScan() {
if (Capacitor.isNativePlatform()) {
AndroidPermissions.checkPermission(AndroidPermissions.PERMISSION.BLUETOOTH_SCAN).then(
result => {
if (result.hasPermission) {
alert('bluetooth permission already granted');
} else {
alert('bluetooth permission not granted');
AndroidPermissions.requestPermission(AndroidPermissions.PERMISSION.BLUETOOTH_SCAN);
}
}
)
}
else {
console.log('Capacitor not detected, this button will do nothing :(')
}
},
//Working
requestFineLocation() {
if (Capacitor.isNativePlatform()) {
AndroidPermissions.checkPermission(AndroidPermissions.PERMISSION.ACCESS_FINE_LOCATION).then(
result => {
if (result.hasPermission) {
alert('fine location permission already granted');
} else {
alert('fine location permission not granted');
AndroidPermissions.requestPermission(AndroidPermissions.PERMISSION.ACCESS_FINE_LOCATION);
}
}
)
}
else {
console.log('Capacitor not detected, this button will do nothing :(')
}
}
}
export default permissions;
AndroidManifest.xml file showing that I have properly declared the permissions I am trying to use
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="io.ionic.starter">
<!-- android permissions -->
<uses-permission android:name="android.permission.BLUETOOTH" />
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
<uses-permission android:name="android.permission.BLUETOOTH_CONNECT" />
<uses-permission android:name="android.permission.BLUETOOTH_SCAN" />
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<application
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:roundIcon="#mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="#style/AppTheme">
<activity
android:configChanges="orientation|keyboardHidden|keyboard|screenSize|locale|smallestScreenSize|screenLayout|uiMode"
android:name="io.ionic.starter.MainActivity"
android:label="#string/title_activity_main"
android:theme="#style/AppTheme.NoActionBarLaunch"
android:launchMode="singleTask">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<provider
android:name="androidx.core.content.FileProvider"
android:authorities="${applicationId}.fileprovider"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="#xml/file_paths"></meta-data>
</provider>
</application>
</manifest>

Related

React Native android permission is not showing

The react native android permission pop-up is not showing, I cannot download a file. It works on a simulator but not on a real phone.
Here is my permission function :
const requestAndroidStoragePermission = async () => {
try {
const granted = await PermissionsAndroid.request(
PermissionsAndroid.PERMISSIONS.WRITE_EXTERNAL_STORAGE,
{
title: "File access",
message:
"The app needs files access to download your performance.",
}
);
if (granted === PermissionsAndroid.RESULTS.GRANTED) {
this.setState({ storagePermission: true });
this.setState({ showExportModal: true });
} else {
console.log("Files permission denied");
}
} catch (err) {
console.warn(err);
}
};
I have the permission on my AndroidManifest.xml :
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"
android:targetSdkVersion="29" />
Someone have an idea ?

how to use storage Permission in flutter?

I want to create flutter apps for downloading files from internet now I want to Check the storage permissions like the code below but I get the error: The method 'PermissionHandler' isn't defined what should I do?
Future<bool> _requestPermissions() async {
var permission = await PermissionHandler().checkPermissionStatus(PermissionGroup.storage);
if (permission != PermissionStatus.granted) {
await PermissionHandler().requestPermissions([PermissionGroup.storage]);
permission = await PermissionHandler().checkPermissionStatus(PermissionGroup.storage);
}
return permission == PermissionStatus.granted;
}
note:i have added the following permissions on AndroidManifest.xml
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>

FileSystemException: Creation failed, path = '/storage/emulated/0/4k' (OS Error: Permission denied, errno = 13) Flutter

I have added every thing required to download files to local storage still I'm getting this error
In Manifest
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.ACCESS_MEDIA_LOCATION"/>
android:requestLegacyExternalStorage="true"
android:hardwareAccelerated="true"
In pubspec.yaml
permission_handler: ^6.1.1
In Build.gradle
compileSdkVersion 30
minSdkVersion 22
targetSdkVersion 30
Future<bool> _requestPermission(Permission permission, Permission permission3,
Permission permission4) async {
print("xxxx IN ");
if (await permission.isGranted) {
print('xxxx ohhh');
return true;
} else {
await permission.request();
.then((value) => () {
print("xxxx value" + value.toString());
if (value == PermissionStatus.granted) {
print("xxxx PERMISSION GRANTED ");
return true;
} else {
print("xxxx PERMISSION DENIED ");
}
})
.whenComplete(() => print('xxxx COMPLETED'))
.onError((error, stackTrace) => () {
print("xxxx onError " + error);
print("xxxx onError " + stackTrace.toString());
})
.catchError((onError) => () {
print('xxxx catchError ' + onError.toString());
});
print("xxxx OUT ");
// var result2 = await permission3.request();
// var result3 = await permission4.request();
}
return false;
}
from this function see what's printed
not getting printed from then()...
Please Please help me out :)
Use android:requestLegacyExternalStorage="true" in the application tag not in <activity> tag:
<application
android:requestLegacyExternalStorage="true" >
what is work for me this
permission_handler: ^8.3.0 // use this version
and in your code
final status = await Permission.storage.request();
var state = await Permission.manageExternalStorage.status;
var state2 = await Permission.storage.status;
if (status.isGranted) {
directory = (await getExternalStorageDirectory())!;
}
if (!state2.isGranted) {
await Permission.storage.request();
}
if (!state.isGranted) {
await Permission.manageExternalStorage.request();
}
if (!await directory!.exists()) {
await directory.create(recursive: true);
}
and in the my permissions
<uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE">
</uses-permission>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"></uses-
permission>
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission
android:name="android.permission.ACTION_MANAGE_ALL_FILES_ACCESS_PERMISSION"/>

java.lang.SecurityException: my location requires permission ACCESS_FINE_LOCATION or ACCESS_COARSE_LOCATION

I have a question about my code.
So, I'm using nativescript-geolocation for get my location.
In component.ts I have this code:
import * as geoLocation from "nativescript-geolocation";
currentGeoLocation: any;
ngOnInit(): void {
geoLocation.isEnabled().then(enabled => {
if (!enabled) {
geoLocation.enableLocationRequest().then(() => geoLocation.watchLocation(location => {
this.currentGeoLocation = location;
this.mapView.longitude = this.currentGeoLocation.longitude;
this.mapView.latitude = this.currentGeoLocation.latitude;
this.mapView.zoom = 15;
console.log(this.currentGeoLocation)
}, error => {
alert(error);
}, {
desiredAccuracy: 3,
updateDistance: 10,
minimumUpdateTime: 1000 * 1
}));
} else {
geoLocation.watchLocation(location => {
this.currentGeoLocation = location;
this.mapView.longitude = this.currentGeoLocation.longitude;
this.mapView.latitude = this.currentGeoLocation.latitude;
this.mapView.zoom = 15;
console.log(this.currentGeoLocation)
}, error => {
alert(error);
}, {
desiredAccuracy: 3,
updateDistance: 10,
minimumUpdateTime: 1000 * 1
});
}
});
}
In AndroidMainfest.xml I have:
<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"/>
<uses-permission android:name="android.permission.READ_PHONE_STATE"/>
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
When install application show error
Android architecture
As per Android doc:
Android 6.0 Marshmallow introduced a new permissions model that lets
apps request permissions from the user at runtime, rather than prior
to installation. Apps that support the new model request permissions
when the app actually requires the services or data protected by the
services. While this doesn't (necessarily) change overall app
behavior, it does create a few changes relevant to the way sensitive
user data is handled:
If the user is running Android 6.0 (API level 23) or later, the user has to grant your app its permissions while they are running the app.
So you need to add run-time permission.
import { Component, OnInit } from "#angular/core";
import * as Permissions from "nativescript-permissions";
declare var android: any;
#Component({
selector: "ns-app",
templateUrl: "app.component.html",
})
export class AppComponent {
public getCameraPermission() {
Permissions.requestPermission(android.Manifest.permission.CAMERA, "Needed for connectivity status").then(() => {
console.log("Permission granted!");
}).catch(() => {
console.log("Permission is not granted (sadface)");
});
}
}
in Android M, you need to request run-time permission
Here Some simple steps to get Permission on Runtime from the user.
1) add below implementation in build.gradle file.
implementation 'com.karumi:dexter:5.0.0'
2) Add below code to get permission at what you want location from user.
Dexter.withActivity(activity)
.withPermissions(
Manifest.permission.ACCESS_FINE_LOCATION,
Manifest.permission.ACCESS_COARSE_LOCATION)
.withListener(new MultiplePermissionsListener() {
#Override
public void onPermissionsChecked(MultiplePermissionsReport report) {
Log.i(TAG, "onPermissionsChecked: ");
// check if all permissions are granted
if (report.areAllPermissionsGranted()) {
// All permissions are granted!
// Do what you want to do.
} else {
// Some permissions are not granted!
Toast.makeText(activity, "Permission not granted", Toast.LENGTH_SHORT).show();
}
}
#Override
public void onPermissionRationaleShouldBeShown(List<PermissionRequest> permissions, PermissionToken token) {
token.continuePermissionRequest();
}
}).
withErrorListener(new PermissionRequestErrorListener() {
#Override
public void onError(DexterError error) {
}
})
.onSameThread()
.check();
Manifest.permission.ACCESS_FINE_LOCATION and Manifest.permission.ACCESS_COARSE_LOCATION both use to get Location.
Function :-
if (report.areAllPermissionsGranted()) {
// Write code to get Location.
}
This function is to check permission granted by the user or not. If yes then it goes in.. And after that write your Code to get Location from User.

React Native - Dangerous permissions auto granted without pop-up

I am new to react-native and trying out permission model. I added following entry in AndroidManifes
<uses-permission android:name="android.permission.READ_CONTACTS" />
Added following function
async requestCameraPermission() {
try {
const granted = await PermissionsAndroid.request(
PermissionsAndroid.PERMISSIONS.READ_CONTACTS,
{
'title': 'Cool Photo App Camera Permission',
'message': 'Cool Photo App needs access to your camera ' +
'so you can take awesome pictures.'
}
)
if (granted === PermissionsAndroid.RESULTS.GRANTED) {
console.log("You can use the camera")
} else {
console.log("Camera permission denied")
}
} catch (err) {
console.warn(err)
}
}
And registered it in constructor as follows
this.requestCameraPermission = this.requestCameraPermission.bind(this);
And called it as
componentDidMount() {
this.requestCameraPermission();
}
I am getting permission auto granted without any pop-up to user. Please let me know if I am doing anything wrong or expecting wrong.

Categories

Resources