-
Notifications
You must be signed in to change notification settings - Fork 53
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Can't share file in Application Document Directory - found work around #27
Comments
There are several changes with Android API 29 and API 30 related to file handling. In fact even API 28 had some changes. |
@MrCsabaToth so what's the recommended API number that works with , e.g. flutter_share 1.0.3? |
Saw this one: """ Maybe this is the reason. |
I copied the app image file to the public download dir:
The operation seems successful, no error report by the app. But in the other to-be-shared app, the sharing is not happening. And I checked the "/Downloads/....jpeg", the file is copied there. Do you know why the sharing is not actually happening, while no error reported? What I should check further? P.S.: I just found some app e.g. Email/Gmail sharing is working; while other app is not, e.g. WeChat (only simple text share is working on WeChat). Has anyone been able to share image on WeChat? Thanks. |
I was having success when the file to share was located on the android external storage. I elected to move my files from an external storage location to the Application Document Directory, located using getApplicationDocumentsDirectory(). I did this so I can deploy to iOS which does not allow access to external storage. I can write the file to:
/data/user/0/com.PlantListGPSv1.Android.PlantListGPSv1/app_flutter/Backup/Backup 2020-08-12@20_18.pgps
placing the above full path into a string variable _fullPathName, and running the code below,
///
print('Full path name: $_fullPathName');
FlutterShare.shareFile(
title: _fileName,
text: 'Plant List GPS File:' + _fileName,
filePath: _fullPathName,
);
///
I get a debug console message and this error message
Full path name: /data/user/0/com.PlantListGPSv1.Android.PlantListGPSv1/app_flutter/Backup/Backup 2020-08-12@20_18.pgps
Exception has occurred.
PlatformException (PlatformException(Failed to find configured root that contains /data/data/com.PlantListGPSv1.Android.PlantListGPSv1/app_flutter/Backup/Backup 2020-08-12@20_18.pgps, null, null))
====
In trying to troubleshoot what FutterShare stopped working I find that my code runs without problem on iOS which has me thinking something changed with Android. I currently have an app working on Google play, build at the end of July with Android 28. After this post, I moved to Android 29 and I can remember when exactly things started breaking, but was soon after I started working in Android 29. I found that my permission-handler plugin went from permission_handler: '^4.2.0+hotfix.2' to permission_handler: ^5.0.1+1 which was a major change. I suspect internal storage, external storage, shared storage(new?) has changed too and could be the root cause of why the flutter_share stopped working with the path provide by getApplicationDocumentsDirectory. I offer this insight to help other to thing in this direction if a cause has not yet been found.
I have developed a work-around as sharing files is important to my app. In a high level, my app reads from the ApplicationDocumentDirectory and writes the file to ExternalStorageDirectory when flutter_share works. Below is an extract of my code that is working for me. I have logged a provider error message that I do not understand, but since flutter_share works, I'm not sure how relevant the exception is, and would appreciate any help in resolving it.
Future getShareFileFullPath(String _subDir, String _fileName) async {
String _fullPathName, _rootDir, _storagePermission;
Io.Directory _storDir;
if (Platform.isAndroid) {
// work around FlutterShare not able to read App Doc Dir
// get file to re-write to external Storage
_storDir = await getApplicationDocumentsDirectory();
_rootDir = _storDir.toString();
_fullPathName =
_rootDir.substring(12, _rootDir.length - 1) + _subDir + _fileName;
print('$_fullPathName');
final _myFile = new Io.File(_fullPathName);
final String _fileData = await _myFile.readAsString(); // have file read
//
// write file to external storage so it can be shared
_storagePermission = await _iOX.askStoragePermission();
print('Storage permission: $_storagePermission');
var _path = await ExtStorage.getExternalStorageDirectory();
_subDir = 'Test';
final String _plgpsDirPath = _path + '/$_subDir/';
Io.Directory(_plgpsDirPath)
.create(recursive: true)
.then((Io.Directory directory) {});
final String _fullPathFileName = _plgpsDirPath + _fileName;
new File(_fullPathFileName).writeAsString(_fileData);
print('File written to:\n$_fullPathFileName');
return _fullPathFileName;
}
// iOS and other OS routine
else {
Io.Directory _storDir = await getApplicationDocumentsDirectory();
_rootDir = _storDir.toString();
_fullPathName = _rootDir.substring(0, _rootDir.length - 1) +
_subDir +
"/" +
_fileName;
print('$_fullPathName');
return _fullPathName;
}
}
AndroidManifest.xml highlights
I'm not sure about the following error message. The share process powers through the Permission denied exception. I suspect sharing between routines is not happening, but not familiar enough with the topic to know the issue. Maybe someone who knows can chime in to help with the reported issue. Thanks.
Debug Console:
I/flutter (23897): /data/user/0/com.PlantListGPSv1.Android.PlantListGPSv1/app_flutter/Backup/Backup 2020-08-14@21_14.pgps
I/flutter (23897): Storage permission: Ok
I/flutter (23897): File written to:
I/flutter (23897): /storage/emulated/0/Test/Backup 2020-08-14@21_14.pgps
I/flutter (23897): Find file at:
I/flutter (23897): /storage/emulated/0/Test/Backup 2020-08-14@21_14.pgps
I/.PlantListGPSv(23897): NativeAlloc concurrent copying GC freed 7847(424KB) AllocSpace objects, 0(0B) LOS objects, 49% free, 1589KB/3179KB, paused 44.346ms total 466.370ms
E/DatabaseUtils(23897): Writing exception to parcel
E/DatabaseUtils(23897): java.lang.SecurityException: Permission Denial: reading androidx.core.content.FileProvider uri content://com.PlantListGPSv1.Android.PlantListGPSv1.provider/external_files/Test/Backup%202020-08-14%4021_14.pgps from pid=21487, uid=1000 requires the provider be exported, or grantUriPermission()
E/DatabaseUtils(23897): at android.content.ContentProvider.enforceReadPermissionInner(ContentProvider.java:729)
E/DatabaseUtils(23897): at android.content.ContentProvider$Transport.enforceReadPermission(ContentProvider.java:602)
E/DatabaseUtils(23897): at android.content.ContentProvider$Transport.query(ContentProvider.java:231)
E/DatabaseUtils(23897): at android.content.ContentProviderNative.onTransact(ContentProviderNative.java:104)
E/DatabaseUtils(23897): at android.os.Binder.execTransactInternal(Binder.java:1021)
E/DatabaseUtils(23897): at android.os.Binder.execTransact(Binder.java:994)
The text was updated successfully, but these errors were encountered: