Make camera optional on Android

This commit is contained in:
Adam Velebil 2022-11-08 11:50:36 +01:00
parent b2de63ae3c
commit 5ad830f191
No known key found for this signature in database
GPG Key ID: AC6D6B9D715FC084
7 changed files with 36 additions and 17 deletions

View File

@ -18,6 +18,7 @@ package com.yubico.authenticator
import android.content.*
import android.content.pm.PackageManager
import android.hardware.camera2.CameraManager
import android.hardware.usb.UsbDevice
import android.hardware.usb.UsbManager
import android.nfc.NfcAdapter
@ -328,6 +329,13 @@ class MainActivity : FlutterFragmentActivity() {
}
result.success(true)
}
"hasCamera" -> {
val cameraService =
getSystemService(Context.CAMERA_SERVICE) as CameraManager
result.success(
cameraService.cameraIdList.isNotEmpty()
)
}
else -> Log.w(TAG, "Unknown app method: ${methodCall.method}")
}
}

View File

@ -3,6 +3,6 @@
<uses-feature android:name="android.hardware.camera.any" />
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.CAMERA" android:required="false"/>
</manifest>

View File

@ -18,6 +18,10 @@ import 'package:flutter/services.dart';
const appMethodsChannel = MethodChannel('app.methods');
Future<bool> getHasCamera() async {
return await appMethodsChannel.invokeMethod('hasCamera');
}
Future<int> getAndroidSdkVersion() async {
return await appMethodsChannel.invokeMethod('getAndroidSdkVersion');
}

View File

@ -71,6 +71,7 @@ Future<Widget> initialize() async {
windowStateProvider.overrideWithProvider(androidWindowStateProvider),
clipboardProvider.overrideWithProvider(androidClipboardProvider),
androidSdkVersionProvider.overrideWithValue(await getAndroidSdkVersion()),
androidHasCameraProvider.overrideWithValue(await getHasCamera()),
supportedThemesProvider
.overrideWithProvider(androidSupportedThemesProvider)
],

View File

@ -64,6 +64,8 @@ class _AndroidClipboard extends AppClipboard {
final androidSdkVersionProvider = Provider<int>((ref) => -1);
final androidHasCameraProvider = Provider<bool>((ref) => false);
final androidSupportedThemesProvider = StateProvider<List<ThemeMode>>((ref) {
if (ref.read(androidSdkVersionProvider) < 29) {
// the user can select from light or dark theme of the app

View File

@ -16,18 +16,19 @@
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:yubico_authenticator/android/state.dart';
import 'package:yubico_authenticator/cancellation_exception.dart';
import 'package:yubico_authenticator/core/state.dart';
import '../../oath/models.dart';
import 'message_page.dart';
import 'device_error_screen.dart';
import '../models.dart';
import '../state.dart';
import '../message.dart';
import '../../fido/views/fido_screen.dart';
import '../../oath/models.dart';
import '../../oath/views/add_account_page.dart';
import '../../oath/views/oath_screen.dart';
import '../message.dart';
import '../models.dart';
import '../state.dart';
import 'device_error_screen.dart';
import 'message_page.dart';
class MainPage extends ConsumerWidget {
const MainPage({super.key});
@ -74,16 +75,18 @@ class MainPage extends ConsumerWidget {
tooltip: 'Add account',
onPressed: () async {
CredentialData? otpauth;
final scanner = ref.read(qrScannerProvider);
if (scanner != null) {
try {
final url = await scanner.scanQr();
if (url != null) {
otpauth = CredentialData.fromUri(Uri.parse(url));
if (ref.read(androidHasCameraProvider)) {
final scanner = ref.read(qrScannerProvider);
if (scanner != null) {
try {
final url = await scanner.scanQr();
if (url != null) {
otpauth = CredentialData.fromUri(Uri.parse(url));
}
} on CancellationException catch (_) {
// ignored - user cancelled
return;
}
} on CancellationException catch (_) {
// ignored - user cancelled
return;
}
}
await showBlurDialog(

View File

@ -20,6 +20,7 @@ import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_gen/gen_l10n/app_localizations.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:yubico_authenticator/android/state.dart';
import 'package:yubico_authenticator/widgets/delayed_visibility.dart';
import '../../app/message.dart';
@ -237,7 +238,7 @@ class _UnlockedViewState extends ConsumerState<_UnlockedView> {
action: capacity == null || capacity > used
? () async {
CredentialData? otpauth;
if (Platform.isAndroid) {
if (Platform.isAndroid && ref.read(androidHasCameraProvider)) {
final scanner = ref.read(qrScannerProvider);
if (scanner != null) {
final url = await scanner.scanQr();