Flutter:如何实时监听权限

Posted

技术标签:

【中文标题】Flutter:如何实时监听权限【英文标题】:Flutter: How do I listen to permissions real time 【发布时间】:2019-08-21 21:41:22 【问题描述】:

我正在开发一个应用程序,我想在其中持续收听位置和电池权限。

示例场景:

    用户打开应用 授予权限访问 进入设置并撤销权限 再次打开应用程序 应用显示一个snackbar,通知用户权限已被撤销。

我是初学者,我正在使用flutter-permissions-handler,下面的代码显示了我的用法。

    _listenForLocationPermission() 
    Future<PermissionStatus> status = PermissionHandler()
        .checkPermissionStatus(PermissionGroup.locationWhenInUse);
    status.then((PermissionStatus status) 
      setState(() 
        _permissionStatus = status;
        if (_permissionStatus != PermissionStatus.granted) 
          _renderOfflineSnackbar('Offline');
        
      );
    );
  

对上述任何建议表示赞赏。

【问题讨论】:

【参考方案1】:

我在同一条船上,发现这行得通

您需要使用 WidgetsBindingObserver 扩展您的类

class _AppState extends State<App> with WidgetsBindingObserver 
  PermissionStatus _status;
  ...
  ...

然后将这些方法添加到您的类中

@override
  void dispose() 
    WidgetsBinding.instance.removeObserver(this);
    super.dispose();
  

  // check permissions when app is resumed
  // this is when permissions are changed in app settings outside of app
  void didChangeAppLifecycleState(AppLifecycleState state) 
    if (state == AppLifecycleState.resumed) 
      PermissionHandler()
          .checkPermissionStatus(PermissionGroup.locationWhenInUse)
          .then(_updateStatus);
    
  

我的完整代码如下,但我没有包含构建小部件以保持简短

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

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

class App extends StatefulWidget 
  @override
  _AppState createState() => _AppState();


class _AppState extends State<App> with WidgetsBindingObserver 
  PermissionStatus _status;

  // check permissions
  @override
  void initState() 
    super.initState();
    WidgetsBinding.instance.addObserver(this);
    PermissionHandler() // Check location permission has been granted
        .checkPermissionStatus(PermissionGroup
            .locationWhenInUse) //check permission returns a Future
        .then(_updateStatus); // handling in callback to prevent blocking UI
  

  @override
  void dispose() 
    WidgetsBinding.instance.removeObserver(this);
    super.dispose();
  

  // check permissions when app is resumed
  // this is when permissions are changed in app settings outside of app
  void didChangeAppLifecycleState(AppLifecycleState state) 
    if (state == AppLifecycleState.resumed) 
      PermissionHandler()
          .checkPermissionStatus(PermissionGroup.locationWhenInUse)
          .then(_updateStatus);
    
  

override
  Widget build(BuildContext context) 
    return MaterialApp(  
    ...
    ...


void _updateStatus(PermissionStatus status) 
    if (status != _status) 
      // check status has changed
      setState(() 
        _status = status; // update
      );
     else 
      if (status != PermissionStatus.granted) 
        PermissionHandler().requestPermissions(
            [PermissionGroup.locationWhenInUse]).then(_onStatusRequested);
      
      
    
  

  void _askPermission() 
    PermissionHandler().requestPermissions(
        [PermissionGroup.locationWhenInUse]).then(_onStatusRequested);
  

  void _onStatusRequested(Map<PermissionGroup, PermissionStatus> statuses) 
    final status = statuses[PermissionGroup.locationWhenInUse];
    if (status != PermissionStatus.granted) 
      // On ios if "deny" is pressed, open App Settings
      PermissionHandler().openAppSettings();
     else 
      _updateStatus(status);
    
  

希望对你有帮助

【讨论】:

非常感谢您的回答。我会试试这个并报告。 你知道你救了我多少天的头痛吗???祝福你!【参考方案2】:

空安全码:

permission_handler: ^8.0.0+2

这个想法是在状态恢复时检查应用程序生命周期回调中的权限。这是帮助您开始的最少代码。

class _FooPageState extends State<FooPage> with WidgetsBindingObserver 
  final Permission _permission = Permission.location;
  bool _checkingPermission = false;

  @override
  void initState() 
    super.initState();
    WidgetsBinding.instance!.addObserver(this);
  

  @override
  void dispose() 
    WidgetsBinding.instance!.removeObserver(this);
    super.dispose();
  

  @override
  void didChangeAppLifecycleState(AppLifecycleState state) 
    super.didChangeAppLifecycleState(state);
    if (state == AppLifecycleState.resumed && !_checkingPermission) 
      _checkingPermission = true;
      _checkPermission(_permission).then((_) => _checkingPermission = false);
    
  

  Future<void> _checkPermission(Permission permission) async 
    final status = await permission.request();
    if (status == PermissionStatus.granted) 
      print('Permission granted');
     else if (status == PermissionStatus.denied) 
      print('Permission denied. Show a dialog and again ask for the permission');
     else if (status == PermissionStatus.permanentlyDenied) 
      print('Take the user to the settings page.');
    
  

  @override
  Widget build(BuildContext context) => Scaffold();

【讨论】:

有没有办法在不请求许可的情况下检查永久拒绝? @HaidarMehsen 不,这不可能。

以上是关于Flutter:如何实时监听权限的主要内容,如果未能解决你的问题,请参考以下文章

在 Flutter 中监听 Firestore 集合及其子集合

Flutter 真正可以监听屏幕旋转的插件

Flutter(Web)如何监听javascript事件或将javascript数据传递给flutter?

如何向 Flutter.EventChannel 添加多个监听器?

从 Flutter 应用程序中的 Firebase 实时数据库事件获取父节点

如何在 Flutter 应用中监听和处理 POST 请求