我希望我的应用程序在后台获取用户位置并发送到服务器。但我的应用每 15 分钟运行两次任务。我不确定是不是因为与模拟器或其他东西建立了新的连接。我没有在物理设备上检查这个。
15分钟后我的日志。
D/EGL_emulation( 5517): eglCreateContext: 0xb76d0c40: maj 2 min 0 rcv 2
D/EGL_emulation( 5517): eglCreateContext: 0xb76d07e0: maj 2 min 0 rcv 2
D/HostConnection( 5517): HostConnection::get() New Host Connection established 0xb76cdec0, tid 8672
D/HostConnection( 5517): HostComposition ext ANDROID_EMU_CHECKSUM_HELPER_v1 ANDROID_EMU_native_sync_v2 ANDROID_EMU_native_sync_v3 ANDROID_EMU_native_sync_v4 ANDROID_EMU_dma_v1 ANDROID_EMU_direct_mem ANDROID_EMU_host_composition_v1 ANDROID_EMU_host_composition_v2 ANDROID_EMU_vulkan ANDROID_EMU_deferred_vulkan_commands ANDROID_EMU_vulkan_null_optional_strings ANDROID_EMU_vulkan_create_resources_with_requirements ANDROID_EMU_YUV_Cache ANDROID_EMU_vulkan_ignored_handles ANDROID_EMU_has_shared_slots_host_memory_allocator ANDROID_EMU_vulkan_free_memory_sync ANDROID_EMU_vulkan_shader_float16_int8 ANDROID_EMU_vulkan_async_queue_submit ANDROID_EMU_sync_buffer_data ANDROID_EMU_read_color_buffer_dma GL_OES_vertex_array_object GL_KHR_texture_compression_astc_ldr ANDROID_EMU_host_side_tracing ANDROID_EMU_gles_max_version_2
D/EGL_emulation( 5517): eglMakeCurrent: 0xb76d07e0: ver 2 0 (tinfo 0xc09b2d30) (first time)
D/PathProviderPlugin( 5517): Use TaskQueues.
D/EGL_emulation( 5517): eglCreateContext: 0xb76e06f0: maj 2 min 0 rcv 2
D/EGL_emulation( 5517): eglCreateContext: 0xb76c6e50: maj 2 min 0 rcv 2
D/HostConnection( 5517): HostConnection::get() New Host Connection established 0xb76df880, tid 8675
D/HostConnection( 5517): HostComposition ext ANDROID_EMU_CHECKSUM_HELPER_v1 ANDROID_EMU_native_sync_v2 ANDROID_EMU_native_sync_v3 ANDROID_EMU_native_sync_v4 ANDROID_EMU_dma_v1 ANDROID_EMU_direct_mem ANDROID_EMU_host_composition_v1 ANDROID_EMU_host_composition_v2 ANDROID_EMU_vulkan ANDROID_EMU_deferred_vulkan_commands ANDROID_EMU_vulkan_null_optional_strings ANDROID_EMU_vulkan_create_resources_with_requirements ANDROID_EMU_YUV_Cache ANDROID_EMU_vulkan_ignored_handles ANDROID_EMU_has_shared_slots_host_memory_allocator ANDROID_EMU_vulkan_free_memory_sync ANDROID_EMU_vulkan_shader_float16_int8 ANDROID_EMU_vulkan_async_queue_submit ANDROID_EMU_sync_buffer_data ANDROID_EMU_read_color_buffer_dma GL_OES_vertex_array_object GL_KHR_texture_compression_astc_ldr ANDROID_EMU_host_side_tracing ANDROID_EMU_gles_max_version_2
D/EGL_emulation( 5517): eglMakeCurrent: 0xb76c6e50: ver 2 0 (tinfo 0xb9f6cf90) (first time)
D/PathProviderPlugin( 5517): Use TaskQueues.
I/flutter ( 5517): LocationTask was executed. inputData = null
I/flutter ( 5517): LocationTask was executed. inputData = null
I/flutter ( 5517): Api.sendLastLocationToServer
I/flutter ( 5517): Api.sendLastLocationToServer
I/flutter ( 5517): Send location
I/flutter ( 5517): Send location
I/WM-WorkerWrapper( 5517): Worker result SUCCESS for Work [ id=1db5828f-d784-4350-84bc-39d4bdbafac1, tags={ be.tramckrijte.workmanager.BackgroundWorker } ]
I/WM-WorkerWrapper( 5517): Worker result SUCCESS for Work [ id=05da0028-6002-4855-aecb-1ff5cdad7b53, tags={ be.tramckrijte.workmanager.BackgroundWorker } ]
我的主要代码包含 Workmanager。
const locationTaskKey = 'LocationTask';
const failedTaskKey = "failedTask";
void main() async {
WidgetsFlutterBinding.ensureInitialized();
LocationPermission permission = await Geolocator.checkPermission();
if (permission == LocationPermission.denied) {
permission = await Geolocator.requestPermission();
}
// Set up the SettingsController, which will glue user settings to multiple
// Flutter Widgets.
final settingsController = SettingsController(SettingsService());
// Load the user's preferred theme while the splash screen is displayed.
// This prevents a sudden theme change when the app is first displayed.
await settingsController.loadSettings();
// Run the app and pass in the SettingsController. The app listens to the
// SettingsController for changes, then passes it further down to the
// SettingsView.
runApp(MyApp(settingsController: settingsController));
}
class MyApp extends StatelessWidget {
const MyApp({
Key? key,
required this.settingsController,
}) : super(key: key);
final SettingsController settingsController;
@override
Widget build(BuildContext context) {
Workmanager().initialize(
callbackDispatcher,
isInDebugMode: true,
);
Workmanager().registerPeriodicTask(
"5",
locationTaskKey,
frequency: const Duration(minutes: 15),
constraints: Constraints(
networkType: NetworkType.not_required,
requiresBatteryNotLow: false,
// requiresCharging: true,
// requiresDeviceIdle: true,
requiresStorageNotLow: false,
),
);
// Glue the SettingsController to the MaterialApp.
//
// The AnimatedBuilder Widget listens to the SettingsController for changes.
// Whenever the user updates their settings, the MaterialApp is rebuilt.
return AnimatedBuilder(
animation: settingsController,
builder: (BuildContext context, Widget? child) {
return MaterialApp(
debugShowCheckedModeBanner: false,
restorationScopeId: 'MyApp',
theme: AppTheme.newLightTheme(),
darkTheme: AppTheme.newDarkTheme(),
themeMode: settingsController.themeMode,
onGenerateRoute: (RouteSettings routeSettings) {
return MaterialPageRoute<void>(
settings: routeSettings,
builder: (BuildContext context) {
switch (routeSettings.name) {
case MainScreen.routeName:
return MainScreen(settingsController: settingsController);
default:
return const ChooseLogin();
}
},
);
},
);
},
);
}
}
void callbackDispatcher() {
Workmanager().executeTask((task, inputData) async {
switch (task) {
case locationTaskKey:
debugPrint("$locationTaskKey was executed. inputData = $inputData");
Position position = await determinePosition();
Api api = Api();
List<AppLocation> locations = [];
locations.add(
AppLocation(
position.timestamp.toString(),
position.longitude,
position.latitude,
),
);
bool status = await api.sendLastLocationToServer(locations);
if (status) {
debugPrint('Send location');
} else {
debugPrint('can not Send location');
}
break;
case failedTaskKey:
debugPrint('failed task');
return Future.error('failed');
}
return Future.value(true);
});
}
Future<Position> determinePosition() async {
bool serviceEnabled;
LocationPermission permission;
// Test if location services are enabled.
serviceEnabled = await Geolocator.isLocationServiceEnabled();
if (!serviceEnabled) {
// Location services are not enabled don't continue
// accessing the position and request users of the
// App to enable the location services.
return Future.error('Location services are disabled.');
}
permission = await Geolocator.checkPermission();
if (permission == LocationPermission.denied) {
permission = await Geolocator.requestPermission();
if (permission == LocationPermission.denied) {
// Permissions are denied, next time you could try
// requesting permissions again (this is also where
// Android's shouldShowRequestPermissionRationale
// returned true. According to Android guidelines
// your App should show an explanatory UI now.
return Future.error('Location permissions are denied');
}
}
if (permission == LocationPermission.deniedForever) {
// Permissions are denied forever, handle appropriately.
return Future.error(
'Location permissions are permanently denied, we cannot request permissions.');
}
// When we reach here, permissions are granted and we can
// continue accessing the position of the device.
return await Geolocator.getCurrentPosition(
desiredAccuracy: LocationAccuracy.high);
}
扑医生 -v 信息。
[✓] Flutter (Channel stable, 2.8.1, on Ubuntu 20.04.3 LTS 5.11.0-46-generic, locale en_US.UTF-8)
• Flutter version 2.8.1 at /home/mahmoudi/snap/flutter/common/flutter
• Upstream repository https://github.com/flutter/flutter.git
• Framework revision 77d935af4d (5 weeks ago), 2021-12-16 08:37:33 -0800
• Engine revision 890a5fca2e
• Dart version 2.15.1
[✓] Android toolchain - develop for Android devices (Android SDK version 32.0.0)
• Android SDK at /home/mahmoudi/Android/Sdk
• Platform android-32, build-tools 32.0.0
• Java binary at: /snap/android-studio/115/android-studio/jre/bin/java
• Java version OpenJDK Runtime Environment (build 11.0.10+0-b96-7249189)
• All Android licenses accepted.
[✓] Chrome - develop for the web
• Chrome at google-chrome
[✓] Linux toolchain - develop for Linux desktop
• clang version 6.0.0-1ubuntu2 (tags/RELEASE_600/final)
• cmake version 3.10.2
• ninja version 1.8.2
• pkg-config version 0.29.1
[✓] Android Studio (version 2020.3)
• Android Studio at /snap/android-studio/115/android-studio
• Flutter plugin version 63.2.1
• Dart plugin version 203.8452
• Java version OpenJDK Runtime Environment (build 11.0.10+0-b96-7249189)
[✓] VS Code (version 1.63.2)
• VS Code at /usr/share/code
• Flutter extension version 3.32.0
[✓] Connected device (3 available)
• sdk gphone x86 (mobile) • emulator-5554 • android-x86 • Android 11 (API 30) (emulator)
• Linux (desktop) • linux • linux-x64 • Ubuntu 20.04.3 LTS 5.11.0-46-generic
• Chrome (web) • chrome • web-javascript • Google Chrome 97.0.4692.71
• No issues found!