Android 带有位置侦听器的后台服务
Android back ground service with location listener
所以我有一个包含位置侦听器的后台服务,我期望的是当我按下主页按钮时,位置侦听器应该被调用,因为位置已更改,并在日志中打印一条消息,所以我知道仍在监听位置变化,但发生的情况是:
-如果我在我的应用程序 activity 中,然后我按下主页按钮,然后我更改了位置,我在日志中看到一条消息,确认侦听器注意到位置更改,但是当我再次更改位置,就像处于暂停状态的侦听器一样,因此任何更改位置的尝试都不会调用侦听器,我在日志中也看不到任何消息,这发生在第一次调用、第二次、第三次调用之后,等等...,位置监听器什么都不做。
返回应用程序主程序 activity,它实际上会一直被再次调用,没有任何问题,除非我再次按下主页按钮。
这是我的服务class
package com.example.husseinjehadalhroub.betawaytracker;
import android.annotation.SuppressLint;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Bundle;
import android.os.Handler;
import android.os.HandlerThread;
import android.os.IBinder;
import android.os.Looper;
import android.os.Message;
import android.widget.Toast;
import static android.os.Process.THREAD_PRIORITY_BACKGROUND;
public class GpsService extends Service {
private Looper mServiceLooper;
private ServiceHandler mServiceHandler;
private LocationManager locationManager;
private int counter = 0;
// Handler that receives messages from the thread
private final class ServiceHandler extends Handler implements LocationListener {
public ServiceHandler(Looper looper) {
super(looper);
}
@SuppressLint("MissingPermission")
@Override
public void handleMessage(Message msg) {
initializeLocationManager();
locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 1000, 3, this);
}
@Override
public void onLocationChanged(Location loc) {
System.out.println("Counter = " + ++counter);
}
@Override
public void onStatusChanged(String provider, int status, Bundle extras) {
}
@Override
public void onProviderEnabled(String provider) {
}
@Override
public void onProviderDisabled(String provider) {
}
}
@Override
public void onCreate() {
// Start up the thread running the service. Note that we create a
// separate thread because the service normally runs in the process's
// main thread, which we don't want to block. We also make it
// background priority so CPU-intensive work doesn't disrupt our UI.
HandlerThread thread = new HandlerThread("ServiceStartArguments",
THREAD_PRIORITY_BACKGROUND);
thread.start();
// Get the HandlerThread's Looper and use it for our Handler
mServiceLooper = thread.getLooper();
mServiceHandler = new ServiceHandler(mServiceLooper);
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
Toast.makeText(this, "service starting", Toast.LENGTH_SHORT).show();
// For each start request, send a message to start a job and deliver the
// start ID so we know which request we're stopping when we finish the job
Message msg = mServiceHandler.obtainMessage();
msg.arg1 = startId;
mServiceHandler.sendMessage(msg);
// If we get killed, after returning from here, restart
return START_STICKY;
}
@Override
public IBinder onBind(Intent intent) {
// We don't provide binding, so return null
return null;
}
@Override
public void onDestroy() {
Toast.makeText(this, "service done", Toast.LENGTH_SHORT).show();
}
private void initializeLocationManager() {
if (locationManager == null)
locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
}
}
所以我有一个包含位置侦听器的后台服务,我期望的是当我按下主页按钮时,位置侦听器应该被调用,因为位置已更改,并在日志中打印一条消息,所以我知道仍在监听位置变化,但发生的情况是:
-如果我在我的应用程序 activity 中,然后我按下主页按钮,然后我更改了位置,我在日志中看到一条消息,确认侦听器注意到位置更改,但是当我再次更改位置,就像处于暂停状态的侦听器一样,因此任何更改位置的尝试都不会调用侦听器,我在日志中也看不到任何消息,这发生在第一次调用、第二次、第三次调用之后,等等...,位置监听器什么都不做。
返回应用程序主程序 activity,它实际上会一直被再次调用,没有任何问题,除非我再次按下主页按钮。
这是我的服务class
package com.example.husseinjehadalhroub.betawaytracker;
import android.annotation.SuppressLint;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Bundle;
import android.os.Handler;
import android.os.HandlerThread;
import android.os.IBinder;
import android.os.Looper;
import android.os.Message;
import android.widget.Toast;
import static android.os.Process.THREAD_PRIORITY_BACKGROUND;
public class GpsService extends Service {
private Looper mServiceLooper;
private ServiceHandler mServiceHandler;
private LocationManager locationManager;
private int counter = 0;
// Handler that receives messages from the thread
private final class ServiceHandler extends Handler implements LocationListener {
public ServiceHandler(Looper looper) {
super(looper);
}
@SuppressLint("MissingPermission")
@Override
public void handleMessage(Message msg) {
initializeLocationManager();
locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 1000, 3, this);
}
@Override
public void onLocationChanged(Location loc) {
System.out.println("Counter = " + ++counter);
}
@Override
public void onStatusChanged(String provider, int status, Bundle extras) {
}
@Override
public void onProviderEnabled(String provider) {
}
@Override
public void onProviderDisabled(String provider) {
}
}
@Override
public void onCreate() {
// Start up the thread running the service. Note that we create a
// separate thread because the service normally runs in the process's
// main thread, which we don't want to block. We also make it
// background priority so CPU-intensive work doesn't disrupt our UI.
HandlerThread thread = new HandlerThread("ServiceStartArguments",
THREAD_PRIORITY_BACKGROUND);
thread.start();
// Get the HandlerThread's Looper and use it for our Handler
mServiceLooper = thread.getLooper();
mServiceHandler = new ServiceHandler(mServiceLooper);
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
Toast.makeText(this, "service starting", Toast.LENGTH_SHORT).show();
// For each start request, send a message to start a job and deliver the
// start ID so we know which request we're stopping when we finish the job
Message msg = mServiceHandler.obtainMessage();
msg.arg1 = startId;
mServiceHandler.sendMessage(msg);
// If we get killed, after returning from here, restart
return START_STICKY;
}
@Override
public IBinder onBind(Intent intent) {
// We don't provide binding, so return null
return null;
}
@Override
public void onDestroy() {
Toast.makeText(this, "service done", Toast.LENGTH_SHORT).show();
}
private void initializeLocationManager() {
if (locationManager == null)
locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
}
}