Flutter 权限处理程序无法正常工作

Nza*_*ibe 1 permissions flutter

我正在尝试通过请求许可(正确显示对话框)并仅在授予时导航来从我的应用程序中获取用户的位置。正在permission_handler颤振中使用的库。我无法从设置磁贴菜单中获取位置小部件以打开,并且正在显示库中的权限状态permission.disabled

我已经为我的应用程序以编程方式打开了设置磁贴,它在下面的块中列出并处于活动状态:

void _requestPerms () async{
Map<PermissionGroup, PermissionStatus> statuses = await PermissionHandler().requestPermissions([
  PermissionGroup.locationWhenInUse, PermissionGroup.locationAlways
]);
final status = statuses[PermissionGroup.locationWhenInUse];
switch(status){
  case PermissionStatus.disabled:
    await PermissionHandler().openAppSettings();
    break;
}
_updateStatus(status);
Run Code Online (Sandbox Code Playgroud)

}

有人可以帮助我理解为什么尽管收到一次对话提示,但电话位置小部件没有打开以及如何导航到下一条路线,permission granted或者如果没有,则优雅地退出应用程序。谢谢。

完整代码:

import 'package:flutter/material.dart';
import 'package:eme_clone/utils/styles.dart';
import 'package:eme_clone/utils/constants.dart';
import 'package:permission_handler/permission_handler.dart';

class LocationDialog extends StatefulWidget {
  @override
   _LocationDialogState createState() => _LocationDialogState();
  }

class _LocationDialogState extends State<LocationDialog> {

PermissionStatus _status;

@override
void initState() {
  super.initState();
  PermissionHandler().checkPermissionStatus(PermissionGroup.locationWhenInUse)
    .then(_updateStatus);
}

@override
Widget build(BuildContext context) {
debugPrint('Location Status $_status');
return Scaffold(
  body: SafeArea(
      child: Column(
        children: <Widget>[
          Image.asset('assets/images/perm_icon_location.png'),
          Text(
            locationDialogHeader,
            style: locationHeaderStyle,
          ),
          Padding(
            padding: const EdgeInsets.all(10.0),
            child: Text(
              locationDialogBody,
              textAlign: TextAlign.center,
              style: locationTextBodyStyle,
            ),
          ),
          Expanded(
            child: Align(
              alignment: FractionalOffset.bottomCenter,
              child: Container(
                width: double.infinity,
                padding: EdgeInsets.all(10.0),
                child: RaisedButton(
                  color: Colors.black,
                  onPressed: _requestPerms,
                  padding: EdgeInsets.only(top: 15.0, bottom: 15.0),
                    child: Text(
                      allow,
                      style: allowBtnTextStyle,
                    ),
                  ),
                ),
              ),
            )
          ],
        )),
  );
}

void _updateStatus(PermissionStatus value) {
  setState(() {
    _status = value;
  });
}

void _requestPerms () async{
  Map<PermissionGroup, PermissionStatus> statuses = await PermissionHandler().requestPermissions([
  PermissionGroup.locationWhenInUse, PermissionGroup.locationAlways
]);
  final status = statuses[PermissionGroup.locationWhenInUse];
  switch(status){
    case PermissionStatus.disabled:
     await PermissionHandler().openAppSettings();
     break;
  }
  _updateStatus(status);
}
Run Code Online (Sandbox Code Playgroud)

}

Loï*_*kam 7

感谢您提供完整的代码。它使调试过程更快。

首先,您需要将以下内容添加到您的 android/app/src/main/AndroidManifest.xml 文件中。(标记前)

<!-- Permissions options for the `location` group -->
    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
    <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
    <uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION" />
Run Code Online (Sandbox Code Playgroud)

然后,您可以使用flutter_spinkit构建初始加载屏幕,同时等待用户许可。要在用户未授予权限时退出应用程序,请使用

SystemChannels.platform.invokeMethod('SystemNavigator.pop');
Run Code Online (Sandbox Code Playgroud)

要在请求获得批准后导航到下一个屏幕,请查看修改后的完整代码

import 'dart:async';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:permission_handler/permission_handler.dart';
import 'package:flutter_spinkit/flutter_spinkit.dart';

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: LocationDialog(),
    );
  }
}

class LocationDialog extends StatefulWidget {
  @override
  _LocationDialogState createState() => _LocationDialogState();
}

class _LocationDialogState extends State<LocationDialog>
    with SingleTickerProviderStateMixin {
  PermissionStatus _status;

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

  runFirst() async {


//await PermissionHandler()
//        .checkPermissionStatus(PermissionGroup.locationWhenInUse)
//        .then(_updateStatus);

 /* PermissionHandle() deprecated in permission_handler: ^5.0.0+hotfix.3 */

 await Permission.locationWhenInUse.status.then(_updateStatus);

    await _requestPerms();
    if (_status == PermissionStatus.granted) {
      Navigator.push(
          context, MaterialPageRoute(builder: (context) => NextPage()));
    } else if (_status == PermissionStatus.denied) {
      SystemChannels.platform.invokeMethod('SystemNavigator.pop');
    }
  }

  @override
  Widget build(BuildContext context) {
    return SpinKitFadingCircle(
      itemBuilder: (BuildContext context, int index) {
        return DecoratedBox(
          decoration: BoxDecoration(
            color: index.isEven ? Colors.red : Colors.green,
          ),
        );
      },
    );
  }

  void _requestPerms() async {
    Map<Permission, PermissionStatus> statuses = await 
        [
      Permission.locationWhenInUse,
      Permission.locationAlways
    ].request();



   if (await Permission.locationWhenInUse.serviceStatus.isEnabled) {
        _updateStatus(PermissionStatus.enable);
        openAppSettings();
   }

  //  switch (status) {
  //    case PermissionStatus.disabled:
  //      await PermissionHandler().
  //      break;
  //  }
  //  _updateStatus(status);
  //  }

  void _updateStatus(PermissionStatus value) {
    setState(() {
      _status = value;
    });
  }
}

class NextPage extends StatefulWidget {
  @override
  _NextPageState createState() => _NextPageState();
}

class _NextPageState extends State<NextPage> {
  PermissionStatus _status;
  @override
  Widget build(BuildContext context) {
    debugPrint('Location Status $_status');
    return Scaffold(
      body: SafeArea(
          child: Column(
        children: <Widget>[
          Image.asset('assets/images/perm_icon_location.png'),
          Text(
            "LocationDialogHelper",
          ),
          Padding(
            padding: const EdgeInsets.all(10.0),
            child: Text(
              "locationDialogBody",
              textAlign: TextAlign.center,
            ),
          ),
          Expanded(
            child: Align(
              alignment: FractionalOffset.bottomCenter,
              child: Container(
                width: double.infinity,
                padding: EdgeInsets.all(10.0),
                child: RaisedButton(
                  color: Colors.black,
                  onPressed: _requestPerms,
                  padding: EdgeInsets.only(top: 15.0, bottom: 15.0),
                  child: Text(
                    "allow",
                    style: TextStyle(color: Colors.white),
                  ),
                ),
              ),
            ),
          )
        ],
      )),
    );
  }

  void _requestPerms() async {
    Map<Permission, PermissionStatus> statuses = await [
            Permission.locationWhenInUse,
            Permission.locationAlways,
          ].request();

    final status = Permission.locationWhenInUse.serviceStatus;
    _updateStatus(status);

// switch (status) {
 //     case PermissionStatus.disabled:
 //       await PermissionHandler().openAppSettings();
 //       break;
//    }
//    _updateStatus(status);
//  }

  void _updateStatus(PermissionStatus value) {
    setState(() {
      _status = value;
    });
  }
}
Run Code Online (Sandbox Code Playgroud)

笔记:

许多突破性的变化 permission_handler: ^5.0.0+hotfix.3

  • 将“权限组”更改为“权限” (3认同)