我正在构建一个需要摄像头的应用程序,当我在我的设备上测试它时,一切都很好,直到我打开摄像头。
当我完成注册过程并从底部导航打开相机时,应用程序崩溃并收到错误消息:
Lost connection to device.
此错误没有其他详细信息,因此我很难找到问题的确切来源。有什么想法吗?
class CameraScreen extends StatefulWidget {
@override
_CameraScreenState createState() => _CameraScreenState();
}
class _CameraScreenState extends State {
CameraController controller;
List cameras;
int selectedCameraIndex;
String imgPath;
@override
void initState() {
super.initState();
availableCameras().then((availableCameras) {
cameras = availableCameras;
if (cameras.length > 0) {
setState(() {
selectedCameraIndex = 0;
});
_initCameraController(cameras[selectedCameraIndex]).then((void v) {});
} else {
print('No camera available');
}
}).catchError((err) {
print('Error :${err.code}Error message : ${err.message}');
});
}
Future _initCameraController(CameraDescription cameraDescription) async {
if (controller != null) {
await controller.dispose();
}
controller = CameraController(cameraDescription, ResolutionPreset.high);
controller.addListener(() {
if (mounted) {
setState(() {});
}
if (controller.value.hasError) {
print('Camera error ${controller.value.errorDescription}');
}
});
try {
await controller.initialize();
} on CameraException catch (e) {
_showCameraException(e);
}
if (mounted) {
setState(() {});
}
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: Container(
child: SafeArea(
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: <Widget>[
Expanded(
flex: 1,
child: _cameraPreviewWidget(),
),
Align(
alignment: Alignment.bottomCenter,
child: Container(
height: 120,
width: double.infinity,
padding: EdgeInsets.all(15),
color: Colors.black,
child: Row(
mainAxisAlignment: MainAxisAlignment.start,
children: <Widget>[
_cameraToggleRowWidget(),
_cameraControlWidget(context),
Spacer()
],
),
),
)
],
),
),
),
);
}
/// Display Camera preview.
Widget _cameraPreviewWidget() {
if (controller == null || !controller.value.isInitialized) {
return const Text(
'Loading',
style: TextStyle(
color: Colors.white,
fontSize: 20.0,
fontWeight: FontWeight.w900,
),
);
}
return AspectRatio(
aspectRatio: controller.value.aspectRatio,
child: CameraPreview(controller),
);
}
/// Display the control bar with buttons to take pictures
Widget _cameraControlWidget(context) {
return Expanded(
child: Align(
alignment: Alignment.center,
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
mainAxisSize: MainAxisSize.max,
children: <Widget>[
FloatingActionButton(
child: Icon(
Icons.camera,
color: Colors.black,
),
backgroundColor: Colors.white,
onPressed: () {
_onCapturePressed(context);
},
)
],
),
),
);
}
/// Display a row of toggle to select the camera (or a message if no camera is available).
Widget _cameraToggleRowWidget() {
if (cameras == null || cameras.isEmpty) {
return Spacer();
}
CameraDescription selectedCamera = cameras[selectedCameraIndex];
CameraLensDirection lensDirection = selectedCamera.lensDirection;
return Expanded(
child: Align(
alignment: Alignment.centerLeft,
child: FlatButton.icon(
onPressed: _onSwitchCamera,
icon: Icon(
_getCameraLensIcon(lensDirection),
color: Colors.white,
size: 24,
),
label: Text(
'${lensDirection.toString().substring(lensDirection.toString().indexOf('.') + 1).toUpperCase()}',
style: TextStyle(color: Colors.white, fontWeight: FontWeight.w500),
),
),
),
);
}
IconData _getCameraLensIcon(CameraLensDirection direction) {
switch (direction) {
case CameraLensDirection.back:
return CupertinoIcons.switch_camera;
case CameraLensDirection.front:
return CupertinoIcons.switch_camera_solid;
case CameraLensDirection.external:
return Icons.camera;
default:
return Icons.device_unknown;
}
}
void _showCameraException(CameraException e) {
String errorText = 'Error:${e.code}\nError message : ${e.description}';
print(errorText);
}
void _onCapturePressed(context) async {
try {
final path =
join((await getTemporaryDirectory()).path, '${DateTime.now()}.png');
await controller.takePicture();
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => PreviewScreen(
imgPath: path,
)),
);
} catch (e) {
_showCameraException(e);
}
}
void _onSwitchCamera() {
selectedCameraIndex =
selectedCameraIndex < cameras.length - 1 ? selectedCameraIndex + 1 : 0;
CameraDescription selectedCamera = cameras[selectedCameraIndex];
_initCameraController(selectedCamera);
}
}
答案 0 :(得分:1)
请确保以下两点:
在安卓清单中添加 android:requestLegacyExternalStorage="true"
在 ios info.plist(位于 /ios/Runner/Info.plist)中以键(粗体)和字符串格式添加这些行
NSPhotoLibraryUsageDescription
此应用需要访问照片库。
NSMicrophoneUsageDescription
此应用不需要使用麦克风。
NSCameraUsageDescription
此应用需要访问相机。