Skip to content
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

Missing Bytes #616

Closed
1 task done
cranst0n opened this issue Feb 19, 2021 · 20 comments
Closed
1 task done

Missing Bytes #616

cranst0n opened this issue Feb 19, 2021 · 20 comments
Labels
android Issue applies to Android platform bug Something isn't working fixed Issue has been addressed and already been deployed or waiting to deploy on master.

Comments

@cranst0n
Copy link

Using 3.0.0-nullsafety.2

Describe the bug
When picking a file with withData set to true, the result has no bytes on the first pick (i.e. when permission is asked for and granted). Subsequent calls return a file with the expected bytes.

Platform

  • Android
  • [] iOS
  • [] Web
  • [] Desktop (Go)

Platform OS version
Android 11

How are you picking?

final result = await FilePicker.platform.pickFiles(
  allowedExtensions: ['gug'],
  type: FileType.custom,
  withData: true,
);

Details to reproduce the issue
Only seems to be an issue on first call.

Error Log
No apparent errors or meaningful output.

Flutter Version details

[✓] Flutter (Channel dev, 1.27.0-4.0.pre, on Linux, locale en_US.UTF-8)
    • Flutter version 1.27.0-4.0.pre at /opt/flutter
    • Framework revision f8cd24de95 (2 days ago), 2021-02-16 11:24:17 -0800
    • Engine revision 1d537824d6
    • Dart version 2.13.0 (build 2.13.0-30.0.dev)

[!] Android toolchain - develop for Android devices (Android SDK version 29.0.2)
    • Android SDK at /home/cranston/Android/Sdk
    • Platform android-29, build-tools 29.0.2
    • Java binary at: /opt/android-studio/jre/bin/java
    • Java version OpenJDK Runtime Environment (build 1.8.0_242-release-1644-b3-6222593)
    ✗ Android license status unknown.
      Run `flutter doctor --android-licenses` to accept the SDK licenses.
      See https://flutter.dev/docs/get-started/install/linux#android-setup for more details.
@cranst0n cranst0n added the new issue An issue that hasn't yet been seen from the maintainer label Feb 19, 2021
@miguelpruivo miguelpruivo added android Issue applies to Android platform bug Something isn't working and removed new issue An issue that hasn't yet been seen from the maintainer labels Feb 19, 2021
@cranst0n
Copy link
Author

Update. If I wrap my FilePicker.platform.pickFiles call with a call to request storage permissions using the permission_handler package, this issue seems to go away:

if (await Permission.storage.request().isGranted) {
  // Call FilePicker.platform.pickFiles in here
}

@miguelpruivo
Copy link
Owner

@cranst0n oddly permissions are being asked before launching the picker itself which isn't launched unless the permissions are actually conceded.

I'll close this for now, but reopen if anyone else experiences the same.

Thank you!

@cranst0n
Copy link
Author

cranst0n commented Mar 3, 2021

@miguelpruivo I meant to post another update but must've slipped my mind. My last comment doesn't seem to be true, I must have not tracked my situation properly. I'm still hitting this issue.

@miguelpruivo
Copy link
Owner

@cranst0n weird then. By looking at Android's source everything is being done properly. One cannot access file explorer without first allowing access to the content. I don't really get why you can only access it on the second access though.

Which Android version are you trying on?

@cranst0n
Copy link
Author

cranst0n commented Mar 3, 2021

Android 11. I'll try again to recreate the issue next time I'm in front of a computer.

@cranst0n
Copy link
Author

cranst0n commented Mar 4, 2021

@miguelpruivo I've revisited this and can confirm I'm still running into this. I've tried using both local files on the phone, as well as picking files from Google Drive. Picking the file the first time fails to include bytes, in both scenarios and succeeds in subsequent picks.

@miguelpruivo
Copy link
Owner

@cranst0n ill give it a try.

@miguelpruivo miguelpruivo reopened this Mar 5, 2021
@cranst0n
Copy link
Author

cranst0n commented Mar 6, 2021

Just an FYI, running the same code on ios works fine for me.

@KarnerTh
Copy link

I have this problem as well. For me this happens on the first call as well as occasionally without a noticeable pattern.

@cranst0n
Copy link
Author

As a workaround, I added a check to see if the bytes are missing, and then manually read them from the file.

@miguelpruivo
Copy link
Owner

I don't see a reason why this should happen. Looks like those "Android nuances" that can't be properly replicated.

If you manage to replicate this perfectly, please, provide me with a sample so I can work in a fix — or at least, give me the steps.

Thank you.

@altrdev
Copy link

altrdev commented Mar 29, 2021

I have this problem as well. For me this happens on the first call as well as occasionally without a noticeable pattern.

Same here

As a workaround, I added a check to see if the bytes are missing, and then manually read them from the file.

Can you share us this workaround?

@cranst0n
Copy link
Author

@altrdev Something along the lines of what I have below.

final result = await FilePicker.platform.pickFiles(
  withData: true,
);

if ((result.files.single.bytes ?? []).isEmpty) {
  // Special case on Android, the bytes don't seem to come through
  // on the first picker call

  final file = File.fromUri(Uri.parse(result.files.single.path!));
  final fileBytes = file.readAsBytesSync();

  // Work with fileBytes...
}

@altrdev
Copy link

altrdev commented Apr 2, 2021

thanks @cranst0n . I do others test and my issue is slightly different.

Picking the file the first time fails to include some bytes. So in my case result.files.single.bytes is not empty but wrong and the file (pdf in my tests) is unreadable.
For now I always read the bytes from the file like your snippet

final file = File.fromUri(Uri.parse(result.files.single.path!));
final fileBytes = file.readAsBytesSync();

@davidlawson
Copy link

So in my case result.files.single.bytes is not empty but wrong and the file (pdf in my tests) is unreadable.

found this on Android as well

@miguelpruivo
Copy link
Owner

This is quite interesting. I suspect that it could be something related with the data codec when transporting data through the platform channel, since the file should be properly read on the Android end.

Could someone please provide a replicable example, since it’s not easy to replicate this edge cases? Or at least, if you’re experiencing it, debug it on your end by checking the bytes on the Android side and then on Flutter’s so we can further investigate?

Thank you.

@wellbranding
Copy link

wellbranding commented May 22, 2021

Also, experience the same issue. Only for the first time after permission was asked.

@miguelpruivo
Copy link
Owner

Please, provide me with the steps to reproduce this so I can easily try to implement a fix.

@gabrielginter
Copy link

gabrielginter commented Jun 12, 2021

This is happening to me as well, here is some code and information:

Try to reproduce this using the following code AND the steps:

CODE:

FilePickerResult result = await FilePicker.platform.pickFiles(
  type: FileType.image,
  allowCompression: false,
  allowMultiple: true,
  withData: true,
);

if (result == null || result.count == 0) return;

var cnt = 0;
for (var asset in result.files) {
  cnt++;
  var imageData = asset.bytes;

  print('imageData.lengthInBytes $cnt: ${imageData.lengthInBytes}');
}

STEPS

  1. Locate a PNG image in your phone before running the code
  2. Get how many bytes is before and write it down
  3. Run the code and pick the image
  4. Compare the length of the bytes

The byte length will be different.

I clarify to follow these steps, because, it seems that this happens the first time you pick the image that you never picked before, sometimes even the second time, but eventually it will read the image completely, and once it does return all the bytes it will return them every time, and then you need to file a new fie. It happens to me every single time with PNG images, I would recommend testing it with newly created screenshots.

The only consistent message in the console when this happens is:

W/System (19344): A resource failed to call close.

But I don't know if it's related or not.

Flutter doctor:

[√] Flutter (Channel stable, 2.2.1, on Microsoft Windows [Version 10.0.19042.1052], locale en-US)
[√] Android toolchain - develop for Android devices (Android SDK version 30.0.3)
[√] Chrome - develop for the web
[√] Android Studio (version 4.1.0)
[√] Connected device (3 available)

Device: Pixel 3XL Android 11

If you require more information, let me know :)

@miguelpruivo
Copy link
Owner

Ok, I was able to replicate this and there was a minor optimisation that could be done and hence prevent this issue.

The fix will be deployed today.

@miguelpruivo miguelpruivo added fixed Issue has been addressed and already been deployed or waiting to deploy on master. bug Something isn't working and removed bug Something isn't working labels Jun 22, 2021
@GeertJohan GeertJohan mentioned this issue Jul 4, 2021
4 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
android Issue applies to Android platform bug Something isn't working fixed Issue has been addressed and already been deployed or waiting to deploy on master.
Projects
None yet
Development

No branches or pull requests

7 participants