4

When my app requests location permission the entire app stops until the dialog is complete (e.g. if the permission dialog pops up during a page transition the transition will freeze mid transition until the dialog is resolved).

Literally it causes execution to pause.

Using: flutter_riverpod, location.

The offending code:

import 'dart:async';

import 'package:flutter/foundation.dart';
import 'package:flutter_riverpod/all.dart';
import 'package:location/location.dart';

class MapApiBloc extends StateNotifier<MapApiState> {
  // Instantiating a location service
  static Location _location = Location();

  // This will subscribe to the user's location
  StreamSubscription<LocationData> _streamSubscription;

  // Permissions stuff
  bool _serviceEnabled;
  PermissionStatus _permissionGranted;

  //  Initial (empty) state
  static const MapApiState _initialState = MapApiState(userLocation: null);

  MapApiBloc() : super(_initialState) {
    init();
  }

  // This runs when you initialize the class
  init() async {
    // Checks if user toggled on location service
    _serviceEnabled = await _location.serviceEnabled();
    if (!_serviceEnabled) {
      _serviceEnabled = await _location.requestService();
      if (!_serviceEnabled) {
        return;
      }
    }

    // Asks for permission
    _permissionGranted = await _location.hasPermission();
    if (_permissionGranted == PermissionStatus.denied) {
      _permissionGranted = await _location.requestPermission();
      if (_permissionGranted != PermissionStatus.granted) {
        return;
      }
    }

    // Starts the subscription
    _streamSubscription = _location.onLocationChanged.listen((event) {
      state = MapApiState(userLocation: event);
    });
  }

  @override
  void dispose() {
    _streamSubscription.cancel();
    super.dispose();
  }
}



class MapApiState {
  final LocationData userLocation;
  const MapApiState({@required this.userLocation});
}

final mapApiProvider = StateNotifierProvider<MapApiBloc>((ref) {
  return MapApiBloc();
});

UI Code:

class ViewNearbyMapPage extends StatefulWidget {
  @override
  _ViewNearbyMapPageState createState() => _ViewNearbyMapPageState();
}

class _ViewNearbyMapPageState extends State<ViewNearbyMapPage> {
  Completer<GoogleMapController> _controller = Completer();

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text("Search Sellers")),
      body: Consumer(
        builder: (context, watch, child) {
          var location = watch(mapApiProvider.state);
          if (location.userLocation?.latitude == null) {
            return Center(child: CircularProgressIndicator());
          }
          CameraPosition _myPosition = CameraPosition(
            target: LatLng(location.userLocation.latitude,
                location.userLocation.longitude),
            zoom: 14.4746,
          );

          return GoogleMap(
            initialCameraPosition: _myPosition,
            onMapCreated: (controller) {
              _controller.complete(controller);
            },
          );
        },
      ),
    );
  }
}
Shazamo Morebucks
  • 478
  • 1
  • 8
  • 19

0 Answers0