Cordova 应用程序每分钟将我的位置上传到后端服务器,即使屏幕关闭或应用程序处于后台
Cordova app that uploads my location every minute to a back-end server, even when screen is off or app is in background
我正在努力为 android 编写一个 Cordova 应用程序,它将在屏幕关闭后保持 运行。我正在尝试后台和前台服务(有时一起)来保持一个简单的循环 运行:获取我的位置,然后通过 TCP 将 JSON 发送到后端服务器。有没有人有办法解决吗?我是 运行 Android 8.1 Oreo,我尝试在我的应用程序中放置前景、背景和背景-运行 timer npm 包。无论我尝试什么,在关闭我的 phone 屏幕后约 5 分钟后,该应用程序停止与后端服务器通信。我已经禁用了节电措施,我真的被困在这里了。谢谢。
随着 android 的更新版本,Google 越来越多地实现了在后台关闭应用程序的功能。从宏伟的计划来看,这是一件好事,这是为了节省电池寿命,然而,这对开发者来说可不是什么好消息。具体来说,看看他们的文档:doze and adaptive battery.
在撰写本文时,没有 cordova 插件可以为较新的 android 版本提供这些功能(doze 最初是在 android 6.0 中引入的,后来的版本变得更加苛刻)。
除非自己写插件,这里没有很好的答案。将您的应用程序 运行 保持在后台是一项功能,随着新版本 android 的发布,确实(并且将)需要持续维护,也就是说,一般来说,这不是 cordova 擅长的事情。
作为开发工具的 Cordova 不适用于深层原生功能。如果您的主要产品需要快速配套应用程序,请使用 cordova 作为平台。
使用这些插件(使用 cordova 9.0.0):
cordova-background-timer 0.0.4 "BackgroundTimer"
cordova-plugin-background-mode 0.7.2 "BackgroundMode"
cordova-plugin-device 2.0.2 "Device"
cordova-plugin-foreground-service 1.1.1 "Cordova Foreground Service"
cordova-plugin-mauron85-background-geolocation 3.0.1 "CDVBackgroundGeolocation"
cordova-plugin-whitelist 1.3.3 "Whitelist"
还有这个 JavaScript 代码:
onDeviceReady: function () {
this.receivedEvent('deviceready');
cordova.plugins.foregroundService.start('GPS Running', 'Background Service');
cordova.plugins.backgroundMode.on('activate', function () {
console.log("Disabled webview optimizations");
cordova.plugins.backgroundMode.disableWebViewOptimizations();
});
cordova.plugins.backgroundMode.enable();
var socket = io.connect('http://server.com:3000');
socket.on('request', function (empty) {
BackgroundGeolocation.getCurrentLocation(function (location) {
socket.emit('location', JSON.stringify(location));
});
});
BackgroundGeolocation.configure({
locationProvider: BackgroundGeolocation.ACTIVITY_PROVIDER,
desiredAccuracy: BackgroundGeolocation.HIGH_ACCURACY,
notificationTitle: 'Location, Location!',
notificationText: 'enabled',
debug: false,
interval: 30 * 1000,
fastestInterval: 30 * 1000,
activitiesInterval: 30 * 1000
});
BackgroundGeolocation.on('location', function (location) {
// handle your locations here
// to perform long running operation on iOS
// you need to create background task
//console.log("regular location:");
//console.log(location);
BackgroundGeolocation.startTask(function (taskKey) {
// execute long running task
// eg. ajax post location
// IMPORTANT: task has to be ended by endTask
BackgroundGeolocation.endTask(taskKey);
});
});
BackgroundGeolocation.on('stationary', function (stationaryLocation) {
// handle stationary locations here
//console.log("Stationary object");
//console.log(stationaryLocation);
});
BackgroundGeolocation.on('error', function (error) {
console.log('[ERROR] BackgroundGeolocation error:', error.code, error.message);
});
BackgroundGeolocation.on('start', function () {
console.log('[INFO] BackgroundGeolocation service has been started');
});
BackgroundGeolocation.on('stop', function () {
console.log('[INFO] BackgroundGeolocation service has been stopped');
});
BackgroundGeolocation.on('authorization', function (status) {
console.log('[INFO] BackgroundGeolocation authorization status: ' + status);
if (status !== BackgroundGeolocation.AUTHORIZED) {
// we need to set delay or otherwise alert may not be shown
setTimeout(function () {
var showSettings = confirm('App requires location tracking permission. Would you like to open app settings?');
if (showSetting) {
return BackgroundGeolocation.showAppSettings();
}
}, 1000);
}
});
BackgroundGeolocation.on('background', function () {
console.log('[INFO] App is in background');
// you can also reconfigure service (changes will be applied immediately)
BackgroundGeolocation.configure({
debug: false
});
});
BackgroundGeolocation.on('foreground', function () {
console.log('[INFO] App is in foreground');
BackgroundGeolocation.configure({
debug: false
});
});
BackgroundGeolocation.on('abort_requested', function () {
console.log('[INFO] Server responded with 285 Updates Not Required');
// Here we can decide whether we want stop the updates or not.
// If you've configured the server to return 285, then it means the server does not require further update.
// So the normal thing to do here would be to `BackgroundGeolocation.stop()`.
// But you might be counting on it to receive location updates in the UI, so you could just reconfigure and set `url` to null.
});
BackgroundGeolocation.on('http_authorization', () => {
console.log('[INFO] App needs to authorize the http requests');
});
BackgroundGeolocation.checkStatus(function (status) {
console.log('[INFO] BackgroundGeolocation service is running', status.isRunning);
console.log('[INFO] BackgroundGeolocation services enabled', status.locationServicesEnabled);
console.log('[INFO] BackgroundGeolocation auth status: ' + status.authorization);
// you don't need to check status before start (this is just the example)
if (!status.isRunning) {
BackgroundGeolocation.start(); //triggers start on start event
}
});
},
并在此应用上禁用省电功能,我成功了。
另外,为了确保它能正常工作,我让后端服务器每 60 秒通过无线方式向我发送一个 websocket 数据包。
这很讨厌,但它确实有效。在某些时候,我将开始逐步消除每个依赖项,以查看所需的最低限度,但这有效!
是的,请求以某种方式兑现并设置在应用程序恢复上 - 嗯...
试试这个:
如果可以,请使用“@mauron85/cordova-plugin-background-geolocation”post 模板,或者删除 url 和 syncUrl,并使用 'cordova-plugin-advanced-http' 回调方法在 onLocation() 中发送您自己的 http 请求,它从本机发送请求。
(现在可以在 android 7 - Samsung Galaxy 上为我工作数周)
我正在努力为 android 编写一个 Cordova 应用程序,它将在屏幕关闭后保持 运行。我正在尝试后台和前台服务(有时一起)来保持一个简单的循环 运行:获取我的位置,然后通过 TCP 将 JSON 发送到后端服务器。有没有人有办法解决吗?我是 运行 Android 8.1 Oreo,我尝试在我的应用程序中放置前景、背景和背景-运行 timer npm 包。无论我尝试什么,在关闭我的 phone 屏幕后约 5 分钟后,该应用程序停止与后端服务器通信。我已经禁用了节电措施,我真的被困在这里了。谢谢。
随着 android 的更新版本,Google 越来越多地实现了在后台关闭应用程序的功能。从宏伟的计划来看,这是一件好事,这是为了节省电池寿命,然而,这对开发者来说可不是什么好消息。具体来说,看看他们的文档:doze and adaptive battery.
在撰写本文时,没有 cordova 插件可以为较新的 android 版本提供这些功能(doze 最初是在 android 6.0 中引入的,后来的版本变得更加苛刻)。
除非自己写插件,这里没有很好的答案。将您的应用程序 运行 保持在后台是一项功能,随着新版本 android 的发布,确实(并且将)需要持续维护,也就是说,一般来说,这不是 cordova 擅长的事情。
作为开发工具的 Cordova 不适用于深层原生功能。如果您的主要产品需要快速配套应用程序,请使用 cordova 作为平台。
使用这些插件(使用 cordova 9.0.0):
cordova-background-timer 0.0.4 "BackgroundTimer"
cordova-plugin-background-mode 0.7.2 "BackgroundMode"
cordova-plugin-device 2.0.2 "Device"
cordova-plugin-foreground-service 1.1.1 "Cordova Foreground Service"
cordova-plugin-mauron85-background-geolocation 3.0.1 "CDVBackgroundGeolocation"
cordova-plugin-whitelist 1.3.3 "Whitelist"
还有这个 JavaScript 代码:
onDeviceReady: function () {
this.receivedEvent('deviceready');
cordova.plugins.foregroundService.start('GPS Running', 'Background Service');
cordova.plugins.backgroundMode.on('activate', function () {
console.log("Disabled webview optimizations");
cordova.plugins.backgroundMode.disableWebViewOptimizations();
});
cordova.plugins.backgroundMode.enable();
var socket = io.connect('http://server.com:3000');
socket.on('request', function (empty) {
BackgroundGeolocation.getCurrentLocation(function (location) {
socket.emit('location', JSON.stringify(location));
});
});
BackgroundGeolocation.configure({
locationProvider: BackgroundGeolocation.ACTIVITY_PROVIDER,
desiredAccuracy: BackgroundGeolocation.HIGH_ACCURACY,
notificationTitle: 'Location, Location!',
notificationText: 'enabled',
debug: false,
interval: 30 * 1000,
fastestInterval: 30 * 1000,
activitiesInterval: 30 * 1000
});
BackgroundGeolocation.on('location', function (location) {
// handle your locations here
// to perform long running operation on iOS
// you need to create background task
//console.log("regular location:");
//console.log(location);
BackgroundGeolocation.startTask(function (taskKey) {
// execute long running task
// eg. ajax post location
// IMPORTANT: task has to be ended by endTask
BackgroundGeolocation.endTask(taskKey);
});
});
BackgroundGeolocation.on('stationary', function (stationaryLocation) {
// handle stationary locations here
//console.log("Stationary object");
//console.log(stationaryLocation);
});
BackgroundGeolocation.on('error', function (error) {
console.log('[ERROR] BackgroundGeolocation error:', error.code, error.message);
});
BackgroundGeolocation.on('start', function () {
console.log('[INFO] BackgroundGeolocation service has been started');
});
BackgroundGeolocation.on('stop', function () {
console.log('[INFO] BackgroundGeolocation service has been stopped');
});
BackgroundGeolocation.on('authorization', function (status) {
console.log('[INFO] BackgroundGeolocation authorization status: ' + status);
if (status !== BackgroundGeolocation.AUTHORIZED) {
// we need to set delay or otherwise alert may not be shown
setTimeout(function () {
var showSettings = confirm('App requires location tracking permission. Would you like to open app settings?');
if (showSetting) {
return BackgroundGeolocation.showAppSettings();
}
}, 1000);
}
});
BackgroundGeolocation.on('background', function () {
console.log('[INFO] App is in background');
// you can also reconfigure service (changes will be applied immediately)
BackgroundGeolocation.configure({
debug: false
});
});
BackgroundGeolocation.on('foreground', function () {
console.log('[INFO] App is in foreground');
BackgroundGeolocation.configure({
debug: false
});
});
BackgroundGeolocation.on('abort_requested', function () {
console.log('[INFO] Server responded with 285 Updates Not Required');
// Here we can decide whether we want stop the updates or not.
// If you've configured the server to return 285, then it means the server does not require further update.
// So the normal thing to do here would be to `BackgroundGeolocation.stop()`.
// But you might be counting on it to receive location updates in the UI, so you could just reconfigure and set `url` to null.
});
BackgroundGeolocation.on('http_authorization', () => {
console.log('[INFO] App needs to authorize the http requests');
});
BackgroundGeolocation.checkStatus(function (status) {
console.log('[INFO] BackgroundGeolocation service is running', status.isRunning);
console.log('[INFO] BackgroundGeolocation services enabled', status.locationServicesEnabled);
console.log('[INFO] BackgroundGeolocation auth status: ' + status.authorization);
// you don't need to check status before start (this is just the example)
if (!status.isRunning) {
BackgroundGeolocation.start(); //triggers start on start event
}
});
},
并在此应用上禁用省电功能,我成功了。
另外,为了确保它能正常工作,我让后端服务器每 60 秒通过无线方式向我发送一个 websocket 数据包。
这很讨厌,但它确实有效。在某些时候,我将开始逐步消除每个依赖项,以查看所需的最低限度,但这有效!
是的,请求以某种方式兑现并设置在应用程序恢复上 - 嗯...
试试这个:
如果可以,请使用“@mauron85/cordova-plugin-background-geolocation”post 模板,或者删除 url 和 syncUrl,并使用 'cordova-plugin-advanced-http' 回调方法在 onLocation() 中发送您自己的 http 请求,它从本机发送请求。
(现在可以在 android 7 - Samsung Galaxy 上为我工作数周)