-
Notifications
You must be signed in to change notification settings - Fork 28.6k
[camera] Example app shows error when initializing camera app for the first time. #73783
10000New 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
Comments
@BeMacized |
Channel stable, 1.22.5, on macOS 11.1 20C69 darwin-x64. This happens both to me and to @mvanbeusekom, only after a clean install (app has been uninstalled first) |
@BeMacized Thanks for details. flutter doctor -v
|
@darshankawar which version of the camera plugin are you using? From the screenshot it looks like you are on a pre-0.6.0 version. This error occurs on version 0.6.4 of the camera plugin after which we added the exposure feature. Note that it is a small bug in the code of the example app it self and not the plugin logic. |
@mvanbeusekom Tried with the latest camera plugin version |
Did you make sure you deleted the App from your test device first? Take the following steps:
I have just reproduced the issue again using version 0.6.4+5. flutter doctor -v
|
@mvanbeusekom |
I don't think it is related to Big Sur, since it happens when running the code on the iPhone itself. @BeMacized has been able to solve it in flutter/plugins#3406, where it looked to be a race condition. It might indeed be related to the iOS version, unfortunately I cannot verify with an older device. |
Thanks @mvanbeusekom for replicating. Since I don't have the latest iOS on my test device, I can't replicate it. Also, the PR to fix the issue seems to be ready to merge once approved. |
Hi everyone
code sample// Copyright 2019 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// ignore_for_file: public_member_api_docs
import 'dart:async';
import 'dart:io';
import 'package:camera/camera.dart';
import 'package:flutter/material.dart';
import 'package:video_player/video_player.dart';
class CameraExampleHome extends StatefulWidget {
@override
_CameraExampleHomeState createState() {
return _CameraExampleHomeState();
}
}
/// Returns a suitable camera icon for [direction].
IconData getCameraLensIcon(CameraLensDirection direction) {
switch (direction) {
case CameraLensDirection.back:
return Icons.camera_rear;
case CameraLensDirection.front:
return Icons.camera_front;
case CameraLensDirection.external:
return Icons.camera;
}
throw ArgumentError('Unknown lens direction');
}
void logError(String code, String message) =>
print('Error: $code\nError Message: $message');
class _CameraExampleHomeState extends State<CameraExampleHome>
with WidgetsBindingObserver, TickerProviderStateMixin {
CameraController controller;
XFile imageFile;
XFile videoFile;
VideoPlayerController videoController;
VoidCallback videoPlayerListener;
bool enableAudio = true;
double _minAvailableExposureOffset = 0.0;
double _maxAvailableExposureOffset = 0.0;
double _currentExposureOffset = 0.0;
AnimationController _flashModeControlRowAnimationController;
Animation<double> _flashModeControlRowAnimation;
AnimationController _exposureModeControlRowAnimationController;
Animation<double> _exposureModeControlRowAnimation;
double _minAvailableZoom;
double _maxAvailableZoom;
double _currentScale = 1.0;
double _baseScale = 1.0;
// Counting pointers (number of user fingers on screen)
int _pointers = 0;
@override
void initState() {
super.initState();
WidgetsBinding.instance.addObserver(this);
_flashModeControlRowAnimationController = AnimationController(
duration: const Duration(milliseconds: 300),
vsync: this,
);
_flashModeControlRowAnimation = CurvedAnimation(
parent: _flashModeControlRowAnimationController,
curve: Curves.easeInCubic,
);
_exposureModeControlRowAnimationController = AnimationController(
duration: const Duration(milliseconds: 300),
vsync: this,
);
_exposureModeControlRowAnimation = CurvedAnimation(
parent: _exposureModeControlRowAnimationController,
curve: Curves.easeInCubic,
);
}
@override
void dispose() {
WidgetsBinding.instance.removeObserver(this);
_flashModeControlRowAnimationController.dispose();
_exposureModeControlRowAnimationController.dispose();
super.dispose();
}
@override
void didChangeAppLifecycleState(AppLifecycleState state) {
// App state changed before we got the chance to initialize.
if (controller == null || !controller.value.isInitialized) {
return;
}
if (state == AppLifecycleState.inactive) {
controller?.dispose();
} else if (state == AppLifecycleState.resumed) {
if (controller != null) {
onNewCameraSelected(controller.description);
}
}
}
final GlobalKey<ScaffoldState> _scaffoldKey = GlobalKey<ScaffoldState>();
@override
Widget build(BuildContext context) {
return Scaffold(
key: _scaffoldKey,
appBar: AppBar(
title: const Text('Camera example'),
),
body: Column(
children: <Widget>[
Expanded(
child: Container(
child: Padding(
padding: const EdgeInsets.all(1.0),
child: Center(
child: _cameraPreviewWidget(),
),
),
decoration: BoxDecoration(
color: Colors.black,
border: Border.all(
color: controller != null && controller.value.isRecordingVideo
? Colors.redAccent
: Colors.grey,
width: 3.0,
),
),
),
),
_captureControlRowWidget(),
_modeControlRowWidget(),
Padding(
padding: const EdgeInsets.all(5.0),
child: Row(
mainAxisAlignment: MainAxisAlignment.start,
children: <Widget>[
_cameraTogglesRowWidget(),
_thumbnailWidget(),
],
),
),
],
),
);
}
/// Display the preview from the camera (or a message if the preview is not available).
Widget _cameraPreviewWidget() {
if (controller == null || !controller.value.isInitialized) {
return const Text(
'Tap a camera',
style: TextStyle(
color: Colors.white,
fontSize: 24.0,
fontWeight: FontWeight.w900,
),
);
} else {
return AspectRatio(
aspectRatio: controller.value.aspectRatio,
child: Listener(
onPointerDown: (_) => _pointers++,
onPointerUp: (_) => _pointers--,
child: LayoutBuilder(
builder: (BuildContext context, BoxConstraints constraints) {
return GestureDetector(
onScaleStart: _handleScaleStart,
onScaleUpdate: _handleScaleUpdate,
onTapDown: (details) => onViewFinderTap(details, constraints),
child: CameraPreview(controller),
);
}),
),
);
}
}
void _handleScaleStart(ScaleStartDetails details) {
_baseScale = _currentScale;
}
Future<void> _handleScaleUpdate(ScaleUpdateDetails details) async {
// When there are not exactly two fingers on screen don't scale
if (_pointers != 2) {
return;
}
_currentScale = (_baseScale * details.scale)
.clamp(_minAvailableZoom, _maxAvailableZoom);
await controller.setZoomLevel(_currentScale);
}
/// Display the thumbnail of the captured image or video.
Widget _thumbnailWidget() {
return Expanded(
child: Align(
alignment: Alignment.centerRight,
child: Row(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
videoController == null && imageFile == null
? Container()
: SizedBox(
child: (videoController == null)
? Image.file(File(imageFile.path))
: Container(
child: Center(
child: AspectRatio(
aspectRatio:
videoController.value.size != null
? videoController.value.aspectRatio
: 1.0,
child: VideoPlayer(videoController)),
),
decoration: BoxDecoration(
border: Border.all(color: Colors.pink)),
),
width: 64.0,
height: 64.0,
),
],
),
),
);
}
/// Display a bar with buttons to change the flash and exposure modes
Widget _modeControlRowWidget() {
return Column(
children: [
Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
mainAxisSize: MainAxisSize.max,
children: <Widget>[
IconButton(
icon: Icon(Icons.flash_on),
color: Colors.blue,
onPressed: controller != null ? onFlashModeButtonPressed : null,
),
IconButton(
icon: Icon(Icons.exposure),
color: Colors.blue,
onPressed:
controller != null ? onExposureModeButtonPressed : null,
),
IconButton(
icon: Icon(enableAudio ? Icons.volume_up : Icons.volume_mute),
color: Colors.blue,
onPressed: controller != null ? onAudioModeButtonPressed : null,
),
],
),
_flashModeControlRowWidget(),
_exposureModeControlRowWidget(),
],
);
}
Widget _flashModeControlRowWidget() {
return SizeTransition(
sizeFactor: _flashModeControlRowAnimation,
child: ClipRect(
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
mainAxisSize: MainAxisSize.max,
children: [
IconButton(
icon: Icon(Icons.flash_off),
color: controller?.value?.flashMode == FlashMode.off
? Colors.orange
: Colors.blue,
onPressed: controller != null
? () => onSetFlashModeButtonPressed(FlashMode.off)
: null,
),
IconButton(
icon: Icon(Icons.flash_auto),
color: controller?.value?.flashMode == FlashMode.auto
? Colors.orange
: Colors.blue,
onPressed: controller != null
? () => onSetFlashModeButtonPressed(FlashMode.auto)
: null,
),
IconButton(
icon: Icon(Icons.flash_on),
color: controller?.value?.flashMode == FlashMode.always
? Colors.orange
: Colors.blue,
onPressed: controller != null
? () => onSetFlashModeButtonPressed(FlashMode.always)
: null,
),
IconButton(
icon: Icon(Icons.highlight),
color: controller?.value?.flashMode == FlashMode.torch
? Colors.orange
: Colors.blue,
onPressed: controller != null
? () => onSetFlashModeButtonPressed(FlashMode.torch)
: null,
),
],
),
),
);
}
Widget _exposureModeControlRowWidget() {
final ButtonStyle styleAuto = TextButton.styleFrom(
primary: controller?.value?.exposureMode == ExposureMode.auto
? Colors.orange
: Colors.blue,
);
final ButtonStyle styleLocked = TextButton.styleFrom(
primary: controller?.value?.exposureMode == ExposureMode.locked
? Colors.orange
: Colors.blue,
);
return SizeTransition(
sizeFactor: _exposureModeControlRowAnimation,
child: ClipRect(
child: Container(
color: Colors.grey.shade50,
child: Column(
children: [
Center(
child: Text("Exposure Mode"),
),
Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
mainAxisSize: MainAxisSize.max,
children: [
TextButton(
child: Text('AUTO'),
style: styleAuto,
onPressed: controller != null
? () =>
onSetExposureModeButtonPressed(ExposureMode.auto)
: null,
onLongPress: () {
if (controller != null) controller.setExposurePoint(null);
showInSnackBar('Resetting exposure point');
},
),
TextButton(
child: Text('LOCKED'),
style: styleLocked,
onPressed: controller != null
? () =>
onSetExposureModeButtonPressed(ExposureMode.locked)
: null,
),
],
),
Center(
child: Text("Exposure Offset"),
),
Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
mainAxisSize: MainAxisSize.max,
children: [
Text(_minAvailableExposureOffset.toString()),
Slider(
value: _currentExposureOffset,
min: _minAvailableExposureOffset,
max: _maxAvailableExposureOffset,
label: _currentExposureOffset.toString(),
onChanged: _minAvailableExposureOffset ==
_maxAvailableExposureOffset
? null
: setExposureOffset,
),
Text(_maxAvailableExposureOffset.toString()),
],
),
],
),
),
),
);
}
/// Display the control bar with buttons to take pictures and record videos.
Widget _captureControlRowWidget() {
return Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
mainAxisSize: MainAxisSize.max,
children: <Widget>[
IconButton(
icon: const Icon(Icons.camera_alt),
color: Colors.blue,
onPressed: controller != null &&
controller.value.isInitialized &&
!controller.value.isRecordingVideo
? onTakePictureButtonPressed
: null,
),
IconButton(
icon: const Icon(Icons.videocam),
color: Colors.blue,
onPressed: controller != null &&
controller.value.isInitialized &&
!controller.value.isRecordingVideo
? onVideoRecordButtonPressed
: null,
),
IconButton(
icon: controller != null && controller.value.isRecordingPaused
? Icon(Icons.play_arrow)
: Icon(Icons.pause),
color: Colors.blue,
onPressed: controller != null &&
controller.value.isInitialized &&
controller.value.isRecordingVideo
? (controller != null && controller.value.isRecordingPaused
? onResumeButtonPressed
: onPauseButtonPressed)
: null,
),
IconButton(
icon: const Icon(Icons.stop),
color: Colors.red,
onPressed: controller != null &&
controller.value.isInitialized &&
controller.value.isRecordingVideo
? onStopButtonPressed
: null,
)
],
);
}
/// Display a row of toggle to select the camera (or a message if no camera is available).
Widget _cameraTogglesRowWidget() {
final List<Widget> toggles = <Widget>[];
if (cameras.isEmpty) {
return const Text('No camera found');
} else {
for (CameraDescription cameraDescription in cameras) {
toggles.add(
SizedBox(
width: 90.0,
child: RadioListTile<CameraDescription>(
title
8000
: Icon(getCameraLensIcon(cameraDescription.lensDirection)),
groupValue: controller?.description,
value: cameraDescription,
onChanged: controller != null && controller.value.isRecordingVideo
? null
: onNewCameraSelected,
),
),
);
}
}
return Row(children: toggles);
}
String timestamp() => DateTime.now().millisecondsSinceEpoch.toString();
void showInSnackBar(String message) {
// ignore: deprecated_member_use
_scaffoldKey.currentState.showSnackBar(SnackBar(content: Text(message)));
}
void onViewFinderTap(TapDownDetails details, BoxConstraints constraints) {
controller.setExposurePoint(Offset(
details.localPosition.dx / constraints.maxWidth,
details.localPosition.dy / constraints.maxHeight,
));
}
void onNewCameraSelected(CameraDescription cameraDescription) async {
if (controller != null) {
await controller.dispose();
}
controller = CameraController(
cameraDescription,
ResolutionPreset.medium,
enableAudio: enableAudio,
);
// If the controller is updated then update the UI.
controller.addListener(() {
if (mounted) setState(() {});
if (controller.value.hasError) {
showInSnackBar('Camera error ${controller.value.errorDescription}');
}
});
try {
await controller.initialize();
_minAvailableExposureOffset = await controller.getMinExposureOffset();
_maxAvailableExposureOffset = await controller.getMaxExposureOffset();
_maxAvailableZoom = await controller.getMaxZoomLevel();
_minAvailableZoom = await controller.getMinZoomLevel();
} on CameraException catch (e) {
_showCameraException(e);
}
if (mounted) {
setState(() {});
}
}
void onTakePictureButtonPressed() {
takePicture().then((XFile file) {
if (mounted) {
setState(() {
imageFile = file;
videoController?.dispose();
videoController = null;
});
if (file != null) showInSnackBar('Picture saved to ${file.path}');
}
});
}
void onFlashModeButtonPressed() {
if (_flashModeControlRowAnimationController.value == 1) {
_flashModeControlRowAnimationController.reverse();
} else {
_flashModeControlRowAnimationController.forward();
_exposureModeControlRowAnimationController.reverse();
}
}
void onExposureModeButtonPressed() {
if (_exposureModeControlRowAnimationController.value == 1) {
_exposureModeControlRowAnimationController.reverse();
} else {
_exposureModeControlRowAnimationController.forward();
_flashModeControlRowAnimationController.reverse();
}
}
void onAudioModeButtonPressed() {
enableAudio = !enableAudio;
if (controller != null) {
onNewCameraSelected(controller.description);
}
}
void onSetFlashModeButtonPressed(FlashMode mode) {
setFlashMode(mode).then((_) {
if (mounted) setState(() {});
showInSnackBar('Flash mode set to ${mode.toString().split('.').last}');
});
}
void onSetExposureModeButtonPressed(ExposureMode mode) {
setExposureMode(mode).then((_) {
if (mounted) setState(() {});
showInSnackBar('Exposure mode set to ${mode.toString().split('.').last}');
});
}
void onVideoRecordButtonPressed() {
startVideoRecording().then((_) {
if (mounted) setState(() {});
});
}
void onStopButtonPressed() {
stopVideoRecording().then((file) {
if (mounted) setState(() {});
if (file != null) {
showInSnackBar('Video recorded to ${file.path}');
videoFile = file;
_startVideoPlayer();
}
});
}
void onPauseButtonPressed() {
pauseVideoRecording().then((_) {
if (mounted) setState(() {});
showInSnackBar('Video recording paused');
});
}
void onResumeButtonPressed() {
resumeVideoRecording().then((_) {
if (mounted) setState(() {});
showInSnackBar('Video recording resumed');
});
}
Future<void> startVideoRecording() async {
if (!controller.value.isInitialized) {
showInSnackBar('Error: select a camera first.');
return;
}
if (controller.value.isRecordingVideo) {
// A recording is already started, do nothing.
return;
}
try {
await controller.startVideoRecording();
} on CameraException catch (e) {
_showCameraException(e);
return;
}
}
Future<XFile> stopVideoRecording() async {
if (!controller.value.isRecordingVideo) {
return null;
}
try {
return controller.stopVideoRecording();
} on CameraException catch (e) {
_showCameraException(e);
return null;
}
}
Future<void> pauseVideoRecording() async {
if (!controller.value.isRecordingVideo) {
return null;
}
try {
await controller.pauseVideoRecording();
} on CameraException catch (e) {
_showCameraException(e);
rethrow;
}
}
Future<void> resumeVideoRecording() async {
if (!controller.value.isRecordingVideo) {
return null;
}
try {
await controller.resumeVideoRecording();
} on CameraException catch (e) {
_showCameraException(e);
rethrow;
}
}
Future<void> setFlashMode(FlashMode mode) async {
try {
await controller.setFlashMode(mode);
} on CameraException catch (e) {
_showCameraException(e);
rethrow;
}
}
Future<void> setExposureMode(ExposureMode mode) async {
try {
await controller.setExposureMode(mode);
} on CameraException catch (e) {
_showCameraException(e);
rethrow;
}
}
Future<void> setExposureOffset(double offset) async {
setState(() {
_currentExposureOffset = offset;
});
try {
offset = await controller.setExposureOffset(offset);
} on CameraException catch (e) {
_showCameraException(e);
rethrow;
}
}
Future<void> _startVideoPlayer() async {
final VideoPlayerController vController =
VideoPlayerController.file(File(videoFile.path));
videoPlayerListener = () {
if (videoController != null && videoController.value.size != null) {
// Refreshing the state to update video player with the correct ratio.
if (mounted) setState(() {});
videoController.removeListener(videoPlayerListener);
}
};
vController.addListener(videoPlayerListener);
await vController.setLooping(true);
await vController.initialize();
await videoController?.dispose();
if (mounted) {
setState(() {
imageFile = null;
videoController = vController;
});
}
await vController.play();
}
Future<XFile> takePicture() async {
if (!controller.value.isInitialized) {
showInSnackBar('Error: select a camera first.');
return null;
}
if (controller.value.isTakingPicture) {
// A capture is already pending, do nothing.
return null;
}
try {
XFile file = await controller.takePicture();
return file;
} on CameraException catch (e) {
_showCameraException(e);
return null;
}
}
void _showCameraException(CameraException e) {
logError(e.code, e.description);
showInSnackBar('Error: ${e.code}\n${e.description}');
}
}
class CameraApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: CameraExampleHome(),
);
}
}
List<CameraDescription> cameras = [];
Future<void> main() async {
// Fetch the available cameras before initializing the app.
try {
WidgetsFlutterBinding.ensureInitialized();
cameras = await availableCameras();
} on CameraException catch (e) {
logError(e.code, e.description);
}
runApp(CameraApp());
} logs[ +117 ms] ------ Debug phase ------
[ ] Starting debug of 00008020-000255113EE8402E (J171aAP, J171aAP, uknownos, unkarch) a.k.a. 'Taha’s iPad' connected through USB...
[ +157 ms] [ 0%] Looking up developer disk image
[ +15 ms] [ 95%] Developer disk image mounted successfully
[+1339 ms] [100%] Connecting to remote debug server
[ ] -------------------------
[ +385 ms] (lldb) command source -s 0 '/tmp/C8D7176D-EF5C-408C-B251-F4A99086A7DC/fruitstrap-lldb-prep-cmds-00008020_000255113EE8402E'
[ ] Executing commands in '/tmp/C8D7176D-EF5C-408C-B251-F4A99086A7DC/fruitstrap-lldb-prep-cmds-00008020_000255113EE8402E'.
[ ] (lldb) platform select remote-ios --sysroot '/Users/tahatesser/Library/Developer/Xcode/iOS DeviceSupport/14.3 (18C66) arm64e/Symbols'
[ ] Platform: remote-ios
[ ] Connected: no
[ ] SDK Path: "/Users/tahatesser/Library/Developer/Xcode/iOS DeviceSupport/14.3 (18C66) arm64e/Symbols"
[ ] (lldb) target create "/Users/tahatesser/AndroidStudioProjects/triage-examples/flutter_plugin_examples/camera_example/build/ios/iphoneos/Runner.app"
[+5005 ms] Current executable set to '/Users/tahatesser/AndroidStudioProjects/triage-examples/flutter_plugin_examples/camera_example/build/ios/iphoneos/Runner.app' (arm64).
[ ] (lldb) script fruitstrap_device_app="/private/var/containers/Bundle/Application/9FE55994-AE42-4FF5-BB88-4E439BADAEAB/Runner.app"
[ +560 ms] (lldb) script fruitstrap_connect_url="connect://127.0.0.1:59540"
[ ] (lldb) script fruitstrap_output_path=""
[ ] (lldb) script fruitstrap_error_path=""
[ ] (lldb) target modules search-paths add /usr "/Users/tahatesser/Library/Developer/Xcode/iOS DeviceSupport/14.3 (18C66) arm64e/Symbols/usr" /System "/Users/tahatesser/Library/Developer/Xcode/iOS DeviceSupport/14.3 (18C66) arm64e/Symbols/System" "/private/var/containers/Bundle/Application/9FE55994-AE42-4FF5-BB88-4E439BADAEAB" "/Users/tahatesser/AndroidStudioProjects/triage-examples/flutter_plugin_examples/camera_example/build/ios/iphoneos" "/var/containers/Bundle/Application/9FE55994-AE42-4FF5-BB88-4E439BADAEAB" "/Users/tahatesser/AndroidStudioProjects/triage-examples/flutter_plugin_examples/camera_example/build/ios/iphoneos" /Developer "/Users/tahatesser/Library/Developer/Xcode/iOS DeviceSupport/14.3 (18C66) arm64e/Symbols/Developer"
[ +14 ms] (lldb) command script import "/tmp/C8D7176D-EF5C-408C-B251-F4A99086A7DC/fruitstrap_00008020_000255113EE8402E.py"
[ +6 ms] (lldb) command script add -f fruitstrap_00008020_000255113EE8402E.connect_command connect
[ ] (lldb) command script add -s asynchronous -f fruitstrap_00008020_000255113EE8402E.run_command run
[ ] (lldb) command script add -s asynchronous -f fruitstrap_00008020_000255113EE8402E.autoexit_command autoexit
[ ] (lldb) command script add -s asynchronous -f fruitstrap_00008020_000255113EE8402E.safequit_command safequit
[ ] (lldb) connect
[ +64 ms] (lldb) run
[ +230 ms] success
[ ] (lldb) safequit
[ +196 ms] Application launched on the device. Waiting for observatory port.
[ +15 ms] Attempting to forward device port 61470 to host port 59553
[ ] executing: /Users/tahatesser/Code/flutter_stable/bin/cache/artifacts/usbmuxd/iproxy 59553:61470 --udid 00008020-000255113EE8402E
[+1010 ms] Forwarded port ForwardedPort HOST:59553 to DEVICE:61470
[ +150 ms] Installing and launching... (completed in 23.5s)
[ +1 ms] Caching compiled dill
[ +113 ms] Connecting to service protocol: http://localhost:59553
[ +1 ms] DDS is currently disabled due to https://github.com/flutter/flutter/issues/62507
[ +25 ms] Successfully connected to service protocol: http://localhost:59553
[ +2 ms] Waiting for Taha’s iPad to report its views...
[ +5 ms] Waiting for Taha’s iPad to report its views... (completed in 4ms)
[ +6 ms] DevFS: Creating new filesystem on the device (null)
[ +8 ms] DevFS: Created new filesystem on the device (file:///private/var/mobile/Containers/Data/Application/543892FA-F1C8-4AE4-9742-E2A9DB8340E5/tmp/camera_examplebaTTbb/camera_example/)
[ +2 ms] Updating assets
[ +240 ms] Syncing files to device Taha’s iPad...
[ +1 ms] Scanning asset files
[ +2 ms] <- reset
[ ] Compiling dart to kernel with 0 updated files
[ +1 ms] <- recompile package:triage/main.dart d0073bf7-c94c-4609-aacd-7daf5a93f8b2
[ ] <- d0073bf7-c94c-4609-aacd-7daf5a93f8b2
[ +53 ms] Updating files
[ +106 ms] DevFS: Sync finished
[ ] Syncing files to device Taha’s iPad... (completed in 166ms)
[ ] Synced 1.7MB.
[ +1 ms] <- accept
[ +2 ms] Connected to _flutterView/0x10383c420.
[ +1 ms] Flutter run key commands.
[ +1 ms] r Hot reload. 🔥🔥🔥
[ +2 ms] R Hot restart.
[ ] h Repeat this help message.
[ ] d Detach (terminate "flutter run" but leave application running).
[ ] c Clear the screen
[ ] q Quit (terminate the application on the device).
[ ] An Observatory debugger and profiler on Taha’s iPad is available at: http://localhost:59553
[+9059 ms] flutter: Error: Uninitialized CameraController
Error Message: getMaxExposureOffset was called on uninitialized CameraController flutter doctor -v[✓] Flutter (Channel stable, 1.22.5, on macOS 11.1 20C69 darwin-x64, locale en-GB)
• Flutter version 1.22.5 at /Users/tahatesser/Code/flutter_stable
• Framework revision 7891006299 (5 weeks ago), 2020-12-10 11:54:40 -0800
• Engine revision ae90085a84
• Dart version 2.10.4
[✓] Android toolchain - develop for Android devices (Android SDK version 30.0.3)
• Android SDK at /Volumes/Extreme/SDK
• Platform android-30, build-tools 30.0.3
• ANDROID_HOME = /Volumes/Extreme/SDK
• Java binary at: /Applications/Android Studio.app/Contents/jre/jdk/Contents/Home/bin/java
• Java version OpenJDK Runtime Environment (build 1.8.0_242-release-1644-b3-6915495)
• All Android licenses accepted.
[✓] Xcode - develop for iOS and macOS (Xcode 12.3)
• Xcode at /Volumes/Extreme/Xcode.app/Contents/Developer
• Xcode 12.3, Build version 12C33
• CocoaPods version 1.10.1
[!] Android Studio (version 4.1)
• Android Studio at /Applications/Android Studio.app/Contents
✗ Flutter plugin not installed; this adds Flutter specific functionality.
✗ Dart plugin not installed; this adds Dart specific functionality.
• Java version OpenJDK Runtime Environment (build 1.8.0_242-release-1644-b3-6915495)
[✓] VS Code (version 1.52.1)
• VS Code at /Applications/Visual Studio Code.app/Contents
• Flutter extension version 3.18.1
[✓] Connected device (1 available)
• Taha’s iPhone (mobile) • 00008020-001059882212002E • ios • iOS 14.3
! Doctor found issues in 1 category. Thank you |
Fix has been merged with flutter/plugins#3406. |
This thread has been automatically locked since there has not been any recent activity after it was closed. If you are still experiencing a similar issue, please open a new bug, including the output of |
Uh oh!
There was an error while loading. Please reload this page.
A PR to fix this issue has been submitted: flutter/plugins#3406
Currently, when starting a camera in the camera example app on iOS, the user's permission is asked the first time.
This causes the app to become inactive during camera initialization, causing the camera controller to be disposed.
As the camera controller is disposed during initialization, some properties cannot be fetched, resulting in an error being shown to the user:
The text was updated successfully, but these errors were encountered: