Skip to content

Android image_picker crashes when non-image file selected #40233

@buntagonalprism

Description

@buntagonalprism

When using ImagePicker.pickImage on Android it is possible to launch into external apps to select a file. Some of these external apps, including Microsoft OneDrive and Google Drive, do not respect the image/* mime type filter, allowing the user to pick a file that is not an image. Doing so crashes the flutter app.

Flutter obviously shouldn't be responsible for the behaviour of these file providers, but it would be good to have this situation handled elegantly by the plugin. Preferably with an error that could be caught in the Flutter application so that a message could be shown to the user.

Steps to Reproduce

  1. Using: image_picker: ^0.6.1+4. Tested on Galaxy S10+
  2. Launch ImagePicker.pickImage(source: ImageSource.gallery). Minimal sample app:
import 'package:flutter/material.dart';
import 'package:image_picker/image_picker.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: Scaffold(
        appBar: AppBar(),
        body: Center(
          child: RaisedButton.icon(
            icon: Icon(Icons.camera_alt),
            label: Text('Pick Image'),
            onPressed: () async {
              final file = await ImagePicker.pickImage(source: ImageSource.gallery);
              print(file.path);
            }
          ),
        ),
      )
    );
  }
}
  1. Open the side menu and select to launch a different file provider app, like Google Drive or Microsoft OneDrive
  • Selecting any of the file sources in the black box below results in the files from that provider being displayed within the Android native file picking window. This window does correctly prevent selection of non-image files, so there is no issue.
  • However, selecting a file source from the red box launches the selected app directly to pick the file. This is where choosing Google Drive or Microsoft OneDrive will result in the image/* restriction being ignored.
    SmartSelect_20190911-170322_Files
  1. Select a non-image type file. E.g. a markdown file from Google Drive. The flutter application crashes.
    SmartSelect_20190911-171151_Drive

Logs

Logs from flutter run including exception

[        ] Connected to _flutterView/0x71f427af20.
[   +2 ms] �  To hot reload changes while running, press "r". To hot restart (and rebuild state), press "R".
[   +2 ms] An Observatory debugger and profiler on SM G975F is available at: http://127.0.0.1:60020/Ye6dFqZSHkY=/
[        ] For a more detailed help message, press "h". To detach, press "d"; to quit, press "q".
[+3213 ms] D/ViewRootImpl@30dbb01[MainActivity](13647): ViewPostIme pointer 0
[  +54 ms] D/ViewRootImpl@30dbb01[MainActivity](13647): ViewPostIme pointer 1
[  +62 ms] D/ViewRootImpl@30dbb01[MainActivity](13647): MSG_WINDOW_FOCUS_CHANGED 0 1
[        ] D/InputMethodManager(13647): prepareNavigationBarInfo() DecorView@30a6393[MainActivity]
[        ] D/InputMethodManager(13647): getNavigationBarColor() -855310
[ +308 ms] D/InputTransport(13647): Input channel destroyed: fd=95
[  +60 ms] D/SurfaceView(13647): onWindowVisibilityChanged(8) false io.flutter.view.FlutterView{48b1b94 VFE...... ........ 0,0-1080,2154} of ViewRootImpl@30dbb01[MainActivity]
[   +1 ms] D/SurfaceView(13647): show() Surface(name=SurfaceView - com.buntagon.image_pick_failure/com.buntagon.image_pick_failure.MainActivity@48b1b94@0[13647])/@0xa1a063d io.flutter.view.FlutterView{48b1b94 VFE...... ........ 0,0-1080,2154}
[   +9 ms] D/SurfaceView(13647): surfaceDestroyed callback.size 1 #2 io.flutter.view.FlutterView{48b1b94 VFE...... ........ 0,0-1080,2154}
[   +2 ms] W/libEGL  (13647): EGLNativeWindowType 0x71d3e77010 disconnect failed
[        ] D/SurfaceView(13647): destroy() Surface(name=SurfaceView - com.buntagon.image_pick_failure/com.buntagon.image_pick_failure.MainActivity@48b1b94@0[13647])/@0xa1a063d io.flutter.view.FlutterView{48b1b94 VFE...... ........ 0,0-1080,2154}
[        ] W/libEGL  (13647): EGLNativeWindowType 0x71d3e76010 disconnect failed
[        ] D/OpenGLRenderer(13647): eglDestroySurface = 0x71edceb800, 0x71d3e76000
[  +15 ms] D/ViewRootImpl@30dbb01[MainActivity](13647): Relayout returned: old=[0,0][1080,2280] new=[0,0][1080,2280] result=0x5 surface={valid=false 0} changed=true
[   +4 ms] D/ViewRootImpl@30dbb01[MainActivity](13647): setWindowStopped(true) old=false
[        ] D/SurfaceView(13647): windowStopped(true) false io.flutter.view.FlutterView{48b1b94 VFE...... ........ 0,0-1080,2154} of ViewRootImpl@30dbb01[MainActivity]
[   +1 ms] D/ViewRootImpl@30dbb01[MainActivity](13647): Surface release. android.view.WindowManagerGlobal.setStoppedState:669 android.app.Activity.performStop:7650 android.app.ActivityThread.callActivityOnStop:4378
android.app.ActivityThread.performStopActivityInner:4356 android.app.ActivityThread.handleStopActivity:4431 android.app.servertransaction.StopActivityItem.execute:41 android.app.servertransaction.TransactionExecutor.executeLifecycleState:145
android.app.servertransaction.TransactionExecutor.execute:70
[+8034 ms] D/SurfaceView(13647): onWindowVisibilityChanged(4) false io.flutter.view.FlutterView{48b1b94 VFE...... ........ 0,0-1080,2154} of ViewRootImpl@30dbb01[MainActivity]
[   +1 ms] D/ViewRootImpl@30dbb01[MainActivity](13647): Relayout returned: old=[0,0][1080,2280] new=[0,0][1080,2280] result=0x1 surface={valid=false 0} changed=false
[ +548 ms] D/skia    (13647): --- Failed to create image decoder with message 'unimplemented'
[   +1 ms] D/AndroidRuntime(13647): Shutting down VM
[        ] E/AndroidRuntime(13647): FATAL EXCEPTION: main
[        ] E/AndroidRuntime(13647): Process: com.buntagon.image_pick_failure, PID: 13647
[        ] E/AndroidRuntime(13647): java.lang.RuntimeException: Failure delivering result ResultInfo{who=null, request=2342, result=-1, data=Intent { act=android.intent.action.VIEW
dat=content://com.google.android.apps.docs.storage.legacy/enc=TArrOdHjdu0KBanoTM4i_vmVWthVLEGGE9zKprXizkaxwDW1nePWL80GLvN_a5ewzDmP3x_CZtSG
[   +1 ms] E/AndroidRuntime(13647): nzuBAiSadZhQFY0QWmeSDvAvDTuKGpRnojrFEb2SZzcdfGn5UCXT46Hr5Q==
[   +3 ms] E/AndroidRuntime(13647):  (has extras) }} to activity {com.buntagon.image_pick_failure/com.buntagon.image_pick_failure.MainActivity}: java.lang.NullPointerException: Attempt to invoke virtual method 'int android.graphics.Bitmap.getWidth()' on a null
object reference
[   +1 ms] E/AndroidRuntime(13647):     at android.app.ActivityThread.deliverResults(ActivityThread.java:4609)
[   +1 ms] E/AndroidRuntime(13647):     at android.app.ActivityThread.handleSendResult(ActivityThread.java:4651)
[        ] E/AndroidRuntime(13647):     at android.app.servertransaction.ActivityResultItem.execute(ActivityResultItem.java:49)
[        ] E/AndroidRuntime(13647):     at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:108)
[        ] E/AndroidRuntime(13647):     at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:68)
[        ] E/AndroidRuntime(13647):     at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1947)
[        ] E/AndroidRuntime(13647):     at android.os.Handler.dispatchMessage(Handler.java:106)
[        ] E/AndroidRuntime(13647):     at android.os.Looper.loop(Looper.java:214)
[        ] E/AndroidRuntime(13647):     at android.app.ActivityThread.main(ActivityThread.java:7037)
[        ] E/AndroidRuntime(13647):     at java.lang.reflect.Method.invoke(Native Method)
[        ] E/AndroidRuntime(13647):     at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:494)
[        ] E/AndroidRuntime(13647):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:965)
[        ] E/AndroidRuntime(13647): Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'int android.graphics.Bitmap.getWidth()' on a null object reference
[        ] E/AndroidRuntime(13647):     at io.flutter.plugins.imagepicker.ImageResizer.resizedImage(ImageResizer.java:52)
[        ] E/AndroidRuntime(13647):     at io.flutter.plugins.imagepicker.ImageResizer.resizeImageIfNeeded(ImageResizer.java:40)
[        ] E/AndroidRuntime(13647):     at io.flutter.plugins.imagepicker.ImagePickerDelegate.handleImageResult(ImagePickerDelegate.java:530)
[        ] E/AndroidRuntime(13647):     at io.flutter.plugins.imagepicker.ImagePickerDelegate.handleChooseImageResult(ImagePickerDelegate.java:463)
[        ] E/AndroidRuntime(13647):     at io.flutter.plugins.imagepicker.ImagePickerDelegate.onActivityResult(ImagePickerDelegate.java:442)
[        ] E/AndroidRuntime(13647):     at io.flutter.app.FlutterPluginRegistry.onActivityResult(FlutterPluginRegistry.java:204)
[        ] E/AndroidRuntime(13647):     at io.flutter.app.FlutterActivityDelegate.onActivityResult(FlutterActivityDelegate.java:132)
[        ] E/AndroidRuntime(13647):     at io.flutter.app.FlutterActivity.onActivityResult(FlutterActivity.java:142)
[        ] E/AndroidRuntime(13647):     at android.app.Activity.dispatchActivityResult(Activity.java:7762)
[   +1 ms] E/AndroidRuntime(13647):     at android.app.ActivityThread.deliverResults(ActivityThread.java:4602)
[        ] E/AndroidRuntime(13647):     ... 11 more
[        ] I/Process (13647): Sending signal. PID: 13647 SIG: 9
[  +90 ms] Service protocol connection closed.
[   +1 ms] Lost connection to device.
[   +2 ms] DevFS: Deleting filesystem on the device (file:///data/user/0/com.buntagon.image_pick_failure/code_cache/image_pick_failureNAIRNV/image_pick_failure/)
[        ] Sending to VM service: _deleteDevFS({fsName: image_pick_failure})
[ +252 ms] Ignored error while cleaning up DevFS: TimeoutException after 0:00:00.250000: Future not completed
[   +2 ms] "flutter run" took 44,098ms.

Flutter analyze

flutter analyze
Analyzing image_pick_failure...
No issues found! (ran in 2.5s)

Flutter Doctor

flutter doctor -v
[√] Flutter (Channel stable, v1.9.1+hotfix.2, on Microsoft Windows [Version 10.0.18362.295], locale en-AU)
    • Flutter version 1.9.1+hotfix.2 at C:\flutter
    • Framework revision 2d2a1ffec9 (4 days ago), 2019-09-06 18:39:49 -0700
    • Engine revision b863200c37
    • Dart version 2.5.0


[√] Android toolchain - develop for Android devices (Android SDK version 29.0.0)
    • Android SDK at C:\Users\Alex\AppData\Local\Android\sdk
    • Android NDK location not configured (optional; useful for native profiling support)
    • Platform android-29, build-tools 29.0.0
    • Java binary at: C:\Program Files\Android\Android Studio\jre\bin\java
    • Java version OpenJDK Runtime Environment (build 1.8.0_152-release-1343-b01)
    • All Android licenses accepted.

[√] Android Studio (version 3.4)
    • Android Studio at C:\Program Files\Android\Android Studio
    • Flutter plugin version 38.1.1
    • Dart plugin version 183.6270
    • Java version OpenJDK Runtime Environment (build 1.8.0_152-release-1343-b01)

[√] VS Code (version 1.37.1)
    • VS Code at C:\Users\Alex\AppData\Local\Programs\Microsoft VS Code
    • Flutter extension version 3.3.0

[√] Connected device (1 available)
    • SM G975F • R58M20N3HSM • android-arm64 • Android 9 (API 28)

• No issues found!

Metadata

Metadata

Assignees

No one assigned

    Labels

    c: new featureNothing broken; request for a new capabilityc: proposalA detailed proposal for a change to Fluttercustomer: quill (g3)p: image_pickerThe Image Picker plugin.packageflutter/packages repository. See also p: labels.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions