how to use storage Permission in flutter? - android

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"/>

Related

Permission Android/data in Android 12 (open failed: EACCES (Permission denied)")

I want to edit a file with ini format. There is no problem outside the Android/data folder and it works, but I want to access it in the following path.
Direction :
/Android/data/com.xxx.xxx/files/xxx/xxx.ini
Error:
"/storage/emulated/0/Android/data/com.xxx.xxx/files/xxx/xxx.ini: open failed: EACCES (Permission denied)"
permissions
`<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.QUERY_ALL_PACKAGES"
tools:ignore="QueryAllPackagesPermission" />
<uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE"
tools:ignore="ScopedStorage"/>
android:requestLegacyExternalStorage="true"`
Сode
fun Save() {
val ini = Wini(
File(
Environment.getExternalStorageDirectory()
.toString() +
"/Android/data/com.xxxx.xxx/xxx/xxx/xxx.ini"
)
)
ini.put("client", "name", nickName)
ini.store()
}
This code works :
fun SaveNick() {
val ini = Wini(
File(
Environment.getExternalStorageDirectory()
.toString() +
"/xxx.ini"
)
)
ini.put("client", "name", nickName)
ini.store()
}

Requesting android permissions in Ionic React app using Capacitor

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>

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.

Android M permissions, return incorrect result

I have the following permissions in my application for Andorid M devices. I have tested this on 6.0.0 and 6.0.1 and I am getting the same results on both Nexus 5X and Nexus 6P. Basically every permission returns wrong results and when I enable/disable them, the result does not change.
I will paste some sample test code below to show how I am testing this.
Manifest Permissions:
<uses-permission android:name="android.permission.CALL_PHONE" />
<uses-permission android:name="android.permission.VIBRATE" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.NFC" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.BIND_NFC_SERVICE" />
<uses-permission android:name="com.samsung.android.providers.context.permission.WRITE_USE_APP_FEATURE_SURVEY" />
<uses-permission android:name="android.permission.RECEIVE" />
<uses-permission android:name="com.google.android.c2dm.permission.RECEIVE" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="com.simplytapp.virtualcard.permission.C2D_MESSAGE" />
<uses-permission android:name="android.permission.READ_CONTACTS" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
MainActivity:
private static final String[] CHECK_PERMISSIONS = {
Manifest.permission.READ_PHONE_STATE,
Manifest.permission.CALL_PHONE,
Manifest.permission.READ_CALL_LOG,
Manifest.permission.WRITE_CALL_LOG,
Manifest.permission.USE_SIP,
Manifest.permission.PROCESS_OUTGOING_CALLS,
Manifest.permission.CALL_PRIVILEGED,
Manifest.permission.MODIFY_PHONE_STATE,
Manifest.permission.VIBRATE,
Manifest.permission.INTERNET,
Manifest.permission.NFC,
Manifest.permission.ACCESS_NETWORK_STATE,
Manifest.permission.WRITE_EXTERNAL_STORAGE,
Manifest.permission.BIND_NFC_SERVICE,
Manifest.permission.WAKE_LOCK,
Manifest.permission.READ_CONTACTS,
Manifest.permission.READ_EXTERNAL_STORAGE,
Manifest.permission.ACCESS_FINE_LOCATION
};
for (int i = 0; i < CHECK_PERMISSIONS.length; i++) {
permissionsController.checkAccessPermissions(0, CHECK_PERMISSIONS[i]);
}
public boolean checkAccessPermissions(int statusCode, String permission) {
boolean granted = true;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
if (ActivityCompat.checkSelfPermission(mContext, permission) != PackageManager.PERMISSION_GRANTED) {
granted = false;
}
}
Log.i("Permissions Check", "Permission: " + permission + " - has status: " + granted);
return granted;
}
This will always return the same result weather permissions are granted or not.
Permissions Check: Permission: android.permission.READ_PHONE_STATE - has status: true
Permissions Check: Permission: android.permission.CALL_PHONE - has status: true
Permissions Check: Permission: android.permission.READ_CALL_LOG - has status: false
Permissions Check: Permission: android.permission.WRITE_CALL_LOG - has status: false
Permissions Check: Permission: android.permission.USE_SIP - has status: false
Permissions Check: Permission: android.permission.PROCESS_OUTGOING_CALLS - has status: false
Permissions Check: Permission: android.permission.CALL_PRIVILEGED - has status: false
Permissions Check: Permission: android.permission.MODIFY_PHONE_STATE - has status: false
Permissions Check: Permission: android.permission.VIBRATE - has status: true
Permissions Check: Permission: android.permission.INTERNET - has status: true
Permissions Check: Permission: android.permission.NFC - has status: true
Permissions Check: Permission: android.permission.ACCESS_NETWORK_STATE - has status: true
Permissions Check: Permission: android.permission.WRITE_EXTERNAL_STORAGE - has status: true
Permissions Check: Permission: android.permission.BIND_NFC_SERVICE - has status: false
Permissions Check: Permission: android.permission.WAKE_LOCK - has status: true
Permissions Check: Permission: android.permission.READ_CONTACTS - has status: true
Permissions Check: Permission: android.permission.READ_EXTERNAL_STORAGE - has status: true
Permissions Check: Permission: android.permission.ACCESS_FINE_LOCATION - has status: true
Either you need to compile your app for target api 22, or you should request the permissions at run time. See: http://developer.android.com/training/permissions/requesting.html
This is just one of the example for permission location of google map. you can add more on it to check other.
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && getActivity().checkSelfPermission( Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED && getActivity().checkSelfPermission(Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
if(!shouldShowRequestPermissionRationale(Manifest.permission.ACCESS_FINE_LOCATION)) {
alertOpenSetting();
}else {
checkLocationPermission();
ActivityCompat.requestPermissions(getActivity(), new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, REQUEST_CODE_ASK_PERMISSIONS);
}
}
public boolean checkLocationPermission()
{
String permission = "android.permission.ACCESS_FINE_LOCATION";
int res = getActivity().checkCallingOrSelfPermission(permission);
return (res == PackageManager.PERMISSION_GRANTED);
}
#Override
public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) {
switch (requestCode) {
case 0: {
//null or 0
}
case 1: {
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
insertPermissionWrapper();
NetworkManager.getInstance().startLocationService();
}else {
//denied
}
return;
}
default:
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
}
}
private void alertOpenSetting() {
AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(getActivity());
alertDialogBuilder.setTitle("Location, Storage and Telephone permissions are required to use this app.");
alertDialogBuilder.setMessage("Please enable these permissions in Permissions under app settings.");
alertDialogBuilder.setNegativeButton("Go to setting", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
goToSettings();
}
});
alertDialogBuilder.create();
alertDialogBuilder.show();
}
HOPEFULLY THIS IS HELPS

Categories

Resources