Trying to delete an audio file but giving exception in flutter - flutter

I'm trying to delete song file but it is unable to delete and throws an exception of permission denied but permissions are already granted using permission_handler and required storage permissions are added in AndroidManifest.xml as well. I have also checked path is valid and file exist before delete which return true. Would anyone help me to solve this.
Error on file.delete() line.
Unhandled Exception: FileSystemException: Deletion failed, path = '/storage/0E15-2E06/Music/Call Sound Effect.mp3' (OS Error: Permission denied, errno = 13)
AndroidManifest:
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE" />
<application
android:label="Example"
android:name="${applicationName}"
android:icon="#mipmap/ic_launcher"
android:usesCleartextTraffic="true"
android:requestLegacyExternalStorage="true" >
Code snippet:
if (await Permission.storage.request().isGranted) {
// Either the permission was already granted before or the user just granted it.
// permission was granted
if (song != null) {
String? path = song.data;
File file = File(path);
bool isExist = await file.exists();
if (isExist) {
await file.delete(recursive: true);
}
}
}

You have to use the permission_handler(https://pub.dev/packages/permission_handler) package and have to mention some permissions in the Androidmanifest.xml file.
<uses-permission android:name="android.permission.WRITE_INTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
Also, you have to ask Permission of storage before doing storage related operation(In your case deletion of audio file).
final _permissionStatus = await Permission.storage.request();
if(_permissionStatus = PermissionStatus.isGranted){
/// Delete audio file
}else{
/// Permission Denied.
}

Related

AndroidAlarmManagerPlus not starting automatically after reboot

I've set permissions in the AndroidManifest.xml file
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
<uses-permission android:name="android.permission.WAKE_LOCK"/>
I've also added the following lines in the AndroidManifest.xml as specified in the docs
<service
android:name="dev.fluttercommunity.plus.androidalarmmanager.AlarmService"
android:permission="android.permission.BIND_JOB_SERVICE"
android:exported="false"/>
<receiver
android:name="dev.fluttercommunity.plus.androidalarmmanager.AlarmBroadcastReceiver"
android:exported="false"/>
<receiver
android:name="dev.fluttercommunity.plus.androidalarmmanager.RebootBroadcastReceiver"
android:enabled="false">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED"></action>
</intent-filter>
</receiver>
In my main.dart file, I've the following lines of codes...
import 'package:android_alarm_manager_plus/android_alarm_manager_plus.dart';
void main() async {
WidgetsFlutterBinding.ensureInitialized();
await AndroidAlarmManager.initialize();
runApp(MyApp());
await AndroidAlarmManager.periodic(Duration(minutes: 1), 0, syncData);
}
void syncData() async {
print("synching data");
String? uploadedUrl = await S3.uploadToS3();
print(uploadedUrl);
}
What should I add for this to work automatically on reboot? TIA :)
From Android 8.0 You can't use most of the implicit broadcast ,
So your application service will not start on
ACTION_LOCKED_BOOT_COMPLETED or ACTION_BOOT_COMPLETED
for more details
you can use WorkManager instead to sync data to server
here is a good example

Get files from the directory - Flutter

I'm trying to fetch some files from the local directory by using the dependency path_provider: ^1.6.27, but was getting an error stating as Unhandled Exception: MissingPluginException(No implementation found for method getExtStorageData on channel path_provider_ex)
The code where I'm fetching
getFiles() async {
directory = (Directory('storage/emulated/0/FolderName')).path;
setState(() {
file = io.Directory('$directory/${widget.folderName}').listSync();
});
List<StorageInfo> storageInfo = await PathProviderEx.getStorageInfo();
}
Getting the error in the line List<StorageInfo> storageInfo = await PathProviderEx.getStorageInfo();
Have mentioned the permissions in the manifest file
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<application
android:requestLegacyExternalStorage="true"/>
If you have just added the plugin this may help you.
MissingPluginException

Capacitor Filesystem returns error while using main functions

I created a new app using capacitor 3, in this app I used the Filesystem to perform some functions. I created a service to handle everything related to the filesystem, but when I went to use the functions I had some problems.
When using Android 11 to create a directory using the mkdir() function I get the following error:
Unable to create directory, unknow reason.
Also on Android 11, when I try to create a file using only writeFile() it returns the following error:
FILE_NOTCREATED
For Android 10 and below the mkdir() function works correctly, but the writeFile() function causes the app to crash without any errors. Also, if I try to change the Diretory.ExternalStorage to Diretory.External I can create a directory in Android 11, but it still crashes when writing a file.
Using Android 11, I tried to write a txt file with a simple string and with also with a small base64 string. When using Diretory.External I can write the base64 string in a new file, but when using the Diretory.ExternalStorage I got the FILE_NOTCREATED error.
I did all the configurations and followed the steps in the documentation to set up AndroidManifest.xml.
Several tests have been done on emulators and phones with different versions of Android.
Tests with writeFile()
Android 11
base64 + Diretory.External = success
string + Diretory.External = crash
base64 + Diretory.ExternalStorage = error
string + ExternalStorage = error
Android 10 and below
base64 + Diretory.External = success
string + Diretory.External = crash
base64 + Diretory.ExternalStorage = success
string + ExternalStorage = crash
Android XML
<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"
android:requestLegacyExternalStorage="true"
>
<!-- Permissions -->
<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.MANAGE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-feature android:name="android.hardware.location.gps" android:required="true" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
MainFunction.ts
testeFilesystem(): void {
let path: string = 'test/project';
this.filesystem.checkAndCreateDir(path).then(_ => {
this.filesystem.writeFile(path, 'test.txt', 'test').then(_ => {
this.uicontroller.presentToast('file saved');
});
})
}
FilesystemService.ts
checkAndCreateDir(path: string): Promise<boolean> {
return Filesystem.readdir({
path: path,
directory: Directory.ExternalStorage
}).then(_ => {
return true;
}).catch(_ => {
return Filesystem.mkdir({
path: path,
directory: Directory.ExternalStorage,
recursive: true
}).then(_ => {
return true;
});
});
}
writeFile(path: string, filename: string, content: string): Promise<boolean> {
return Filesystem.writeFile({
path: path + filename,
data: content,
directory: Directory.ExternalStorage
}).then(result => {
if (result) {
return true;
} else {
return false;
}
});
}
Ionic Info
Ionic CLI : 6.16.1 C:\Users\User\AppData\Roaming\npm\node_modules#ionic\cli
Ionic Framework : #ionic/angular 5.6.7
#angular-devkit/build-angular : 0.1102.10
#angular-devkit/schematics : 11.2.13
#angular/cli : 11.2.13
#ionic/angular-toolkit : 3.1.1
Capacitor:
Capacitor CLI : 3.0.0
#capacitor/android : 3.0.0
#capacitor/core : 3.0.0
#capacitor/ios : not installed
Utility:
cordova-res : 0.15.3
native-run : 1.3.0
System:
NodeJS : v14.16.1 (C:\Program Files (x86)\nodejs\node.exe)
npm : 6.14.12
OS : Windows 10
Got the same error ('FILE_NOTCREATED') on Android 12 using the following code after some writes:
// Save to filesystem
const resp = await Filesystem.writeFile({
path: fileName,
data, // base64 pdf
directory: Directory.Documents,
});
The error occurs because of the same filename. After adding the current date with the following way, the error was solved:
const currentDate = new Date().toLocaleString().replace(/[,:\s\/]/g, '-');
const fileName = `myFile-${currentDate}.pdf`;
Be aware to replace all slashes because if not it will create sub-directories and if 'recursive: true' is not added the following error occurs on android:
Parent folder not found.
I found this issue on capacitor's github, maybe it can help you, in short it says:
If you target SDK 30, then android:requestLegacyExternalStorage="true" will not work on Android 11+ devices.
Google doesn't allow to programmatically access external shared files anymore. (Documents and ExternalStorage)
https://developer.android.com/training/data-storage/use-cases#opt-out-in-production-app

Flutter Image File share Permission Denial

When i am try to share my directory image via share plug in ! Image is not going to share ! Asking me permission what is that ??? Can any one give me solution on it
FlatButton(
onPressed: () async {
Directory dir = await getApplicationDocumentsDirectory();
File testFile = new File("${dir.path}/image.png");
FlutterShareFile.shareImage(dir.path, "image.png", ShareFileType.image);
},
)
I am getting this type of warning :
E/DatabaseUtils( 8123): java.lang.SecurityException: Permission Denial: reading androidx.core.content.FileProvider uri content://com.photogranth.watermark.contentprovider/images/image.png from pid=6574, uid=1000 requires the provider be exported, or grantUriPermission()
E/DatabaseUtils( 8123): at android.content.ContentProvider.enforceReadPermissionInner(ContentProvider.java:742)
E/DatabaseUtils( 8123): at android.content.ContentProvider$Transport.enforceReadPermission(ContentProvider.java:615)
E/DatabaseUtils( 8123): at android.content.ContentProvider$Transport.enforceFilePermission(ContentProvider.java:606)
E/DatabaseUtils( 8123): at android.content.ContentProvider$Transport.openTypedAssetFile(ContentProvider.java:520)
E/DatabaseUtils( 8123): at android.content.ContentProviderNative.onTransact(ContentProviderNative.java:307)
E/DatabaseUtils( 8123): at android.os.Binder.execTransactInternal(Binder.java:1021)
E/DatabaseUtils( 8123): at android.os.Binder.execTransact(Binder.java:994)
Did you add this to your AndroidManifest.xml file?
<application>
...
<provider
android:name="androidx.core.content.FileProvider"
android:authorities="${applicationId}.provider"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="#xml/provider_paths"/>
</provider>
</application>

nativescript-contacts throw error

Error: Error: java.lang.SecurityException: Permission Denial: opening provider com.android.providers.contacts.ContactsProvider2 from ProcessRecord{c896ebc 5117:org.nativescript.Jztong/u0a11
1} (pid=5117, uid=10111) requires android.permission.READ_CONTACTS or android.permission.WRITE_CONTACTS
Add this lines in your app/App_Resources/Android/AndroidManifest.xml
<uses-permission android:name="android.permission.WRITE_CONTACTS" />
<uses-permission android:name="android.permission.READ_CONTACTS" />
If you are using android v6 you should requires permission at runtime, you can use nativescript-permissions plugin.
var perm = permissions.requestPermission(android.Manifest.permission.WRITE_CONTACTS, "I need write Contact permission!");
perm.then(() => {
//addContact();
}).catch(() => {
alert("Oops, No permissions to write contact!");
});