Reputation: 41
I am developing a custom object detection app for Android using the camera package in conjunction with tflite. When the screen loads, it asks the user for camera and microphone permission using the permission_handler package. I'm also using a ChangeNotifier class to store the results after asking the user for permission. Then, depending on whether the user accepts these conditions, I'm conditionally rendering widgets. Now, there are a few cases here:
a. Neither is granted → request for both permission if it isn't permanently denied and if it is then ask the user to manually grant it from settings
b. Permission for the camera is granted, but the user denied mic permission → request for mic permission if it isn't permanently denied and if it is then ask the user to manually grant it from settings
c. Permission for the mic is granted, but camera permission is denied → request for camera permission if it isn't permanently denied and if it is then ask the user to manually grant it from settings
d. Neither is granted → request for both permission if they aren't permanently denied and if they are then ask the user to manually grant them from settings
Here is my current implementation.
The problem is that even when the user grants both the permissions, it shows: 'Camera permission was denied!', 'Request camera permission' widget. So, how can I handle all four different cases in a more elegant way?
Upvotes: 0
Views: 147
Reputation: 1399
class _LiveFeedState extends State<LiveFeed> with WidgetsBindingObserver {
Widget? errWidget;
@override
void didChangeAppLifecycleState(AppLifecycleState state) {
super.didChangeAppLifecycleState(state);
switch (state) {
case AppLifecycleState.resumed:
log("App Resumed");
_checkCameraPermissionStatus();
break;
case AppLifecycleState.inactive:
log("App Inactive");
break;
case AppLifecycleState.paused:
log("App Paused");
break;
case AppLifecycleState.detached:
log("App Detached");
break;
}
}
@override
void dispose() {
super.dispose();
WidgetsBinding.instance.removeObserver(this);
}
@override
void initState() {
super.initState();
WidgetsBinding.instance.addObserver(this);
}
Widget bodyWidget() {
return CameraFeed...;
}
Widget permissionScreen(Function onPressedHandler, String titleText, String buttonText) {
return Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(titleText),
ElevatedButton(
onPressed: () {
onPressedHandler();
},
child: Text(buttonText)),
],
);
}
Future<void> _checkCameraPermissionStatus() async {
var status = await Permission.camera.request().then((value) => value);
switch (status) {
case PermissionStatus.granted:
errWidget = await _checkMicPermissionStatus();
setState(() {});
break;
case PermissionStatus.denied:
setState(() {
errWidget = permissionScreen(_checkCameraPermissionStatus, 'Camera permission was denied!', 'Request camera permission');
});
break;
case PermissionStatus.permanentlyDenied:
setState(() {
errWidget = permissionScreen(openAppSettings, 'Camera permission was permanently denied! Open app setings and manually grant permission', 'Open app settings');
});
break;
default:
errWidget = await _checkMicPermissionStatus();
setState(() {});
break;
}
}
Future<Widget> _checkMicPermissionStatus() async {
var status = await Permission.microphone.request().then((value) => value);
switch (status) {
case PermissionStatus.granted:
return bodyWidget();
case PermissionStatus.denied:
return permissionScreen(_checkCameraPermissionStatus, 'Microphone permission was denied!', 'Request Microphone permission');
case PermissionStatus.permanentlyDenied:
return permissionScreen(openAppSettings, 'Microphone permission was permanently denied! Open app setings and manually grant permission', 'Open app settings');
default:
return bodyWidget();
}
}
@override
Widget build(BuildContext context) {
return SafeArea(
child: Scaffold(
appBar: isPortrait
? AppBar(
title: const Text("SpotHole"),
)
: null,
body: FutureBuilder(
future: Future.wait([Permission.camera.status, Permission.microphone.status]),
builder: (BuildContext context, AsyncSnapshot<List<PermissionStatus>> snapshot) {
if (snapshot.hasData) {
if (snapshot.data![0] == PermissionStatus.granted ||
snapshot.data![0] == PermissionStatus.limited ||
snapshot.data![1] == PermissionStatus.granted ||
snapshot.data![1] == PermissionStatus.limited) {
return bodyWidget();
} else {
if (errWidget != null) {
return errWidget!;
} else {
if (snapshot.data![0] != PermissionStatus.granted || snapshot.data![0] != PermissionStatus.limited) {
return permissionScreen(_checkCameraPermissionStatus, 'Camera permission was denied!', 'Request camera permission');
} else {
return permissionScreen(_checkCameraPermissionStatus, 'Microphone permission was denied!', 'Request Microphone permission');
}
}
}
} else {
return const CircularProgressIndicator.adaptive();
}
},
)));
}
}
Upvotes: 0