質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
Flutter

Flutterは、iOSとAndroidのアプリを同じコードで開発するためのフレームワークです。オープンソースで開発言語はDart。双方のプラットフォームにおける高度な実行パフォーマンスと開発効率を提供することを目的としています。

Android

Androidは、Google社が開発したスマートフォンやタブレットなど携帯端末向けのプラットフォームです。 カーネル・ミドルウェア・ユーザーインターフェイス・ウェブブラウザ・電話帳などのアプリケーションやソフトウェアをひとつにまとめて構成。 カーネル・ライブラリ・ランタイムはほとんどがC言語/C++、アプリケーションなどはJavaSEのサブセットとAndroid環境で書かれています。

Dart

Dartは、Googleによって開発されたJavaScriptの代替となることを目的に作られた、ウェブ向けのプログラミング言語である。

Q&A

解決済

2回答

2943閲覧

【Flutter】" NoSuchMethodError ", " The getter 'length' was called on null " を解決したいです

cocona15531

総合スコア6

Flutter

Flutterは、iOSとAndroidのアプリを同じコードで開発するためのフレームワークです。オープンソースで開発言語はDart。双方のプラットフォームにおける高度な実行パフォーマンスと開発効率を提供することを目的としています。

Android

Androidは、Google社が開発したスマートフォンやタブレットなど携帯端末向けのプラットフォームです。 カーネル・ミドルウェア・ユーザーインターフェイス・ウェブブラウザ・電話帳などのアプリケーションやソフトウェアをひとつにまとめて構成。 カーネル・ライブラリ・ランタイムはほとんどがC言語/C++、アプリケーションなどはJavaSEのサブセットとAndroid環境で書かれています。

Dart

Dartは、Googleによって開発されたJavaScriptの代替となることを目的に作られた、ウェブ向けのプログラミング言語である。

0グッド

0クリップ

投稿2021/02/27 01:15

編集2021/02/27 02:58

前提・実現したいこと

Flutterでカメラアプリを作っているFlutter初心者の者です。
「カメラを起動」を押すと文字通りカメラが起動する機能を実装中にエラーメッセージが発生しました。
![イメージ説明]

こちらに記載されているソースコードを参考にさせて頂きました。
https://github.com/aftercider/camera-app-2018/blob/master/lib/main.dart

発生している問題・エラーメッセージ

======== Exception caught by widgets library =======================================================
The following NoSuchMethodError was thrown building CameraWidget(dirty, state: _CameraWidgetState#ae112):
The getter 'length' was called on null.
Receiver: null
Tried calling: length

main.dart

dart

1import 'dart:async'; 2import 'dart:io'; 3 4import 'package:flutter/material.dart'; 5import 'package:camera/camera.dart'; 6import 'package:path_provider/path_provider.dart'; 7import 'package:image_picker_saver/image_picker_saver.dart'; 8import 'package:simple_permissions/simple_permissions.dart'; 9import 'camera.dart'; 10 11 12void main() { 13 runApp(new MyApp()); 14} 15 16class MyApp extends StatelessWidget { 17 18 Widget build (BuildContext context){ 19 return MaterialApp( 20 title: 'Sort cam', 21 theme: ThemeData( 22 primarySwatch:Colors.blue, 23 ), 24 home: MyHomePage() 25 ); 26 } 27} 28class MyHomePage extends StatelessWidget{ 29 Widget build(BuildContext context){ 30 return Scaffold( 31 appBar:AppBar( 32 title: const Text('Sort cam'), 33 actions: <Widget>[ 34 IconButton(icon: Icon(Icons.settings), 35 onPressed:(){}, 36 ) 37 ] 38 ), 39 body: Center( 40 child: RaisedButton(onPressed: () { 41 Navigator.push( 42 context, 43 MaterialPageRoute( 44 builder: (context) => CameraApp()), 45 ); 46 }, child: Text('カメラを起動')) 47 ), 48 ); 49 } 50} 51 52

該当のソースコード(camera.dart)

dart

1import 'dart:async'; // 非同期処理(async/await) 2import 'dart:io'; // ファイルの入出力 3 4import 'package:camera/camera.dart'; 5import 'package:flutter/material.dart'; 6import 'package:path_provider/path_provider.dart'; 7import 'package:image_picker_saver/image_picker_saver.dart'; 8import 'package:simple_permissions/simple_permissions.dart'; 9import 'main.dart'; 10 11List<CameraDescription> cameras; // 使用できるカメラのリスト 12 13// ここから始まる 14Future<void> main() async { 15 cameras = await availableCameras(); 16 runApp(CameraApp()); 17} 18 19// 親玉のApp 20class CameraApp extends StatelessWidget { 21 22 Widget build(BuildContext context) { 23 return MaterialApp( 24 home: CameraWidget(), 25 ); 26 } 27} 28 29// 親玉の中身 30class CameraWidget extends StatefulWidget { 31 32 _CameraWidgetState createState() { 33 return _CameraWidgetState(); 34 } 35} 36 37// 実際はこれがやることやる 38class _CameraWidgetState extends State<CameraWidget> { 39 CameraController controller; 40 final GlobalKey<ScaffoldState> _scaffoldKey = GlobalKey<ScaffoldState>(); 41 String timestamp() => 42 DateTime.now().millisecondsSinceEpoch.toString(); // ファイル名にはタイムスタンプ入れる。 43 void showInSnackBar(String message) => _scaffoldKey.currentState 44 .showSnackBar(SnackBar(content: Text(message))); // SnackBarでメッセージ表示 45 46 47 Widget build(BuildContext context) { 48 Scaffold sc = Scaffold( 49 key: _scaffoldKey, 50 body: Column( 51 children: <Widget>[ 52 Expanded( 53 child: Container( 54 child: Padding( 55 padding: const EdgeInsets.all(1.0), 56 child: Center( 57 child: _cameraPreviewWidget(), // カメラのプレビューを表示するWidget 58 ), 59 ), 60 ), 61 ), 62 Row( 63 mainAxisAlignment: MainAxisAlignment.spaceEvenly, 64 mainAxisSize: MainAxisSize.max, 65 children: <Widget>[ 66 IconButton( 67 // カメラの撮影ボタン 68 icon: const Icon(Icons.camera_alt), 69 onPressed: controller != null && controller.value.isInitialized 70 ? onTakePictureButtonPressed // 撮影ボタンを押された時にコールバックされる関数 71 : null, 72 ), 73 ], 74 ) 75 ], 76 ), 77 ); 78 79 // カメラのセットアップ。セットアップが終わったらもう一回buildが走るので、 80 // controllerがnullかどうかで処理実施有無を判定。 81 if (controller == null) { 82 if (cameras.length == 0) { 83 throw Exception("使用できるカメラがありません"); 84 } 85 setUpCamera(cameras[0]); 86 } 87 return sc; 88 } 89 90 /// カメラプレビューを表示するWidget 91 Widget _cameraPreviewWidget() { 92 if (controller == null || !controller.value.isInitialized) { 93 // カメラの準備ができるまではテキストを表示 94 return const Text('Tap a camera'); 95 } else { 96 // 準備ができたらプレビュー表示 97 return AspectRatio( 98 aspectRatio: controller.value.aspectRatio, 99 child: CameraPreview(controller), 100 ); 101 } 102 } 103 104 // カメラを準備する 105 void setUpCamera(CameraDescription cameraDescription) async { 106 if (controller != null) { 107 await controller.dispose(); 108 } 109 controller = CameraController(cameraDescription, ResolutionPreset.high); 110 111 // カメラの情報が更新されたら呼ばれるリスナー設定 112 controller.addListener(() { 113 if (mounted) setState(() {}); // 準備終わったらbuildし直す。 114 if (controller.value.hasError) { 115 showInSnackBar('Camera error ${controller.value.errorDescription}'); 116 } 117 }); 118 119 await controller.initialize(); 120 121 // パーミッションの確認・要求 122 if (Platform.isAndroid && 123 !await SimplePermissions.checkPermission(Permission.WriteExternalStorage)) { 124 SimplePermissions.requestPermission(Permission.WriteExternalStorage); 125 } else if (Platform.isIOS && 126 !await SimplePermissions.checkPermission(Permission.PhotoLibrary)) { 127 SimplePermissions.requestPermission(Permission.PhotoLibrary); 128 } 129 130 if (mounted) { 131 setState(() {}); 132 } 133 } 134 135 // 撮影ボタンが押されたら撮影して、画像を保存する 136 void onTakePictureButtonPressed() { 137 takePicture().then((String filePath) { 138 if (mounted) { 139 setState(() {}); 140 if (filePath != null) showInSnackBar('Picture saved to $filePath'); 141 } 142 }); 143 } 144 145 // 画像撮影・保存処理 146 Future<String> takePicture() async { 147 if (!controller.value.isInitialized) { 148 return null; 149 } 150 151 Directory dir; 152 if (Platform.isAndroid) { 153 dir = await getExternalStorageDirectory(); // 外部ストレージに保存 154 } else if (Platform.isIOS) { 155 dir = await getTemporaryDirectory(); // 一時ディレクトリに保存 156 } else { 157 return null; 158 } 159 160 final String dirPath = '${dir.path}/Pictures/flutter_test'; 161 await Directory(dirPath).create(recursive: true); 162 String filePath = '$dirPath/${timestamp()}.jpg'; 163 164 if (controller.value.isTakingPicture) { 165 return null; 166 } 167 168 await controller.takePicture(filePath); 169 170 // filePathに保存されたデータをiOSならPhotoLibrary領域にコピーする 171 if (Platform.isIOS) { 172 String tmpPath = filePath; 173 var savedFile = File.fromUri(Uri.file(tmpPath)); 174 filePath = await ImagePickerSaver.saveFile( 175 fileData: savedFile.readAsBytesSync()); 176 } 177 178 return filePath; 179 } 180}

試したこと

解決方法として"Get Upgrade"をしていなかったのでしてみたりしましたが、状況は変わりませんでした。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

hoshi-takanori

2021/02/27 10:08

cameras が null ってことですよね。Flutter よく分かってませんが、main.dart と camera.dart の両方に main 函数があるようですが、camera.dart の main は呼ばれてますか?
cocona15531

2021/02/27 12:07

コメントありがとうございます。恐らく呼ばれていると思います。
guest

回答2

0

ベストアンサー

errorメッセージ自体は、lengthが存在しないのに呼ばれているというエラーメッセージなので、

dart

1 if (controller == null) { 2 if (cameras.length == 0) { 3 throw Exception("使用できるカメラがありません"); 4 } 5 setUpCamera(cameras[0]); 6 } 7 return sc;

のcameras.length == 0の部分を省くか別の書き方をして試してみるのはどうでしょう。

投稿2021/02/28 07:32

Rassy

総合スコア44

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

参考にされたafterciderさんのcamera-app-2018のQiita記事を見てみましたが、2018年の記事でありflutterやlibraryの情報が古そうな印象を受けました。
まずは2020年以降でcamera appを作っている方の記事を参考にされると良いのかなと思います。
例:
https://tech-blog.rakus.co.jp/entry/20200929/flutter

投稿2021/02/27 22:15

Rassy

総合スコア44

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問