首页 > 解决方案 > Flutter:尝试从图库或相机中选择图像时,Image_Picker 使应用程序崩溃

问题描述

尝试在我的社交媒体应用上上传图片时,它总是崩溃。它已经 2 个月试图解决这个问题。最初我使用的是带有弃用警告的旧颤振代码。我现在已经将应用程序迁移到 AndroidX,希望能解决这个问题,但在你甚至无法拍摄应用程序崩溃的图像之前,它仍然无法打开选择图像选项。

颤振医生

[√] Flutter (Channel dev, 1.24.0-10.2.pre, on Microsoft Windows [Version 10.0.19041.630], locale en-GB)
    • Flutter version 1.24.0-10.2.pre at C:\Flutter
    • Framework revision 022b333a08 (5 days ago), 2020-11-18 11:35:09 -0800
    • Engine revision 07c1eed46b
    • Dart version 2.12.0 (build 2.12.0-29.10.beta)

[√] Android toolchain - develop for Android devices (Android SDK version 30.0.2)
    • Android SDK at F:\Android\SDKs
    • Platform android-30, build-tools 30.0.2
    • ANDROID_HOME = F:\Android\SDKs
    • Java binary at: C:\Program Files\Android\Android Studio1\jre\bin\java
    • Java version OpenJDK Runtime Environment (build 1.8.0_242-release-1644-b01)
    • All Android licenses accepted.

[√] Android Studio (version 4.1.0)
    • Android Studio at C:\Program Files\Android\Android Studio1
    • 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 1.8.0_242-release-1644-b01)

[√] VS Code (version 1.51.1)
    • VS Code at C:\Users\ACEHOME\AppData\Local\Programs\Microsoft VS Code
    • Flutter extension version 3.16.0

[√] Connected device (1 available)
    • DRA LX5 (mobile) • VUY9K20409902290 • android-arm • Android 8.1.0 (API 27)

• No issues found!

调试控制台错误:从应用程序崩溃的地方开始

I/flutter (14332): Firebase Messaging Token: dI1-F5iKBVA:APA91bHJE6Yk91vcEv3BX0h2A2KaNZMWvEALwrqYRzZ-ZoihIste67XLiwnf72OPcbvWfLm7tm4ScD8c2CzOvsiqOG7IZMd5aPfOcULEDCLrUbgJ_rFxoSE0kIQhxdpXcqMFWMp4G4E0
I/flutter (14332): Firebase Messaging Token: dI1-F5iKBVA:APA91bHJE6Yk91vcEv3BX0h2A2KaNZMWvEALwrqYRzZ-ZoihIste67XLiwnf72OPcbvWfLm7tm4ScD8c2CzOvsiqOG7IZMd5aPfOcULEDCLrUbgJ_rFxoSE0kIQhxdpXcqMFWMp4G4E0
V/jhw     (14332): call Intent.migrateExtraStreamToClipData(1)
D/Surface (14332): Surface::disconnect(this=0x903be000,api=1)
D/Surface (14332): Surface::disconnect(this=0x903be000,api=-1)
D/Surface (14332): Surface::disconnect(this=0x903a3000,api=1)
W/ThreadedRenderer(14332): ThreadedRenderer::detachAnimators pid = 14332 threadid = 14474
V/PhoneWindow(14332): DecorView setVisiblity: visibility = 4, Parent = ViewRoot{d76c32d com.finde.med/com.finde.med.MainActivity,ident = 0}, this = DecorView@8723b57[MainActivity]
W/ThreadedRenderer(14332): ThreadedRenderer::detachAnimators pid = 14332 threadid = 14474

W/ConnectionTracker(14332): Exception thrown while unbinding
W/ConnectionTracker(14332): java.lang.IllegalArgumentException: Service not registered: lp@5595c0d
W/ConnectionTracker(14332):     at android.app.LoadedApk.forgetServiceDispatcher(LoadedApk.java:1556)
W/ConnectionTracker(14332):     at android.app.ContextImpl.unbindService(ContextImpl.java:1642)
W/ConnectionTracker(14332):     at android.content.ContextWrapper.unbindService(ContextWrapper.java:703)
W/ConnectionTracker(14332):     at ci.f(:com.google.android.gms.dynamite_measurementdynamite@204217128@20.42.17 (110306-0):1)
W/ConnectionTracker(14332):     at ci.d(:com.google.android.gms.dynamite_measurementdynamite@204217128@20.42.17 (110306-0):2)
W/ConnectionTracker(14332):     at lq.D(:com.google.android.gms.dynamite_measurementdynamite@204217128@20.42.17 (110306-0):10)
W/ConnectionTracker(14332):     at lc.a(:com.google.android.gms.dynamite_measurementdynamite@204217128@20.42.17 (110306-0):2)
W/ConnectionTracker(14332):     at ee.run(:com.google.android.gms.dynamite_measurementdynamite@204217128@20.42.17 (110306-0):3)
W/ConnectionTracker(14332):     at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:457)
W/ConnectionTracker(14332):     at java.util.concurrent.FutureTask.run(FutureTask.java:266)
W/ConnectionTracker(14332):     at ix.run(:com.google.android.gms.dynamite_measurementdynamite@204217128@20.42.17 (110306-0):6)
Lost connection to device.
Exited (sigterm)

上传页面代码

import 'dart:io';

import 'package:cached_network_image/cached_network_image.dart';
import 'package:firebase_storage/firebase_storage.dart';
import 'package:flutter/material.dart';
import 'package:flutter_svg/svg.dart';
import 'package:findemed/models/user.dart';
import 'package:findemed/pages/home.dart';
import 'package:findemed/widgets/progress.dart';
import 'package:geolocator/geolocator.dart';
import 'package:image_picker/image_picker.dart';
import 'package:path_provider/path_provider.dart';
import 'package:image/image.dart' as Im;
import 'package:uuid/uuid.dart';

class Upload extends StatefulWidget {
  final User currentUser;

  Upload({this.currentUser});

  @override
  _UploadState createState() => _UploadState();
}

class _UploadState extends State<Upload>
    with AutomaticKeepAliveClientMixin<Upload> {
  TextEditingController captionController = TextEditingController();
  TextEditingController locationController = TextEditingController();
  File file;
  bool isUploading = false;
  String postId = Uuid().v4();

  handleTakePhoto() async {
    final _picker = ImagePicker();
    PickedFile image;

    Navigator.pop(context);
    // File file 
    image = await _picker.getImage(
      source: ImageSource.camera,
      maxHeight: 675,
      maxWidth: 960,
    );
    setState(() {
      this.file = File(image.path);
    });
  }

  handleChooseFromGallery() async {
    final _picker = ImagePicker();
    PickedFile image;

    Navigator.pop(context);
    // File file (removed)
    image = await _picker.getImage(
      source: ImageSource.gallery,
      );
    setState(() {
      this.file = File(image.path);
    });
  }

  selectImage(parentContext) {
    return showDialog(
      context: parentContext,
      builder: (context) {
        return SimpleDialog(
          title: Text("Create Post"),
          children: <Widget>[
            SimpleDialogOption(
                child: Text("Photo with Camera"), 
                onPressed: handleTakePhoto
                ),
            SimpleDialogOption(
                child: Text("Image from Gallery"),
                onPressed: handleChooseFromGallery
                ),
            SimpleDialogOption(
              child: Text("Cancel"),
              onPressed: () => Navigator.pop(context),
            )
          ],
        );
      },
    );
  }

  

  Container buildSplashScreen() {
    return Container(
      color: Theme.of(context).primaryColor.withOpacity(0.6),
      child: Column(
        mainAxisAlignment: MainAxisAlignment.center,
        children: <Widget>[
          SvgPicture.asset('assets/images/upload.svg', height: 170.0),
          Padding(
            padding: EdgeInsets.only(top: 50.0),
            child: RaisedButton(
                shape: RoundedRectangleBorder(
                  borderRadius: BorderRadius.circular(15.0),
                ),
                child: Text(
                  "Upload Image",
                  style: TextStyle(
                    color: Colors.white,
                    fontSize: 16.0,
                  ),
                ),
                color: Theme.of(context).accentColor,
                onPressed: () => selectImage(context)),
          ),
        ],
      ),
    );
  } 

  clearImage() {
    setState(() {
      file = null;
    });
  }

  compressImage() async {
    final tempDir = await getTemporaryDirectory();
    final path = tempDir.path;
    Im.Image imageFile = Im.decodeImage(file.readAsBytesSync());
    final compressedImageFile = File('$path/img_$postId.jpg')
      ..writeAsBytesSync(Im.encodeJpg(imageFile, quality: 85));
    setState(() {
      file = compressedImageFile;
    });
  }

  Future<String> uploadImage(imageFile) async {
    StorageUploadTask uploadTask =
        storageRef
        .child("post_$postId.jpg")
        .putFile(imageFile);
    StorageTaskSnapshot storageSnap = await uploadTask
        .onComplete;
    String downloadUrl = await storageSnap.ref
        .getDownloadURL();
   return downloadUrl;

  }

  createPostInFirestore(
      {String mediaUrl, String location, String description}) {
    postsRef
        .doc(widget.currentUser.id)
        .collection("userPosts")
        .doc(postId)
        .set({
      "postId": postId,
      "ownerId": widget.currentUser.id,
      "username": widget.currentUser.username,
      "mediaUrl": mediaUrl,
      "description": description,
      "location": location,
      "timestamp": timestamp,
      "likes": {},
    });
  }

  handleSubmit() async {
    setState(() {
      isUploading = true;
    });
    await compressImage();
    String mediaUrl = await uploadImage(file);
    createPostInFirestore(
      mediaUrl: mediaUrl,
      location: locationController.text,
      description: captionController.text,
    );
    captionController.clear();
    locationController.clear();
    setState(() {
      file = null;
      isUploading = false;
      postId = Uuid().v4();
    });
  }

  Scaffold buildUploadForm() {
    return Scaffold(
      appBar: AppBar(
        backgroundColor: Colors.white70,
        leading: IconButton(
            icon: Icon(Icons.arrow_back, color: Colors.black),
            onPressed: clearImage),
        title: Text(
          "Caption Post",
          style: TextStyle(color: Colors.black),
        ),
        actions: [
          FlatButton(
            onPressed: isUploading ? null : () => handleSubmit(),
            child: Text(
              "Post",
              style: TextStyle(
                color: Theme.of(context).accentColor,
                fontWeight: FontWeight.bold,
                fontSize: 20.0,
              ),
            ),
          ),
        ],
      ),
      body: ListView(
        children: <Widget>[
          isUploading ? linearProgress(context) : Text(""),
          Container(
            height: 220.0,
            width: MediaQuery.of(context).size.width * 0.8,
            child: Center(
              child: AspectRatio(
                aspectRatio: 16 / 9,
                child: Container(
                  decoration: BoxDecoration(
                    image: DecorationImage(
                      fit: BoxFit.cover,
                      image: FileImage(file),
                    ),
                  ),
                ),
              ),
            ),
          ),
          Padding(
            padding: EdgeInsets.only(top: 10.0),
          ),
          ListTile(
            leading: CircleAvatar(
              backgroundImage:
                  CachedNetworkImageProvider(widget.currentUser.photoUrl),
            ),
            title: Container(
              width: 250.0,
              child: TextField(
                controller: captionController,
                decoration: InputDecoration(
                  hintText: "Write a caption...",
                  border: InputBorder.none,
                ),
              ),
            ),
          ),
          Divider(),
          ListTile(
            leading: Icon(
              Icons.pin_drop,
              color: Theme.of(context).accentColor,
              size: 35.0,
            ),
            title: Container(
              width: 250.0,
              child: TextField(
                controller: locationController,
                decoration: InputDecoration(
                  hintText: "Where was this photo taken?",
                  border: InputBorder.none,
                ),
              ),
            ),
          ),
          Container(
            width: 200.0,
            height: 100.0,
            alignment: Alignment.center,
            child: RaisedButton.icon(
              label: Text(
                "Use Current Location",
                style: TextStyle(color: Colors.white),
              ),
              shape: RoundedRectangleBorder(
                borderRadius: BorderRadius.circular(30.0),
              ),
              color: Theme.of(context).accentColor,
              onPressed: getUserLocation,
              icon: Icon(
                Icons.my_location,
                color: Colors.white,
              ),
            ),
          ),
        ],
      ),
    );
  }

  getUserLocation() async {
    Position position = await Geolocator()
        .getCurrentPosition(desiredAccuracy: LocationAccuracy.high);
    List<Placemark> placemarks = await Geolocator()
        .placemarkFromCoordinates(position.latitude, position.longitude);
    Placemark placemark = placemarks[0];
    String completeAddress =
        '${placemark.subThoroughfare} ${placemark.thoroughfare}, ${placemark.subLocality} ${placemark.locality}, ${placemark.subAdministrativeArea}, ${placemark.administrativeArea} ${placemark.postalCode}, ${placemark.country}';
    print(completeAddress);
    String formattedAddress = "${placemark.subLocality}, ${placemark.locality}, ${placemark.country}";
    locationController.text = formattedAddress;
  }

 bool get wantKeepAlive => true;

  @override
  Widget build(BuildContext context) {
    super.build(context);

    return file == null ? buildSplashScreen() : buildUploadForm();
  }
}

标签: fluttercrashimagepicker

解决方案


推荐阅读