0

My goal is to have a capability in my application to generate a PDF file from a template, and to open it with an external application (Adobe Acrobat Reader for instance) from my application. Once the PDF file is opened in Acrobat Reader, it may be modified by this application. In this case, from my application, I still want to be able to open the latest version of the document. One last info: I don't want to add MANAGE_EXTERNAL_STORAGE because I want my application to be available on Play Store.

In more details, I provide a sample test code her below: It is instantiating a PDF file from a template (available in my 'assets') to the application directory (/storage/emulated/0/Android/data/<my_app>/files). Then, once the file is generated, I use OpenFilex.open() to open it in Acrobat Reader application for instance.

While in Acrobat Reader, if the user modifies the PDF file using Acrobat Reader, the file is saved in Download directory, and not updated in my application local storage.

If I generate the PDF file in Download directory, I cannot open it anymore with OpenFilex.open() (I have a permission denied). If I try and copy the file modified by Acrobat Reader from Download to the application local storage, I have an exception (OS Error: Permission denied, errno = 13).

How can I manage my PDF file to make it available for both my application and for external applications ?

import 'dart:io';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:open_filex/open_filex.dart';


const String FLIGHT_DEBRIEF_DOWNLOAD_DIRECTORY = "/sdcard/Documents/";
const String FLIGHT_DEBRIEF_LOCAL_DIRECTORY = "/storage/emulated/0/Android/data/<my_app>/files/";
const String FLIGHT_DEBRIEF_DEFAULT_TEMPLATE = "defaultTemplate.pdf";
const String FLIGHT_DEBRIEF_DEFAULT_NAME = "myFile";
const String  FLIGHT_DEBRIEF_EXTENSION = "pdf";

void main() => runApp(new MaterialApp(home: new MyApp()));

class MyApp extends StatefulWidget {
  @override
  _MyAppState createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {

  @override
  void initState() {
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: new AppBar(
        title: new Text('Flutter Test file sharing'),
      ),
      body: new Center(
        child: new ElevatedButton(
          onPressed: instantiateDebrief,
          child: new Text(
            'tap to instantiate PDF',
            //style: Theme.of(context).textTheme.headline,
          ),
        ),
      ),
    );
  }

  Future<void> instantiateDebrief() async {
    String _destinationFileName = "";

    _destinationFileName = "$FLIGHT_DEBRIEF_DEFAULT_NAME.$FLIGHT_DEBRIEF_EXTENSION";

    final byteData = await rootBundle.load("assets/documents/" + FLIGHT_DEBRIEF_DEFAULT_TEMPLATE);
    await File(FLIGHT_DEBRIEF_LOCAL_DIRECTORY + _destinationFileName)
        .writeAsBytes(byteData.buffer.asUint8List(byteData.offsetInBytes, byteData.lengthInBytes));

    displayMissionDebrief(context, _destinationFileName);
  }

  Future<void> displayMissionDebrief(BuildContext context, String fileName) async {
    await OpenFilex.open(FLIGHT_DEBRIEF_LOCAL_DIRECTORY + fileName);
  }
}

My flutter doctor output (note that I plan to upgrade to latest flutter 3.10 once I have fixed this issue):

$ flutter doctor -v
[√] Flutter (Channel stable, 3.7.10, on Microsoft Windows [version 10.0.22621.1992], locale fr-FR)
    • Flutter version 3.7.10 on channel stable at C:\src\flutter
    • Upstream repository https://github.com/flutter/flutter.git
    • Framework revision 4b12645012 (4 months ago), 2023-04-03 17:46:48 -0700
    • Engine revision ec975089ac
    • Dart version 2.19.6
    • DevTools version 2.20.1

[X] Windows Version (Unable to confirm if installed Windows version is 10 or greater)

[√] Android toolchain - develop for Android devices (Android SDK version 31.0.0-rc5)
    • Android SDK at C:\Users\chris\AppData\Local\Android\sdk
    • Platform android-33, build-tools 31.0.0-rc5
    • Java binary at: C:\Program Files\Android\Android Studio\jre\bin\java
    • Java version OpenJDK Runtime Environment (build 11.0.12+7-b1504.28-7817840)
    • All Android licenses accepted.

[√] Chrome - develop for the web
    • Chrome at C:\Program Files (x86)\Google\Chrome\Application\chrome.exe

[√] Visual Studio - develop for Windows (Visual Studio Community 2022 17.2.2)
    • Visual Studio at C:\Program Files\Microsoft Visual Studio\2022\Community
    • Visual Studio Community 2022 version 17.2.32519.379
    • Windows 10 SDK version 10.0.19041.0

[√] Android Studio (version 2021.2)
    • Android Studio at C:\Program Files\Android\Android Studio
    • Flutter plugin can be installed from:
       https://plugins.jetbrains.com/plugin/9212-flutter
    • Dart plugin can be installed from:
       https://plugins.jetbrains.com/plugin/6351-dart
    • Java version OpenJDK Runtime Environment (build 11.0.12+7-b1504.28-7817840)

[√] Connected device (4 available)
    • SM S901B (mobile) • R3CT90HPJLR • android-arm64  • Android 13 (API 33)
    • Windows (desktop) • windows     • windows-x64    • Microsoft Windows [version 10.0.22621.1992]
    • Chrome (web)      • chrome      • web-javascript • Google Chrome 115.0.5790.102
    • Edge (web)        • edge        • web-javascript • Microsoft Edge 113.0.1774.42

[√] HTTP Host Availability
    • All required HTTP hosts are available

I have tried using SAF package, or Share_Plus package, but it does not answer my issue. PDF files are still not shareable from Acrobat Reader to my application and vice versa.

0 Answers0