这是我第一次在Expo上进行开发,我正在构建一个应用程序,该应用程序可跟踪位置并使用节点每5秒钟将数据发送到服务器。我正在使用来自博览会的TaskManager API,我会遵循所有步骤,并且在获取数据时可以正常工作。但是,当我将应用程序置于后台时,它将停止console.log(data)
。
即使在使用 Expo Dev Tool 的开发环境中,它也应该在后台任务中运行(TaskManager
)?还是必须先进入生产模式才能使用?
当我将应用程序设置为这样的后台模式时,我的console.log
停止工作。
我的示例代码App.js
const LOCATION_TRACKER = 'background-task-location';
export default class App extends Component {
state = {
mapRegion: null,
hasLocationPermissions: false,
locationResult: null,
marker: {
latitude: 0,
longitude: 0
},
latitude: 0,
longitude: 0,
location: null,
errorMessage: null
}
componentDidMount() {
//this.watchCurLocation();
this.onLoad();
}
//init task manager
onLoad = async() => {
let isRegistered = await TaskManager.isTaskRegisteredAsync(LOCATION_TRACKER)
if (!isRegistered) await Location.startLocationUpdatesAsync(LOCATION_TRACKER, {
accuracy: Location.Accuracy.High,
/* after edit */
timeInterval: 2500,
distanceInterval: 5,
})
}
onPress = async () => {
console.log('waiting')
await Location.startLocationUpdatesAsync(LOCATION_TRACKER, {
accuracy: Location.Accuracy.High,
timeInterval: 5000,
distanceInterval: 5
});
console.log('waiting for get task option');
//const data = await TaskManager.getTaskOptionsAsync(LOCATION_TRACKER)
//console.log(data);
};
watchCurLocation = () =>{
this.onPress();
setTimeout(() => {
this.watchCurLocation();
}, 5000);
}
}
TaskManager.defineTask(LOCATION_TRACKER, ({ data, error }) => {
if (error) {
console.log(error)
// Error occurred - check `error.message` for more details.
return;
}
if (data) {
const { locations } = data;
console.log(data)
// do something with the locations captured in the background
}
});
答案 0 :(得分:2)
从Android Oreo起,应用程序在后台运行时将不会运行此类任务。 适当的限制:https://developer.android.com/about/versions/oreo/background#services
您必须在系统托盘中显示一些通知,才能使跟踪器在后台工作。
a)您可以尝试添加使用频道的通知,而无需退出EXPO
https://docs.expo.io/versions/v32.0.0/guides/notification-channels
或b)弹出expo并添加一个前台服务,该服务将在应用程序进入后台时启动
与此类似,只是为了了解这个主意:
public class ForegroundService extends Service {
///....
public void toForeground(){
startForeground(NOTIFICATION_ID, getNotification());
}
public void toBackground(){
stopForeground(true);
}
/**
* Returns the {@link NotificationCompat} used as part of the foreground service.
*/
private Notification getNotification() {
Intent intent = new Intent(this, ForegroundService.class);
// The PendingIntent that leads to a call to onStartCommand() in this service.
PendingIntent servicePendingIntent = PendingIntent.getService(this, 0, intent,
PendingIntent.FLAG_UPDATE_CURRENT);
// The PendingIntent to launch activity.
PendingIntent activityPendingIntent = PendingIntent.getActivity(this, 0,
new Intent(this, MainActivity.class), 0);
NotificationCompat.Builder builder = new NotificationCompat.Builder(this)
.addAction(R.drawable.shell_notification_icon, getString(R.string.launch_activity),
activityPendingIntent)
.setContentText(text)
.setContentTitle(Utils.getLocationTitle(this))
.setOngoing(true)
.setPriority(Notification.PRIORITY_DEFAULT)
.setSmallIcon(R.drawable.shell_notification_icon)
.setTicker(text)
.setDefaults(Notification.DEFAULT_LIGHTS)
.setWhen(System.currentTimeMillis());
// Set the Channel ID for Android O.
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
builder.setChannelId(CHANNEL_ID); // Channel ID
}
return builder.build();
}
//...
}