Пакет Flutter image_picker возвращает ноль при попытке извлечь видео из галереи - PullRequest
0 голосов
/ 30 апреля 2020

Я пытаюсь создать приложение, которое позволяет пользователям выбирать видео и загружать их, поэтому для этого я использую пакет image_picker. Тем не менее, в настоящее время я выполняю тесты, и всякий раз, когда я пытаюсь выбрать видео из галереи, вместо того, чтобы вернуть файл, я получаю нулевое значение. Я не знаю, связана ли проблема с тем, как я использую пакет или с разрешениями, хотя в соответствии с пакетом вам не нужны разрешения для android.

Ниже функции в моем коде, которая доставляет мне неприятности:

handleChooseFromGallery() async {
Navigator.pop(context);
File filePicked = await ImagePicker.pickVideo(
  source: ImageSource.gallery,
  maxDuration: Duration(seconds: 90),
);
//This line always returns false
print({'is file not null': filePicked != null});
setState(() {
  if (filePicked != null) {
    this.files.add(filePicked);
    this.selected = true;
  } else {
    showError();
  }
});
  }

Полный код (за исключением совершенно не относящихся к делу вещей):

import 'dart:io';

import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:golfapp/data/course_data.dart';
import 'package:golfapp/data/user_data.dart';
import 'package:provider/provider.dart';
import 'package:image_picker/image_picker.dart';
import 'package:uuid/uuid.dart';
import 'package:firebase_storage/firebase_storage.dart';
import 'package:cloud_firestore/cloud_firestore.dart';

import 'package:golfapp/data/semana_data.dart';
import 'package:golfapp/widgets/chewie_item.dart';

final StorageReference storageRef = FirebaseStorage.instance.ref();
final postsRef = Firestore.instance.collection('posts');
final DateTime timestamp = DateTime.now();

class DetailScreen extends StatefulWidget {
  final int index;
  final String photoUrl;
  final String videoUrl;

  DetailScreen({this.index, this.photoUrl, this.videoUrl});

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

class _DetailScreenState extends State<DetailScreen> {
  bool isUploading = false;
  bool selected = false;
  List<File> files = [];
  String postId = Uuid().v4();
  TextEditingController captionController = TextEditingController();

  showError() {
    showDialog(
      context: context,
      builder: (BuildContext context) {
        return AlertDialog(
          title: Row(
            children: [
              Padding(
                padding: EdgeInsets.only(right: 10.0),
                child: Text('Error'),
              ),
              Icon(Icons.error_outline, size: 60.0),
            ],
          ),
          content: SingleChildScrollView(
            child: ListBody(
              children: [
                Text(
                  'Hubo un error con el video seleccionado.',
                  style: TextStyle(
                    fontFamily: 'Montserrat',
                    fontWeight: FontWeight.w600,
                    fontSize: 17.0,
                  ),
                ),
              ],
            ),
          ),
        );
      },
    );
  }

  clearImage() {
    setState(() {
      this.selected = false;
    });
  }

  handleTakePhoto() async {
    Navigator.pop(context);
    File fileTaken = await ImagePicker.pickVideo(
      source: ImageSource.camera,
      maxDuration: Duration(seconds: 90),
    );
    setState(() {
      if (fileTaken != null) {
        this.files.add(fileTaken);
        this.selected = true;
      } else {
        showError();
      }
    });
  }

  handleChooseFromGallery() async {
    Navigator.pop(context);
    File filePicked = await ImagePicker.pickVideo(
      source: ImageSource.gallery,
      maxDuration: Duration(seconds: 90),
    );
    print({'is file not null': filePicked != null});
    setState(() {
      if (filePicked != null) {
        this.files.add(filePicked);
        this.selected = true;
      } else {
        showError();
      }
    });
  }

  selectImage(parentContext) {
    return showDialog(
      context: parentContext,
      builder: (context) {
        return SimpleDialog(
          title: Text("Seleccionar video"),
          children: <Widget>[
            SimpleDialogOption(
              child: Text("Tomar video"),
              onPressed: handleTakePhoto,
            ),
            SimpleDialogOption(
              child: Text("Video de la galería"),
              onPressed: handleChooseFromGallery,
            ),
            SimpleDialogOption(
              child: Text("Cancelar"),
              onPressed: () => Navigator.pop(context),
            )
          ],
        );
      },
    );
  }

  Future<String> uploadVideo(imageFile) async {
    StorageUploadTask uploadTask = storageRef
        .child(Provider.of<UserData>(context, listen: false).user.id)
        .child(Provider.of<CourseData>(context, listen: false).course.uid)
        .child(Provider.of<SemanaData>(context, listen: false).semana.uid)
        .putFile(imageFile, StorageMetadata(contentType: 'video/mp4'));
    StorageTaskSnapshot storageSnap = await uploadTask.onComplete;
    String downloadUrl = await storageSnap.ref.getDownloadURL();
    return downloadUrl;
  }

  createPostInFirestore({List<String> mediaUrl, String description}) {
    postsRef
        .document(Provider.of<UserData>(context, listen: false).user.id)
        .collection("userPosts")
        .document(Provider.of<CourseData>(context, listen: false).course.uid)
        .setData({
      "semana": Provider.of<SemanaData>(context, listen: false).semana.uid,
      "postId": postId,
      "ownerId": Provider.of<UserData>(context, listen: false).user.id,
      "username": Provider.of<UserData>(context, listen: false).user.username,
      "mediaUrl": mediaUrl,
      "description": description,
      "timestamp": timestamp,
      "likes": {},
    });
  }

  handleSubmit() async {
    setState(() {
      isUploading = true;
    });
    List<String> mediaUrlS = [];
    for (File fileLoop in files) {
      String mediaUrl = await uploadVideo(fileLoop);
      mediaUrlS.add(mediaUrl);
    }
    createPostInFirestore(
      mediaUrl: mediaUrlS,
      description: captionController.text,
    );
    captionController.clear();
    setState(() {
      files = [];
      isUploading = false;
      postId = Uuid().v4();
      selected = false;
    });
  }

  Scaffold buildUploadForm() {
    return Scaffold(
      appBar: AppBar(
        title: Text(
          "Tu video",
          style: TextStyle(color: Colors.black),
        ),
        actions: [
          FlatButton(
            onPressed: files.length < 2 ? selectImage(context) : null,
            child: Text(
              'Seleccionar otro video',
            ),
          ),
          FlatButton(
            onPressed: isUploading ? null : () => handleSubmit(),
            child: Text(
              "Mandar",
            ),
          ),
        ],
      ),
      body: ListView.builder(
          scrollDirection: Axis.vertical,
          shrinkWrap: true,
          itemCount: files.length,
          itemBuilder: (BuildContext context, int index) {
            final File fileBuilder = files[index];
            return Container(
              height: 220.0,
              width: MediaQuery.of(context).size.width * 0.8,
              child: Center(
                child: AspectRatio(
                  aspectRatio: 16 / 9,
                  child: Container(
                    child: ChewieListItem(
                      videoUrl: fileBuilder.path,
                      network: false,
                      file: fileBuilder,
                    ),
                  ),
                ),
              ),
            );
          }),
    );
  }

  Widget buildNormalScreen () {
    return Container(
      child: GestureDetector(
        onTap: () {
          selectImage(context);
        },
        child: Container(
          height: 50.0,
          decoration: BoxDecoration(
            borderRadius: BorderRadius.circular(30.0),
            color: Theme.of(context).accentColor,
          ),
          child: Center(
            child: Row(
              mainAxisAlignment: MainAxisAlignment.center,
              children: <Widget>[
                Text(
                  'Subir videos',
                  style: TextStyle(
                    fontFamily: 'Comfortaa',
                    fontSize: 17.0,
                    color: Colors.white,
                  ),
                ),
              ],
            ),
          ),
        ),
      ),
    );
  }

  @override
  Widget build(BuildContext context) {
    return !selected
        ? buildNormalScreen()
        : buildUploadForm();
  }
}

В функции вверху я также попытался сделать что-то вроде ImagePicker.pickVideo().then((file){...}), но это не работал Я также добавил <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/> в мой файл "android / app / src / main / AndroidManifest. xml". Я также попытался добавить android:requestLegacyExternalStorage="true" внутри тега <application> в моем файле "android / app / src / main / AndroidManifest. xml", но затем я получил ошибку: console printout

Я не знаю, что мне следует изменить ни в моем коде, ни в одном из файлов в папке android, любая помощь очень важна.

Заранее большое спасибо

1 Ответ

0 голосов
/ 30 апреля 2020

Поместите условие в ту же функцию.

handleChooseFromGallery() async {
Navigator.pop(context);
File filePicked = await ImagePicker.pickVideo(
  source: ImageSource.gallery,
  maxDuration: Duration(seconds: 90),
  //This line always returns false
  print({'is file not null': filePicked != null});
  setState(() {
    if (filePicked != null) {
      this.files.add(filePicked);
      this.selected = true;
    } else {
      showError();
    }
  });
}

);

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...