androidflutteriobinary-datauint8list

How to Display File Stored in ORACLE "LONG RAW" Field in Flutter App


I have an Oracle Database that stores binary files like PDF, XLS, JPG etc in a field named FILE_FILE_DATA which is of type LONG RAW

I am required to fetch this data from Oracle and display in my Flutter App.

I am using NodeJS as a server which is successfully able to fetch data and throw it back to flutter thru an http call.

The code and fetched data looks like this:

final data1 = json.decode(value.body)['rtnData'] as List<dynamic>;
final data2 = json.decode(data1[0]);
data = data2[0]['FILE_FILE_DATA']['data'];
debugPrint('data: $data');

data now prints a large array of number like this:

[80, 75, 3, 4, 20, 0, 6, 0, 8, 0, 0, 0, 32, 0, 96, 193, 88, 5, 195, 12, 0, 0, 52, 81, 0, 0, 24, 0, 0, 0, 120, 108, 47, 119, 111, 114, 107, 115, 104, 101, 101, 116, 115, 47, 115, 104, 101, 101, 116, 49, 46, 120, 109, 108, 141, 156, 91, 115, 226, 184, 22, 70, 223, 187, 234, 252, 7, 138, 151, 60, 29, 130, 109, 12, 132, 234, 100]

Can anyone please tell me how to convert this into a local file and dislay using launchUrl()? I have tried the following but on first line I get an exception "type 'Null' is not a subtype of type 'int'"

  Uint8List fileFileData = Uint8List.fromList(data);
  Directory tempDir = await getTemporaryDirectory();
  String path = tempDir.path;

  // Clean up the attachment name (remove spaces)
  String attachmentName = basename(fileName).replaceAll(" ", "");

  // Create a File instance for the output file
  FILE.File file = FILE.File('$path/$attachmentName');
  String localFileName = ('$path/$attachmentName');
  debugPrint('localFileName=$localFileName');
  if (!await file.exists()) {
    await file.create();
  }
  file.writeAsBytesSync(fileFileData);

======Update============

On the very first row:

Uint8List fileFileData = Uint8List.fromList(data);

I get this Exception:

type 'List<dynamic>' is not a subtype of type 'List<int>'

But the data does contain integers only. I have even tried to manually assign data with numbers only i.e. [1, 5, 6, 65,......]


Solution

  • After some research I found out that I need to use cast<int>() which worked. The same has been advised by some of the users in the comments above also which is appreciated.

    I am posting the final solution below in case it helps others:

    var imageData = data2[0]['FILE_FILE_DATA']['data'];
    try {
      final ints = imageData.cast<int>();
      final bytes = Uint8List.fromList(ints);
      Directory? tempDir = await getDownloadsDirectory();
      String path = tempDir!.path;
    
      // Create a File instance for the output file
      FILE.File file = FILE.File('$path/$attachmentName');
      await file.writeAsBytes(bytes);
    
      String localFileName = ('$path/$attachmentName');
      await OpenFile.open(localFileName);
    } catch (e) {
      debugPrint('----error--$e');
    }
    

    In order to use Openfile.open() you also need to add the following in your AndroidManifest.xml

    <application>
        <provider
            android:name="androidx.core.content.FileProvider"
            android:authorities="com.example.myapp.fileprovider"
            android:grantUriPermissions="true"
            android:exported="false">
            <meta-data
                android:name="android.support.FILE_PROVIDER_PATHS"
                android:resource="@xml/filepaths" />
        </provider>
    </application>