久しぶりの投稿です。
色々あって疲れていますが、なんとか余裕ができたので記事を書いていきます。なぜなら温泉に入って元気いっぱいだったからです🙌
やりたいこと
- カメラ権限を許可するかどうかによって画面出し分けをしたい
- 初期状態はローディング画面を表示させておきたい
必要なセットアップ
-
flutter_hooks
・・・カメラ権限周りの状態管理 -
permission_handler
・・・カメラ権限に必要なPackages
dependencies:
flutter_hooks: ^0.20.5
permission_handler: ^11.3.1
iOSのセットアップ
ios/Podfile
post_install do |installer|
installer.pods_project.targets.each do |target|
flutter_additional_ios_build_settings(target)
target.build_configurations.each do |config|
config.build_settings['GCC_PREPROCESSOR_DEFINITIONS'] ||= [
'$(inherited)',
## dart: [PermissionGroup.location, PermissionGroup.locationAlways, PermissionGroup.locationWhenInUse]
'PERMISSION_LOCATION=1',
## dart: PermissionGroup.microphone
'PERMISSION_MICROPHONE=1',
## dart: PermissionGroup.camera
'PERMISSION_CAMERA=1'
## dart: PermissionGroup.photos
'PERMISSION_PHOTOS=1',
]
end
end
end
ios/Runner/Info.plist
<key>NSCameraUsageDescription</key>
<string>camera</string>
Androidのセットアップ
gradle.properties
android.useAndroidX=true
android.enableJetifier=true
android/app/build.gradle
android {
compileSdkVersion 33
...
}
android/app/src/main/AndroidManifest.xml
<uses-permission android:name="android.permission.CAMERA" />
実装までの道のり
AppLifecycleListenerを定義
こちらは株式会社ゆめみで作成しているflutter-mobile-project-templateから引用しました。
詳しくはこちらを閲覧いただけると幸いです。
import 'dart:ui';
import 'package:flutter/material.dart';
/// A widget that listens to the lifecycle of the app.
/// Surround the widget you want to listen to with [CustomAppLifecycleListener].
class CustomAppLifecycleListener extends StatefulWidget {
const CustomAppLifecycleListener({
required Widget child,
VoidCallback? onResume,
VoidCallback? onInactive,
VoidCallback? onHide,
VoidCallback? onShow,
VoidCallback? onPause,
VoidCallback? onRestart,
VoidCallback? onDetach,
Future<AppExitResponse> Function()? onExitRequested,
void Function(AppLifecycleState state)? onStateChange,
super.key,
}) : _child = child,
_onResume = onResume,
_onInactive = onInactive,
_onHide = onHide,
_onShow = onShow,
_onPause = onPause,
_onRestart = onRestart,
_onDetach = onDetach,
_onExitRequested = onExitRequested,
_onStateChange = onStateChange;
final Widget _child;
final VoidCallback? _onResume;
final VoidCallback? _onInactive;
final VoidCallback? _onHide;
final VoidCallback? _onShow;
final VoidCallback? _onPause;
final VoidCallback? _onRestart;
final VoidCallback? _onDetach;
final Future<AppExitResponse> Function()? _onExitRequested;
final void Function(AppLifecycleState state)? _onStateChange;
@override
State<CustomAppLifecycleListener> createState() =>
_CustomAppLifecycleListenerState();
}
class _CustomAppLifecycleListenerState
extends State<CustomAppLifecycleListener> {
late final AppLifecycleListener _appLifecycleListener;
@override
void initState() {
_appLifecycleListener = AppLifecycleListener(
onResume: widget._onResume,
onInactive: widget._onInactive,
onHide: widget._onHide,
onShow: widget._onShow,
onPause: widget._onPause,
onRestart: widget._onRestart,
onDetach: widget._onDetach,
onExitRequested: widget._onExitRequested,
onStateChange: widget._onStateChange,
);
super.initState();
}
@override
void dispose() {
_appLifecycleListener.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return widget._child;
}
}
実装
import 'package:cores_core/util.dart';
import 'package:flutter/material.dart';
import 'package:flutter_hooks/flutter_hooks.dart';
import 'package:permission_handler/permission_handler.dart';
class CameraPermissionScreen extends HookWidget {
const CameraPermissionScreen({super.key});
@override
Widget build(BuildContext context) {
final isInitialized = useState(false);
final isCameraPermissionGranted = useState(false);
useEffect(
() {
WidgetsBinding.instance.addPostFrameCallback((_) async {
final currentPermissionStatus = await Permission.camera.status;
if (currentPermissionStatus.isGranted) {
isCameraPermissionGranted.value = true;
isInitialized.value = true;
return;
}
final newPermissionStatus = await Permission.camera.request();
isCameraPermissionGranted.value = newPermissionStatus.isGranted;
isInitialized.value = true;
});
return;
},
[],
);
return CustomAppLifecycleListener(
onResume: () async {
if (!isInitialized.value) {
// Note: カメラ使用権限の初回チェックが完了していない場合は何もしない
return;
}
final newPermissionStatus = await Permission.camera.status;
isCameraPermissionGranted.value = newPermissionStatus.isGranted;
},
child: Scaffold(
body: isInitialized.value
? isCameraPermissionGranted.value
? Text('カメラ権限オン')
: Text('カメラ権限オフ')
: Text('初期状態'),
),
);
}
}
最後に
少しでもお役に立てれば嬉しいです🙌