diff --git a/README.md b/README.md index cfed2e0..ba4cd71 100644 --- a/README.md +++ b/README.md @@ -3,4 +3,84 @@ A new Flutter plugin that allows you to track the background location for Android & iOS [![Build Status](https://travis-ci.com/icapps/flutter-background-location-tracker.svg?branch=master)](https://travis-ci.com/icapps/flutter-background-location-tracker) -[![Coverage Status](https://coveralls.io/repos/github/icapps/flutter-background-location-tracker/badge.svg?branch=master)](https://coveralls.io/github/icapps/flutter-background-location-tracker?branch=master) \ No newline at end of file +[![Coverage Status](https://coveralls.io/repos/github/icapps/flutter-background-location-tracker/badge.svg?branch=master)](https://coveralls.io/github/icapps/flutter-background-location-tracker?branch=master) + +## Android Config + +### Update compile sdk + +Compile sdk should be at 29 at least. +``` +android { + ... + compileSdkVersion 29 + ... + + defaultConfig { + ... + targetSdkVersion 29 + ... + } + ... +} +``` + +## iOS Configuration + +### Update Info.plist + +Add the correct permission descriptions +``` + NSLocationAlwaysAndWhenInUseUsageDescription + Your description why you should use NSLocationAlwaysAndWhenInUseUsageDescription + NSLocationAlwaysUsageDescription + Your description why you should use NSLocationAlwaysAndWhenInUseUsageDescription + NSLocationWhenInUseUsageDescription + Your description why you should use NSLocationAlwaysAndWhenInUseUsageDescription +``` + +Add the background location updates in xcode + +Or add the info to the Info.plist + +``` + UIBackgroundModes + + location + +``` + +### Update the AppDelegate + +Make sure you call the `setPluginRegistrantCallback` so other plugins can be accessed in the background. + +``` +import UIKit +import Flutter +import background_location_tracker + +@UIApplicationMain +@objc class AppDelegate: FlutterAppDelegate { + override func application(_ application: UIApplication,didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { + GeneratedPluginRegistrant.register(with: self) + + BackgroundLocationTrackerPlugin.setPluginRegistrantCallback { registry in + GeneratedPluginRegistrant.register(with: registry) + } + + return super.application(application, didFinishLaunchingWithOptions: launchOptions) + } +} +``` + + +FAQ: + +#### I get a Unhandled Exception: MissingPluginException(No implementation found for method .... on channel ...) + +``` +This is mostly caused by a misconfiguration of the plugin: +Android Pre v2 embedding: make sure the plugin registrant callback is set +Android v2 embedding: Log a new github issues. This +iOS: make sure the plugin registrant callback is set +``` diff --git a/example/ios/Podfile.lock b/example/ios/Podfile.lock index bcb4e04..ec60fe1 100644 --- a/example/ios/Podfile.lock +++ b/example/ios/Podfile.lock @@ -2,12 +2,15 @@ PODS: - background_location_tracker (0.0.1): - Flutter - Flutter (1.0.0) + - flutter_local_notifications (0.0.1): + - Flutter - "permission_handler (5.0.1+1)": - Flutter DEPENDENCIES: - background_location_tracker (from `.symlinks/plugins/background_location_tracker/ios`) - Flutter (from `Flutter`) + - flutter_local_notifications (from `.symlinks/plugins/flutter_local_notifications/ios`) - permission_handler (from `.symlinks/plugins/permission_handler/ios`) EXTERNAL SOURCES: @@ -15,14 +18,17 @@ EXTERNAL SOURCES: :path: ".symlinks/plugins/background_location_tracker/ios" Flutter: :path: Flutter + flutter_local_notifications: + :path: ".symlinks/plugins/flutter_local_notifications/ios" permission_handler: :path: ".symlinks/plugins/permission_handler/ios" SPEC CHECKSUMS: background_location_tracker: 3f0954d5a839b9bfffbdc887e679d183a7bbc1c9 Flutter: 0e3d915762c693b495b44d77113d4970485de6ec + flutter_local_notifications: 0c0b1ae97e741e1521e4c1629a459d04b9aec743 permission_handler: eac8e15b4a1a3fba55b761d19f3f4e6b005d15b6 PODFILE CHECKSUM: aafe91acc616949ddb318b77800a7f51bffa2a4c -COCOAPODS: 1.9.1 +COCOAPODS: 1.10.0 diff --git a/example/ios/Runner/AppDelegate.swift b/example/ios/Runner/AppDelegate.swift index 351bd4c..3a465c4 100644 --- a/example/ios/Runner/AppDelegate.swift +++ b/example/ios/Runner/AppDelegate.swift @@ -1,11 +1,20 @@ import UIKit import Flutter +import background_location_tracker @UIApplicationMain @objc class AppDelegate: FlutterAppDelegate { override func application(_ application: UIApplication,didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { GeneratedPluginRegistrant.register(with: self) - + + if #available(iOS 10.0, *) { + UNUserNotificationCenter.current().delegate = self + } + + BackgroundLocationTrackerPlugin.setPluginRegistrantCallback { registry in + GeneratedPluginRegistrant.register(with: registry) + } + return super.application(application, didFinishLaunchingWithOptions: launchOptions) } } diff --git a/example/lib/main.dart b/example/lib/main.dart index cbf4ed0..5d7cca2 100644 --- a/example/lib/main.dart +++ b/example/lib/main.dart @@ -1,7 +1,10 @@ import 'dart:async'; +import 'dart:io'; +import 'dart:math'; import 'package:background_location_tracker/background_location_tracker.dart'; import 'package:flutter/material.dart'; +import 'package:flutter_local_notifications/flutter_local_notifications.dart'; import 'package:permission_handler/permission_handler.dart'; void _backgroundCallback() => BackgroundLocationTrackerManager.handleBackgroundUpdated((data) async => Repo().update(data)); @@ -13,7 +16,6 @@ Future main() async { config: const BackgroundLocationTrackerConfig( androidConfig: AndroidConfig( notificationIcon: 'explore', - enableCancelTrackingAction: false, ), ), ); @@ -50,6 +52,15 @@ class _MyAppState extends State { child: const Text('Request location permission'), onPressed: _requestLocationPermission, ), + if (Platform.isIOS) + MaterialButton( + child: const Text('Request Notification permission'), + onPressed: _requestNotificationPermission, + ), + MaterialButton( + child: const Text('Send notification'), + onPressed: () => sendNotification('Hallokes'), + ), if (isTracking != null) ...[ MaterialButton( child: const Text('Start Tracking'), @@ -90,6 +101,15 @@ class _MyAppState extends State { print('NOT GRANTED'); // ignore: avoid_print } } + + Future _requestNotificationPermission() async { + final result = await Permission.notification.request(); + if (result == PermissionStatus.granted) { + print('GRANTED'); // ignore: avoid_print + } else { + print('NOT GRANTED'); // ignore: avoid_print + } + } } class Repo { @@ -99,5 +119,32 @@ class Repo { factory Repo() => _instance ??= Repo._(); - void update(BackgroundLocationUpdateData data) => print('Location Update: Lat: ${data.lat} Lon: ${data.lon}'); // ignore: avoid_print + void update(BackgroundLocationUpdateData data) { + final text = 'Location Update: Lat: ${data.lat} Lon: ${data.lon}'; + print(text); // ignore: avoid_print + sendNotification(text); + } +} + +void sendNotification(String text) { + const settings = InitializationSettings( + android: AndroidInitializationSettings('app_icon'), + iOS: IOSInitializationSettings( + requestAlertPermission: false, + requestBadgePermission: false, + requestSoundPermission: false, + ), + ); + FlutterLocalNotificationsPlugin().initialize(settings, onSelectNotification: (data) async { + print('ON CLICK $data'); // ignore: avoid_print + }); + FlutterLocalNotificationsPlugin().show( + Random().nextInt(9999), + 'Title', + text, + const NotificationDetails( + android: AndroidNotificationDetails('test_notification', 'Test', 'Test'), + iOS: IOSNotificationDetails(), + ), + ); } diff --git a/example/pubspec.lock b/example/pubspec.lock index bd93d52..3709258 100644 --- a/example/pubspec.lock +++ b/example/pubspec.lock @@ -62,6 +62,20 @@ packages: description: flutter source: sdk version: "0.0.0" + flutter_local_notifications: + dependency: "direct main" + description: + name: flutter_local_notifications + url: "https://pub.dartlang.org" + source: hosted + version: "3.0.2" + flutter_local_notifications_platform_interface: + dependency: transitive + description: + name: flutter_local_notifications_platform_interface + url: "https://pub.dartlang.org" + source: hosted + version: "2.0.0+1" flutter_test: dependency: "direct dev" description: flutter @@ -102,6 +116,13 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "2.0.1" + platform: + dependency: transitive + description: + name: platform + url: "https://pub.dartlang.org" + source: hosted + version: "2.2.1" plugin_platform_interface: dependency: transitive description: @@ -156,6 +177,13 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "0.2.19-nullsafety.2" + timezone: + dependency: transitive + description: + name: timezone + url: "https://pub.dartlang.org" + source: hosted + version: "0.5.9" typed_data: dependency: transitive description: diff --git a/example/pubspec.yaml b/example/pubspec.yaml index 07db537..efb644f 100644 --- a/example/pubspec.yaml +++ b/example/pubspec.yaml @@ -11,6 +11,7 @@ dependencies: background_location_tracker: path: ../ permission_handler: ^5.0.1+1 + flutter_local_notifications: ^3.0.2 dev_dependencies: flutter_test: