flutter - app crashes using android.permission.FOREGROUND_SERVICE_LOCATION - Stack Overflow

I'm trying to build a flutter app to get the location every 2 seconds even when the app is minimis

I'm trying to build a flutter app to get the location every 2 seconds even when the app is minimised. I'm using the flutter_background_service: ^5.0.4 for the app to check location when minimised.

Using android.permission.FOREGROUND_SERVICE_LOCATION for permission the app crashes. So, i tried with out using it but got a lot of errors.

Main code:

import 'dart:async';
import 'dart:ui';
import 'package:disable_battery_optimization/disable_battery_optimization.dart';
import 'package:flutter/material.dart';
import 'package:geolocator/geolocator.dart';
import 'package:flutter_background_service/flutter_background_service.dart';
import 'package:flutter_background_service_android/flutter_background_service_android.dart';
import 'package:permission_handler/permission_handler.dart';

void main() async {
  WidgetsFlutterBinding.ensureInitialized();
  await initializeService();
  runApp(MyApp());
}

Future<void> initializeService() async {
  final service = FlutterBackgroundService();

  await service.configure(
    androidConfiguration: AndroidConfiguration(
      onStart: onStart,
      autoStart: false,
      isForegroundMode: true,
      notificationChannelId: 'location_service',
      initialNotificationTitle: 'Background Location Service',
      initialNotificationContent: 'Fetching location...',
      foregroundServiceNotificationId: 888,
    ),
    iosConfiguration: IosConfiguration(
      onForeground: onStart,
      onBackground: onIosBackground,
    ),
  );
}

@pragma('vm:entry-point')
void onStart(ServiceInstance service) async {
  DartPluginRegistrant.ensureInitialized();

  if (service is AndroidServiceInstance) {

    service.on('foregroundService').listen((event) {
      service.setAsForegroundService();
    });
    service.on('stopService').listen((event) {
      service.stopSelf();
    });
  }

  Timer.periodic(const Duration(seconds: 2), (timer) async {
    final runCheck = FlutterBackgroundService();
    if (!(await runCheck.isRunning())) timer.cancel();


    if (service is AndroidServiceInstance) {
      if(await service.isForegroundService()){
        Position position = await Geolocator.getCurrentPosition(
          desiredAccuracy: LocationAccuracy.bestForNavigation,
        );

        print('Latitude: ${position.latitude}, Longitude: ${position.longitude}');

        service.invoke(
          'updateLocation',
          {
            'latitude': position.latitude.toString(),
            'longitude': position.longitude.toString(),
          },
        );
      }
    }
  });
}

@pragma('vm:entry-point')
Future<bool> onIosBackground(ServiceInstance service) async {
  WidgetsFlutterBinding.ensureInitialized();
  return true;
}

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

class LocationTrackerScreen extends StatefulWidget {
  @override
  _LocationTrackerScreenState createState() => _LocationTrackerScreenState();
}

class _LocationTrackerScreenState extends State<LocationTrackerScreen> {
  String _latitude = '0.0';
  String _longitude = '0.0';

  @override
  void initState() {
    super.initState();
     locationPermission();
    FlutterBackgroundService().on('updateLocation').listen((event) {
      setState(() {
        _latitude = event?['latitude'] ?? '0.0';
        _longitude = event?['longitude'] ?? '0.0';
      });
    });
  }

  Future<void> batteryOptimizationCheck()async{
    DisableBatteryOptimization.showDisableBatteryOptimizationSettings();
    bool? isBatteryOptimizationDisabled =
    await DisableBatteryOptimization.isBatteryOptimizationDisabled;

    if (isBatteryOptimizationDisabled != null) {
      if(isBatteryOptimizationDisabled== true){

        print("Battery optimization is ${isBatteryOptimizationDisabled ?
        "Disabled" : "Enabled"}");
      }
    } else {
      print("Could not determine battery optimization status.");
    }
  }
  void  locationPermission() async {

    await batteryOptimizationCheck();

    bool serviceEnabled = await Geolocator.isLocationServiceEnabled();
    if (!serviceEnabled) {
      ScaffoldMessenger.of(context).showSnackBar(const SnackBar(
          content: Text('Location services are disabled. Please enable them.')));
      return;
    }

    LocationPermission permission = await Geolocator.checkPermission();
    if (permission == LocationPermission.denied ||
        permission == LocationPermission.deniedForever) {
      permission = await Geolocator.requestPermission();
      if (permission == LocationPermission.denied ||
          permission == LocationPermission.deniedForever) {
        ScaffoldMessenger.of(context).showSnackBar(const SnackBar(
            content: Text('Location permissions are permanently denied.')));
        return;
      }
    }

    var accuracy = await Geolocator.getLocationAccuracy();
    if (accuracy != LocationAccuracyStatus.precise) {
      permission = await Geolocator.requestPermission();
      accuracy = await Geolocator.getLocationAccuracy();
      if (accuracy != LocationAccuracyStatus.precise) {
        ScaffoldMessenger.of(context).showSnackBar(const SnackBar(
            content: Text('Precise Location Permission denied, Low Accuracy')));
      }
    }

    var alwaysPermission = await Permission.locationAlways.status;
    if (!alwaysPermission.isGranted) {
      var result = await Permission.locationAlways.request();
      if (!result.isGranted) {
        ScaffoldMessenger.of(context).showSnackBar(const SnackBar(
            content: Text(
                'Location Always permission is required for background location tracking.')));
      }
    }
  }

  void startService() async {
    final service = FlutterBackgroundService();
    service.invoke('foregroundService');
    var isRunning = await service.isRunning();

    if (!isRunning) {
      service.startService();
    }
  }

  void stopService() async {

    final service = FlutterBackgroundService();
    var isRunning = await service.isRunning();

    if (isRunning) {
      service.invoke('stopService');
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text('Location Tracker')),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            Text(
              'Latitude: $_latitude\nLongitude: $_longitude',
              style: const TextStyle(fontSize: 24, fontWeight: FontWeight.bold),
              textAlign: TextAlign.center,
            ),
            const SizedBox(height: 20),
            ElevatedButton(
              onPressed: startService,
              style: ElevatedButton.styleFrom(backgroundColor: Colors.green),
              child: const Text('Start'),
            ),
            const SizedBox(height: 10),
            ElevatedButton(
              onPressed: stopService,
              style: ElevatedButton.styleFrom(backgroundColor: Colors.red),
              child: const Text('Stop'),
            ),
          ],
        ),
      ),
    );
  }
}

Console:

Failed to start foreground service due to SecurityException - have you fotten to request a permission? - Starting FGS with type location callerApp=ProcessRecord{4d894c2 12877:com.sfstrace.fleet/u0a238} targetSDK=34 requires permissions: all of the permissions allOf=true [android.permission.FOREGROUND_SERVICE_LOCATION] any of the permissions allOf=false [android.permission.ACCESS_COARSE_LOCATION, android.permission.ACCESS_FINE_LOCATION]  and the app must be in the eligible state/exemptions to access the foreground only permission
    V/BackgroundService(12877): Starting flutter engine for background service
    W/BackgroundService(12877): Failed to start foreground service due to SecurityException - have you fotten to request a permission? - Starting FGS with type location callerApp=ProcessRecord{4d894c2 12877:com.sfstrace.fleet/u0a238} targetSDK=34 requires permissions: all of the permissions allOf=true [android.permission.FOREGROUND_SERVICE_LOCATION] any of the permissions allOf=false [android.permission.ACCESS_COARSE_LOCATION, android.permission.ACCESS_FINE_LOCATION]  and the app must be in the eligible state/exemptions to access the foreground only permission
    D/FlutterArchivePlugin(12877): onAttachedToEngine - IN
    D/FlutterArchivePlugin(12877): doOnAttachedToEngine - IN
    D/FlutterArchivePlugin(12877): doOnAttachedToEngine - OUT
    D/FlutterArchivePlugin(12877): onAttachedToEngine - OUT
    V/BackgroundService(12877): Service already running, using existing service
    D/FlutterGeolocator(12877): Geolocator foreground service connected
    D/FlutterGeolocator(12877): Initializing Geolocator services
    D/FlutterGeolocator(12877): Flutter engine connected. Connected engine count 2
    I/flutter (12877): `flutter_background_service_android` threw an error: Exception: This class should only be used in the main isolate (UI App). The app may not function as expected until you remove this plugin from pubspec.yaml
    D/EGL_emulation(12877): app_time_stats: avg=1585.87ms min=9.88ms max=4736.17ms count=3
    E/flutter (12877): [ERROR:flutter/runtime/dart_vm_initializer(41)] Unhandled Exception: MissingPluginException(No implementation found for method isServiceRunning on channel id.flutter/background_service/android/method)
    E/flutter (12877): #0      MethodChannel._invokeMethod (package:flutter/src/services/platform_channel.dart:332:7)
    E/flutter (12877): <asynchronous suspension>
    E/flutter (12877): #1      FlutterBackgroundServiceAndroid.isServiceRunning (package:flutter_background_service_android/flutter_background_service_android.dart:127:18)
    E/flutter (12877): <asynchronous suspension>
    E/flutter (12877): #2      onStart.<anonymous closure> (package:demo_speedo/main.dart:52:11)
    E/flutter (12877): <asynchronous suspension>
    E/flutter (12877): 
    E/flutter (12877): [ERROR:flutter/runtime/dart_vm_initializer(41)] Unhandled Exception: MissingPluginException(No implementation found for method isServiceRunning on channel id.flutter/background_service/android/method)
    E/flutter (12877): #0      MethodChannel._invokeMethod (package:flutter/src/services/platform_channel.dart:332:7)
    E/flutter (12877): <asynchronous suspension>
    E/flutter (12877): #1      FlutterBackgroundServiceAndroid.isServiceRunning (package:flutter_background_service_android/flutter_background_service_android.dart:127:18)
    E/flutter (12877): <asynchronous suspension>
    E/flutter (12877): #2      onStart.<anonymous closure> (package:demo_speedo/main.dart:52:11)
    E/flutter (12877): <asynchronous suspension>
    E/flutter (12877): 
    E/flutter (12877): [ERROR:flutter/runtime/dart_vm_initializer(41)] Unhandled Exception: MissingPluginException(No implementation found for method isServiceRunning on channel id.flutter/background_service/android/method)
    E/flutter (12877): #0      MethodChannel._invokeMethod (package:flutter/src/services/platform_channel.dart:332:7)
    E/flutter (12877): <asynchronous suspension>
    E/flutter (12877): #1      FlutterBackgroundServiceAndroid.isServiceRunning (package:flutter_background_service_android/flutter_background_service_android.dart:127:18)
    E/flutter (12877): <asynchronous suspension>
    E/flutter (12877): #2      onStart.<anonymous closure> (package:demo_speedo/main.dart:52:11)
    E/flutter (12877): <asynchronous suspension>
    E/flutter (12877): 
    E/flutter (12877): [ERROR:flutter/runtime/dart_vm_initializer(41)] Unhandled Exception: MissingPluginException(No implementation found for method isServiceRunning on channel id.flutter/background_service/android/method)
    E/flutter (12877): #0      MethodChannel._invokeMethod (package:flutter/src/services/platform_channel.dart:332:7)
    E/flutter (12877): <asynchronous suspension>
    E/flutter (12877): #1      FlutterBackgroundServiceAndroid.isServiceRunning (package:flutter_background_service_android/flutter_background_service_android.dart:127:18)
    E/flutter (12877): <asynchronous suspension>
    E/flutter (12877): #2      onStart.<anonymous closure> (package:demo_speedo/main.dart:52:11)
    E/flutter (12877): <asynchronous suspension>
    E/flutter (12877): 

Manifest:

<manifest xmlns:android=";>
    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
    <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
    <uses-permission android:name="android.permission.INTERNET"/>
    <uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
    <uses-permission android:name="android.permission.ACCESS_FOREGROUND_LOCATION" />
    <uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION" />
    <uses-permission android:name="android.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS" />
    <uses-permission android:name="android.permission.FOREGROUND_SERVICE_DATA_SYNC"/>


    <application
        android:label="SFS Fleet Tracker"
        android:name="${applicationName}"
        android:icon="@mipmap/ic_launcher">
        <activity
            android:name=".MainActivity"
            android:exported="true"
            android:launchMode="singleTop"
            android:taskAffinity=""
            android:theme="@style/LaunchTheme"
            android:configChanges="orientation|keyboardHidden|keyboard|screenSize|smallestScreenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode"
            android:hardwareAccelerated="true"
            android:windowSoftInputMode="adjustResize">
            <!-- Specifies an Android theme to apply to this Activity as soon as
                 the Android process has started. This theme is visible to the user
                 while the Flutter UI initializes. After that, this theme continues
                 to determine the Window background behind the Flutter UI. -->
            <meta-data
              android:name="io.flutter.embedding.android.NormalTheme"
              android:resource="@style/NormalTheme"
                android:value="2"
              />
            <intent-filter>
                <action android:name="android.intent.action.MAIN"/>
                <category android:name="android.intent.category.LAUNCHER"/>
            </intent-filter>
        </activity>
        <!-- Don't delete the meta-data below.
             This is used by the Flutter tool to generate GeneratedPluginRegistrant.java -->
        <meta-data
            android:name="flutterEmbedding"
            android:value="2" />


        <service
            android:name="id.flutter.flutter_background_service.BackgroundService"
            android:enabled="true"
            android:exported="true"
            android:foregroundServiceType="location" />
    </application>
    <!-- Required to query activities that can process text, see:
          and
         .

         In particular, this is used by the Flutter engine in io.flutter.plugin.text.ProcessTextPlugin. -->
    <queries>
        <intent>
            <action android:name="android.intent.action.PROCESS_TEXT"/>
            <data android:mimeType="text/plain"/>
        </intent>
    </queries>
</manifest>

I'm a beginner trying to solve this issue.

发布者:admin,转转请注明出处:http://www.yc00.com/questions/1745008418a4605922.html

相关推荐

发表回复

评论列表(0条)

  • 暂无评论

联系我们

400-800-8888

在线咨询: QQ交谈

邮件:admin@example.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信