Flutter-permission-handler: App crashes if permissions disabled manually from app settings

Created on 31 Oct 2019  路  2Comments  路  Source: Baseflow/flutter-permission-handler

馃悰 Bug Report


App crashes if any permission is disabled manually through the app's settings.

猸愶笍 replicable only in debug mode 猸愶笍

Expected behavior

The app shouldn't be affected

Reproduction steps

  1. First, grant a permission using PermissionHandler().requestPermissions
  2. Open the app settings using the provided function PermissionHandler().openAppSettings()
  3. Disable the granted permission in step 1 from the app's permissions through its settings (While the app is running)
  4. The app stops functioning properly (It turned black in my case)
  5. This doesn't happen if a permission is enabled

I tried it for storage permission


can be replicated in the example app

import 'dart:io';

import 'package:flutter/material.dart';
import 'package:permission_handler/permission_handler.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: const Text('Plugin example app'),
          actions: <Widget>[
            IconButton(
              icon: const Icon(Icons.settings),
              onPressed: () {
                PermissionHandler().openAppSettings().then((bool hasOpened) =>
                    debugPrint('App Settings opened: ' + hasOpened.toString()));
              },
            )
          ],
        ),
        body: Center(
          child: ListView(
              children: PermissionGroup.values
                  .where((PermissionGroup permission) {
                    if (Platform.isIOS) {
                      return permission != PermissionGroup.unknown &&
                          permission != PermissionGroup.sms &&
                          permission != PermissionGroup.storage &&
                          permission !=
                              PermissionGroup.ignoreBatteryOptimizations;
                    } else {
                      return permission != PermissionGroup.unknown &&
                          permission != PermissionGroup.mediaLibrary &&
                          permission != PermissionGroup.photos &&
                          permission != PermissionGroup.reminders;
                    }
                  })
                  .map((PermissionGroup permission) =>
                      PermissionWidget(permission))
                  .toList()),
        ),
      ),
    );
  }
}

class PermissionWidget extends StatefulWidget {
  const PermissionWidget(this._permissionGroup);

  final PermissionGroup _permissionGroup;

  @override
  _PermissionState createState() => _PermissionState(_permissionGroup);
}

class _PermissionState extends State<PermissionWidget> {
  _PermissionState(this._permissionGroup);

  final PermissionGroup _permissionGroup;
  PermissionStatus _permissionStatus = PermissionStatus.unknown;

  @override
  void initState() {
    super.initState();

    _listenForPermissionStatus();
  }

  void _listenForPermissionStatus() {
    final Future<PermissionStatus> statusFuture =
        PermissionHandler().checkPermissionStatus(_permissionGroup);

    statusFuture.then((PermissionStatus status) {
      setState(() {
        _permissionStatus = status;
      });
    });
  }

  Color getPermissionColor() {
    switch (_permissionStatus) {
      case PermissionStatus.denied:
        return Colors.red;
      case PermissionStatus.granted:
        return Colors.green;
      default:
        return Colors.grey;
    }
  }

  @override
  Widget build(BuildContext context) {
    return ListTile(
      title: Text(_permissionGroup.toString()),
      subtitle: Text(
        _permissionStatus.toString(),
        style: TextStyle(color: getPermissionColor()),
      ),
      trailing: IconButton(
          icon: const Icon(Icons.info),
          onPressed: () {
            checkServiceStatus(context, _permissionGroup);
          }),
      onTap: () {
        requestPermission(_permissionGroup);
      },
    );
  }

  void checkServiceStatus(BuildContext context, PermissionGroup permission) {
    PermissionHandler()
        .checkServiceStatus(permission)
        .then((ServiceStatus serviceStatus) {
      final SnackBar snackBar =
          SnackBar(content: Text(serviceStatus.toString()));

      Scaffold.of(context).showSnackBar(snackBar);
    });
  }

  Future<void> requestPermission(PermissionGroup permission) async {
    final List<PermissionGroup> permissions = <PermissionGroup>[permission];
    final Map<PermissionGroup, PermissionStatus> permissionRequestResult =
        await PermissionHandler().requestPermissions(permissions);

    setState(() {
      print(permissionRequestResult);
      _permissionStatus = permissionRequestResult[permission];
      print(_permissionStatus);
    });
  }
}

Configuration

Version: ^3.3.0

Platform:

:robot: Android

Most helpful comment

I think this issue is not related to PermissionHandler itself. I remember that I encounter this issue without any plugins added at all. Changing the persmissions disconnects the app.

All 2 comments

I think this issue is not related to PermissionHandler itself. I remember that I encounter this issue without any plugins added at all. Changing the persmissions disconnects the app.

Cool. The OS must be doing it, it should restart instead 馃ズ

Was this page helpful?
0 / 5 - 0 ratings

Related issues

jaleelmeemo picture jaleelmeemo  路  5Comments

pedromassango picture pedromassango  路  4Comments

marcelderkskarlmax picture marcelderkskarlmax  路  5Comments

shinriyo picture shinriyo  路  5Comments

igoriuz picture igoriuz  路  5Comments