dev-hwang / flutter_location Goto Github PK
View Code? Open in Web Editor NEWA plugin that can access the location services of each platform and collect device location data.
License: MIT License
A plugin that can access the location services of each platform and collect device location data.
License: MIT License
What is the distanceFilter
parameter unit (meter or ...) in getLocationStream()
?!
On iOS
file: LocationServicesUtils.swift
line 13.
//
// LocationServicesUtils.swift
// fl_location
//
// Created by WOO JIN HWANG on 2021/07/26.
//
import CoreLocation
import Foundation
class LocationServicesUtils {
static func checkLocationServicesStatus() -> LocationServicesStatus {
if CLLocationManager.locationServicesEnabled() {
return LocationServicesStatus.ENABLED
} else {
return LocationServicesStatus.DISABLED
}
}
}
[CoreLocation] This method can cause UI unresponsiveness if invoked on the main thread. Instead, consider waiting for the
-locationManagerDidChangeAuthorization:callback and checking
authorizationStatus first.
Hello,
This plugin is great but there's one issue with Android. The location stops streaming in the background because the AlarmManager is not implemented.
I've implemented a workaround to fix this, but it would be great if it worked out of the box.
Thank you.
W/FlutterJNI( 2053): Tried to send a platform message to Flutter, but FlutterJNI was detached from native C++. Could not send. Channel: plugins.pravera.com/fl_location/updates. Response ID: 17447
This is the error I am facing while using your library
Hi Team,
Somehow getting this exception at 'com.pravera.fl_location.MethodCallHandlerImpl$onMethodCall'
version used: fl_location: ^1.2.2
Detailed stack trace :
Exception java.lang.IllegalStateException: Reply already submitted
at io.flutter.embedding.engine.dart.DartMessenger$Reply.reply (DartMessenger.java:435)
at io.flutter.plugin.common.MethodChannel$IncomingMethodCallHandler$1.success (MethodChannel.java:263)
at com.pravera.fl_location.MethodCallHandlerImpl$onMethodCall$callback$2.onUpdate$lambda$0 (MethodCallHandlerImpl.kt:80)
at com.pravera.fl_location.MethodCallHandlerImpl$onMethodCall$callback$2.$r8$lambda$D3GkxlYP8jK0HiV-Qvbve8bnfdk
location permission accepte to app close and not reopen
at com.pravera.fl_location.service.LocationDataProvider.checkLocationSettingsAndStartLocationUpdates(LocationDataProvider.kt:68)
E/AndroidRuntime(11608): at com.pravera.fl_location.service.LocationDataProvider.requestLocationUpdates(LocationDataProvider.kt:60)
E/AndroidRuntime(11608): at com.pravera.fl_location.service.LocationDataProviderManager.requestLocationUpdates(LocationDataProviderManager.kt:47)
E/AndroidRuntime(11608): at com.pravera.fl_location.LocationStreamHandlerImpl.onListen(LocationStreamHandlerImpl.kt:39)
E/AndroidRuntime(11608): at io.flutter.plugin.common.EventChannel$IncomingStreamRequestHandler.onListen(EventChannel.java:218)
E/AndroidRuntime(11608): at io.flutter.plugin.common.EventChannel$IncomingStreamRequestHandler.onMessage(EventChannel.java:197)
E/AndroidRuntime(11608): at io.flutter.embedding.engine.dart.DartMessenger.invokeHandler(DartMessenger.java:295)
E/AndroidRuntime(11608): at io.flutter.embedding.engine.dart.DartMessenger.lambda$dispatchMessageToQueue$0$io-flutter-embedding-engine-dart-DartMessenger(DartMessenger.java:322)
E/AndroidRuntime(11608): at io.flutter.embedding.engine.dart.DartMessenger$$ExternalSyntheticLambda0.run(Unknown Source:12)
E/AndroidRuntime(11608): at android.os.Handler.handleCallback(Handler.java:938)
E/AndroidRuntime(11608): at android.os.Handler.dispatchMessage(Handler.java:99)
E/AndroidRuntime(11608): at android.os.Looper.loopOnce(Looper.java:201)
E/AndroidRuntime(11608): at android.os.Looper.loop(Looper.java:288)
E/AndroidRuntime(11608): at android.app.ActivityThread.main(ActivityThread.java:7842)
E/AndroidRuntime(11608): at java.lang.reflect.Method.invoke(Native Method)
E/AndroidRuntime(11608): at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:548)
E/AndroidRuntime(11608): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1003)
I/Process (11608): Sending signal. PID: 11608 SIG: 9
example :
iOS location success
Android location failure,error: TimeoutException after 0:00:10.000000: Future not completed
Is there any way to get the full nmea message using this plugin?
why this permission is required?
ACCESS_FINE_LOCATION
FAILURE: Build failed with an exception.
Could not create an instance of type com.android.build.api.variant.impl.LibraryVariantBuilderImpl.
Namespace not specified. Please specify a namespace in the module's build.gradle file like so:
android {
namespace 'com.example.namespace'
}
Getting runtime error:
Caused by java.util.ConcurrentModificationException:
at java.util.LinkedHashMap$LinkedHashIterator.nextNode (LinkedHashMap.java:760)
at java.util.LinkedHashMap$LinkedValueIterator.next (LinkedHashMap.java:787)
at com.pravera.fl_location.service.LocationDataProviderManager.onActivityResult (LocationDataProviderManager.kt:59)
at io.flutter.embedding.engine.FlutterEngineConnectionRegistry$FlutterEngineActivityPluginBinding.onActivityResult (FlutterEngineConnectionRegistry.java:809)
at io.flutter.embedding.engine.FlutterEngineConnectionRegistry.onActivityResult (FlutterEngineConnectionRegistry.java:432)
at io.flutter.embedding.android.FlutterActivityAndFragmentDelegate.onActivityResult (FlutterActivityAndFragmentDelegate.java:872)
at io.flutter.embedding.android.FlutterActivity.onActivityResult (FlutterActivity.java:917)
at android.app.Activity.dispatchActivityResult (Activity.java:8659)
at android.app.ActivityThread.deliverResults (ActivityThread.java:5939)
Error 1
fl_location-1.2.1\android\src\main\kotlin\com\pravera\fl_location\service\LocationPermissionManager.kt: (15, 1): Class 'LocationPermissionManager' is not abstract and does not implement abstract member public abstract fun onRequestPermissionsResult(p0: Int, p1: Array<(out) String!>, p2: IntArray): Boolean defined in io.flutter.plugin.common.PluginRegistry.RequestPermissionsResultListener
Error2
fl_location-1.2.1\android\src\main\kotlin\com\pravera\fl_location\service\LocationPermissionManager.kt: (114, 2): 'onRequestPermissionsResult' overrides nothing
Using
Flutter 3.13.1 • channel stable • https://github.com/flutter/flutter.git
Framework • revision e1e47221e8 (3 months ago) • 2023-08-22 21:43:18 -0700
Engine • revision b20183e040
Tools • Dart 3.1.0 • DevTools 2.25.0
flutter_foreground_task: ^6.0.0+1
fl_location: ^3.0.0
Code:
`import 'dart:async';
import 'dart:isolate';
import 'package:fl_location/fl_location.dart';
import 'package:flutter/material.dart';
import 'package:flutter_foreground_task/flutter_foreground_task.dart';
void main() => runApp(const ExampleApp());
// The callback function should always be a top-level function.
void startCallback() {
// The setTaskHandler function must be called to handle the task in the background.
FlutterForegroundTask.setTaskHandler(MyTaskHandler());
}
class MyTaskHandler extends TaskHandler {
StreamSubscription? _streamSubscription;
@OverRide
Future onStart(DateTime timestamp, SendPort? sendPort) async {
_streamSubscription = FlLocation.getLocationStream().listen((event) {
FlutterForegroundTask.updateService(
notificationTitle: 'My Location',
notificationText: '${event.latitude}, ${event.longitude}',
);
// Send data to the main isolate.
sendPort?.send(event);
});
}
@OverRide
Future onDestroy(DateTime timestamp, SendPort? sendPort) async {
await _streamSubscription?.cancel();
}
@OverRide
Future onRepeatEvent(DateTime timestamp, SendPort? sendPort) async {}
}
class ExampleApp extends StatelessWidget {
const ExampleApp({Key? key}) : super(key: key);
@OverRide
Widget build(BuildContext context) {
return const MaterialApp(
debugShowCheckedModeBanner: false,
home: ExamplePage(),
);
}
}
class ExamplePage extends StatefulWidget {
const ExamplePage({Key? key}) : super(key: key);
@OverRide
State createState() => _ExamplePageState();
}
class _ExamplePageState extends State {
ReceivePort? _receivePort;
Future _checkAndRequestPermission({bool? background}) async {
if (!await FlLocation.isLocationServicesEnabled) {
// Location services are disabled.
return false;
}
var locationPermission = await FlLocation.checkLocationPermission();
if (locationPermission == LocationPermission.deniedForever) {
// Cannot request runtime permission because location permission is denied forever.
return false;
} else if (locationPermission == LocationPermission.denied) {
// Ask the user for location permission.
locationPermission = await FlLocation.requestLocationPermission();
if (locationPermission == LocationPermission.denied ||
locationPermission == LocationPermission.deniedForever) return false;
}
// Location permission must always be allowed (LocationPermission.always)
// to collect location data in the background.
if (background == true &&
locationPermission == LocationPermission.whileInUse) return false;
// Location services has been enabled and permission have been granted.
return true;
}
Future _initForegroundTask() async {
FlutterForegroundTask.init(
androidNotificationOptions: AndroidNotificationOptions(
channelId: 'foreground_service',
channelName: 'Foreground Service Notification',
channelDescription:
'This notification appears when the foreground service is running.',
channelImportance: NotificationChannelImportance.LOW,
priority: NotificationPriority.LOW,
iconData: const NotificationIconData(
resType: ResourceType.mipmap,
resPrefix: ResourcePrefix.ic,
name: 'routica_launcher_icon',
),
),
iosNotificationOptions: const IOSNotificationOptions(
showNotification: true,
playSound: false,
),
foregroundTaskOptions: const ForegroundTaskOptions(
interval: 5000,
isOnceEvent: false,
autoRunOnBoot: true,
allowWakeLock: true,
allowWifiLock: true,
),
);
}
Future _startForegroundTask() async {
if (await _checkAndRequestPermission(background: true) == false) {
print('Location permission denied!!');
return false;
}
ReceivePort? receivePort = FlutterForegroundTask.receivePort;
if (await FlutterForegroundTask.isRunningService) {
await FlutterForegroundTask.restartService();
} else {
await FlutterForegroundTask.startService(
notificationTitle: 'Foreground Service is running',
notificationText: 'Tap to return to the app',
callback: startCallback,
);
}
return _registerReceivePort(receivePort);
}
Future _stopForegroundTask() async {
return await FlutterForegroundTask.stopService();
}
bool _registerReceivePort(ReceivePort? receivePort) {
_closeReceivePort();
if (receivePort != null) {
_receivePort = receivePort;
_receivePort?.listen((message) {
if (message is Location) {
print('location: ${message.toJson()}');
}
});
return true;
}
return false;
}
void _closeReceivePort() {
_receivePort?.close();
_receivePort = null;
}
@OverRide
void initState() {
super.initState();
initForegroundTask();
WidgetsBinding.instance.addPostFrameCallback(() async {
// You can get the previous ReceivePort without restarting the service.
if (await FlutterForegroundTask.isRunningService) {
final newReceivePort = FlutterForegroundTask.receivePort;
_registerReceivePort(newReceivePort);
}
});
}
@OverRide
void dispose() {
_closeReceivePort();
super.dispose();
}
@OverRide
Widget build(BuildContext context) {
// A widget that prevents the app from closing when the foreground service is running.
// This widget must be declared above the [Scaffold] widget.
return WithForegroundTask(
child: Scaffold(
appBar: AppBar(
title: const Text('Flutter Foreground Task'),
centerTitle: true,
),
body: _buildContentView(),
),
);
}
Widget _buildContentView() {
buttonBuilder(String text, {VoidCallback? onPressed}) {
return ElevatedButton(
child: Text(text),
onPressed: onPressed,
);
}
return Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
buttonBuilder('start', onPressed: _startForegroundTask),
buttonBuilder('stop', onPressed: _stopForegroundTask),
],
),
);
}
}
`
Getting the following error:
════════ Exception caught by services library ══════════════════════════════════
The following MissingPluginException was thrown while activating platform stream on channel plugins.pravera.com/fl_location/updates:
MissingPluginException(No implementation found for method listen on channel plugins.pravera.com/fl_location/updates)
When the exception was thrown, this was the stack
#0 MethodChannel._invokeMethod
platform_channel.dart:308
#1 EventChannel.receiveBroadcastStream.
platform_channel.dart:652
════════════════════════════════════════════════════════════════════════════════
any idea? @Dev-hwang
Note: It works fine if calling on the main isolate.
this package supports background location updates even if the app is killed ?
Hi
When running FlLocation.getLocation(timeLimit: const Duration(seconds: 10));
in background using flutter_foreground_task, below exception occurs
Code:
reqResult = await FlutterForegroundTask.startService(
notificationTitle: Strings.labelTrackLocationService,
notificationText: Strings.msgTrackingLocation,
callback: startCallback,
);
void startCallback() {
FlutterForegroundTask.setTaskHandler(MovementTrackingServiceHandler());
}
class MovementTrackingServiceHandler {
_getCurrentLocation() {
Location? location;
try {
location = await fl.FlLocation.getLocation(timeLimit: const Duration(seconds: 10));
} catch (e) {
debugPrint('$e');
}
}
}
java.lang.IncompatibleClassChangeError: Found interface com.google.android.gms.location.SettingsClient, but class was expected (declaration of 'com.google.android.gms.location.SettingsClient' appears in /data/app/~~n6Huw2QsDW-xwP2Tie6VxQ==/com.azooz.driverr-OKSmBNpK8FV8oWawPK30Hw==/base.apk)
Version 1.2.2 works well on Android but does not work on iOS.
Version 2.0.0 or newer works on iOS but does not work on Android.
If I install version 2.0.0 or newer, my splashart takes almost 1 minute to come out.
Hello,
Do you plan to add a way to ask the user to enable the GPS with a dialog (not talking about permissions, but about enabling the GPS service, the one you can check with FlLocation.isLocationServicesEnabled
).
AFAIK, the only way to do this now is to send the user to the general settings.
Thanks for the plugin, cheers!
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.