Исключение разрешения камеры на iOS в проекте флаттераIOS

Программируем под IOS
Ответить
Anonymous
 Исключение разрешения камеры на iOS в проекте флаттера

Сообщение Anonymous »

Я постоянно получаю следующее исключение во Flutter, когда пытаюсь открыть ReaderWidget этого примера из библиотеки zxing:
[ERROR:flutter/runtime/dart_vm_initializer.cc(41)] Unhandled Exception: CameraException(channel-error, Unable to establish connection on channel: "dev.flutter.pigeon.camera_avfoundation.CameraApi.getAvailableCameras".)
#0 AVFoundationCamera.availableCameras (package:camera_avfoundation/src/avfoundation_camera.dart:76:7)

#1 _ReaderWidgetState.initStateAsync. (package:flutter_zxing/src/ui/reader_widget.dart:199:29)


Следующая часть выдает исключение (ссылка на пакет на github):
@override
Future availableCameras() async {
try {
return (await _hostApi.getAvailableCameras())
// See comment in messages.dart for why this is safe.
.map((PlatformCameraDescription? c) => c!)
.map(cameraDescriptionFromPlatform)
.toList();
} on PlatformException catch (e) {
throw CameraException(e.code, e.message);
}
}

Аналогичное исключение возникает, когда я пытаюсь получить доступ к медиатеке.
Я обнаружил, что мне нужно добавить следующие строки в info.plist, что я и сделал:
NSPhotoLibraryUsageDescription
We need photo library access to scan barcodes
NSCameraUsageDescription
We need to access your camera for scanning QR codes

Когда я открываю XCode -> Runner -> Runner -> Info, я также вижу перечисленные записи и послесловия, которые я успешно выполнил, флаттер сборки ios.
Кроме того, при использовании приложения мне никогда не предлагается предоставить доступ. Я просто открываю экран, где должна быть камера, и вижу ошибку.
Когда я скачиваю и устанавливаю пример, все работает как положено. Появляется всплывающее окно, и я вижу опцию «Камера» в настройках приложения на моем телефоне. Я также пробовал скопировать Info.plist из примера 1:1, но это тоже не помогает.
Есть идеи, как заставить работать разрешения или какие дополнительные шаги Мне нужно запросить разрешение?
Вот код моего компонента:

class SetupStepScanQrCode extends StatefulWidget {
final SetupStepperWidget setupStepper;

const SetupStepScanQrCode(this.setupStepper, {Key? key}) : super(key: key);

@override
State createState() => SetupStepScanQrCodeState();
}

class SetupStepScanQrCodeState extends State {
late final SetupStepperWidget setupStepper;
Uint8List? createdCodeBytes;

Code? result;
Codes? multiResult;

bool isMultiScan = false;

bool showDebugInfo = true;
int successScans = 0;
int failedScans = 0;

bool isManualProcess = false;
bool qrCodeScanned = false;
String? deviceName;
String? devicePassword;

@override
void initState() {
super.initState();
setupStepper = widget.setupStepper;
}

void setDeviceDetails(name, password) {
deviceName = name;
devicePassword = password;
}

void connect() {
setupStepper.setDeviceDetails(deviceName, devicePassword);
setupStepper.next();
}

Future _initializeReaderWidget() async {
try {
return ReaderWidget(
onScan: _onScanSuccess,
onScanFailure: _onScanFailure,
onMultiScan: _onMultiScanSuccess,
onMultiScanFailure: _onMultiScanFailure,
onMultiScanModeChanged: _onMultiScanModeChanged,
onControllerCreated: _onControllerCreated,
isMultiScan: isMultiScan,
scanDelay: Duration(milliseconds: isMultiScan ? 50 : 500),
resolution: ResolutionPreset.high,
lensDirection: CameraLensDirection.back,
flashOnIcon: const Icon(Icons.flash_on),
flashOffIcon: const Icon(Icons.flash_off),
flashAlwaysIcon: const Icon(Icons.flash_on),
flashAutoIcon: const Icon(Icons.flash_auto),
galleryIcon: const Icon(Icons.photo_library),
toggleCameraIcon: const Icon(Icons.switch_camera),
actionButtonsBackgroundBorderRadius: BorderRadius.circular(10),
actionButtonsBackgroundColor: Colors.black.withOpacity(0.5),
);
} catch (e) {
print(e);
return Center(child: Text('Error initializing camera (caught).'));
}
}

@override
Widget build(BuildContext context) {
final isCameraSupported = defaultTargetPlatform == TargetPlatform.iOS ||
defaultTargetPlatform == TargetPlatform.android;

return BaseLayout(
stepTitle,
SizedBox(
height: 300,
width: 300,
child: Stack(
children: [
FutureBuilder(
future: _initializeReaderWidget(),
builder: (context, snapshot) {
if (snapshot.connectionState == ConnectionState.done) {
if (snapshot.hasError) {
// Display error message or a fallback UI
return Center(
child: Text(
'Error initializing camera (snapshot.hasError)'));
}
// Return the ReaderWidget or error widget if no error
return snapshot.data!;
} else {
// Return a loading indicator while waiting for the future to complete
return Center(child: CircularProgressIndicator());
}
},
),
if (showDebugInfo)
DebugInfoWidget(
successScans: successScans,
failedScans: failedScans,
error: isMultiScan ? multiResult?.error : result?.error,
duration: isMultiScan
? multiResult?.duration ?? 0
: result?.duration ?? 0,
onReset: _onReset,
),
],
),
),
description: stepDescription,
content: Column(
children: stepContent,
),
);
}

String get stepTitle {
if (isManualProcess) {
return 'Bluetoothverbindung herstellen';
}
return 'Scan QR-Code';
}

String get stepImage {
if (isManualProcess) {
return manualSetupBluetooth;
}
return cameraPlaceholder;
}

String get stepDescription {
if (isManualProcess) {
return '';
}
return 'Hier eine Anleitung.';
}

List get stepContent {
if (isManualProcess) {
return [SetupStepSubBluetooth(this)];
}
return [
qrCodeScanned
? Text(
'QR-Code erkannt',
textAlign: TextAlign.center,
style: Theme.of(context)
.textTheme
.displayMedium!
.copyWith(color: Theme.of(context).colorScheme.primary),
)
: Text(
'Kein QR-Code vorhanden?',
textAlign: TextAlign.center,
style: Theme.of(context)
.textTheme
.displaySmall!
.copyWith(color: const Color(0xFF7C7C7C)),
),
SizedBox(height: qrCodeScanned ? paddingMain * 2 : paddingMain / 2),
qrCodeScanned
? FilledButton(
onPressed: () {
// TODO: Disable if devicename and password are empty
connect();
},
child: const Text('Jetzt verbinden'),
)
: OutlinedButton(
onPressed: () {
setState(() {
isManualProcess = true;
});
},
child: const Text('Manuelle Eingabe starten'),
),
];
}

void _onControllerCreated(_, Exception? error) {
if (error != null) {
// Handle permission or unknown errors
_showMessage(context, 'Error: $error');
}
}

_onScanSuccess(Code? code) {
setState(() {
successScans++;
result = code;
});
}

_onScanFailure(Code? code) {
setState(() {
failedScans++;
result = code;
});
if (code?.error?.isNotEmpty == true) {
_showMessage(context, 'Error: ${code?.error}');
}
}

_onMultiScanSuccess(Codes codes) {
setState(() {
successScans++;
multiResult = codes;
});
}

_onMultiScanFailure(Codes result) {
setState(() {
failedScans++;
multiResult = result;
});
if (result.codes.isNotEmpty == true) {
_showMessage(context, 'Error: ${result.codes.first.error}');
}
}

_onMultiScanModeChanged(bool isMultiScan) {
setState(() {
this.isMultiScan = isMultiScan;
});
}

_showMessage(BuildContext context, String message) {
ScaffoldMessenger.of(context).hideCurrentSnackBar();
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(content: Text(message)),
);
}

_onReset() {
setState(() {
successScans = 0;
failedScans = 0;
});
}
}

Вот мой Info.plist (который - согласно XCode -> Targets Runner -> Настройки сборки -> Файл Info.plist используется при отладке, профилировании и выпуске)




CADisableMinimumFrameDurationOnPhone

CFBundleDevelopmentRegion
$(DEVELOPMENT_LANGUAGE)
CFBundleDisplayName
COMPANY Myapplication
CFBundleExecutable
$(EXECUTABLE_NAME)
CFBundleIdentifier
$(PRODUCT_BUNDLE_IDENTIFIER)
CFBundleInfoDictionaryVersion
6.0
CFBundleName
myapplication
CFBundlePackageType
APPL
CFBundleShortVersionString
$(FLUTTER_BUILD_NAME)
CFBundleSignature
????
CFBundleURLTypes


CFBundleTypeRole
Editor
CFBundleURLName
auth0
CFBundleURLSchemes

$(PRODUCT_BUNDLE_IDENTIFIER)



CFBundleVersion
$(FLUTTER_BUILD_NUMBER)
LSRequiresIPhoneOS

NSBluetoothAlwaysUsageDescription
Our app uses Bluetooth to configure your WiFi credentials.
UIApplicationSupportsIndirectInputEvents

UILaunchStoryboardName
LaunchScreen
UIMainStoryboardFile
Main
NSPhotoLibraryUsageDescription
We need photo library access to scan barcodes
NSCameraUsageDescription
We need to access your camera for scanning QR codes
UISupportedInterfaceOrientations

UIInterfaceOrientationPortrait
UIInterfaceOrientationLandscapeLeft
UIInterfaceOrientationLandscapeRight

UISupportedInterfaceOrientations~ipad

UIInterfaceOrientationPortrait
UIInterfaceOrientationPortraitUpsideDown
UIInterfaceOrientationLandscapeLeft
UIInterfaceOrientationLandscapeRight





Подробнее здесь: https://stackoverflow.com/questions/786 ... er-project
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «IOS»