androidflutterpathillegalargumentexceptionfile-sharing

Why is the flutter share_plus package giving this IllegalArgumentException?


I am writing a function that essentially gets data from an http request as a byte array, then writes it to a file in the temporary directory in order to share to wherever the user desires. I have successfully gotten this to work on iOS, but for some reason every time I reach the share code on Android I get the following error:

PlatformException(error, Failed to find configured root that contains /storage/emulated/0/Android/data/<bundle-identifier-hidden-here-for-privacy>/cache/share/testfile.pdf, null, java.lang.IllegalArgumentException: Failed to find configured root that contains /storage/emulated/0/Android/data/<bundle-identifier-hidden-here-for-privacy>/cache/share/testfile.pdf

When I print file.path on the file I saved right before I attempt to share, I get this:

/data/user/0/<bundle-identifier-hidden-here-for-privacy>/cache/testfile.pdf

Here is the code itself, it's fairly straightforward. I'm using share_plus(^6.0.1), path_provider(^2.0.11), and http(^0.13.5) (which seems to be irrelevant here beyond being the source of the data):

var res = await http.post(
    Uri.parse(url),
    body: {"document_html": htmlString},
);

var temp = await getTemporaryDirectory();

File file = File("${temp.path}/testfile.pdf");

file = await file.writeAsBytes(res.bodyBytes);

String path = file.absolute.path;
Share.shareFiles([path]).catchError((err) {
    print(err);
}); 

Solution

  • I haven't tested your implementation but recently I needed to implement share plus but using XFile, see:

    import 'package:path_provider/path_provider.dart';
    import 'package:image_picker/image_picker.dart';
    import 'package:screenshot/screenshot.dart';
    import 'package:share_plus/share_plus.dart';
    
    
    IconButton(
          onPressed: () async {
            await widget.screenshotController
                .capture(pixelRatio: 1.5)
                .then((bytes) async {
              final Directory output = await getTemporaryDirectory();
              final String screenshotFilePath = '${output.path}/appName.png';
              final File screenshotFile = File(screenshotFilePath);
              await screenshotFile.writeAsBytes(bytes!);
              Share.shareXFiles(
                [XFile(screenshotFilePath)],
                text:
                    "Text. My invite link:\n$appLink",
                sharePositionOrigin: () {
                  RenderBox? box = context.findRenderObject() as RenderBox?;
                  return box!.localToGlobal(Offset.zero) & box.size;
                }(),
              );
            }).catchError((onError) {
              print(onError);
            });
          },
          icon: const Icon(Icons.share_outlined),
        );