我从事一项需要从特定时间开始注视/停止,收集用户位置并将其发送到API的服务。
我这样开始服务
Calendar calendar = Calendar.getInstance();
calendar.setTimeInMillis(System.currentTimeMillis());
calendar.set(Calendar.HOUR_OF_DAY, CONSTANTES.START_HOURS); //6
calendar.set(Calendar.MINUTE, CONSTANTES.START_MINUTES); //30
calendar.set(Calendar.SECOND, CONSTANTES.START_SECOND);
AlarmManager alarm = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
PendingIntent pendingIntent = PendingIntent.getBroadcast(this, 0,
new Intent(MainActivity.this, AlarmTask.class).setAction("START_SERVICE"), PendingIntent.FLAG_UPDATE_CURRENT);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
alarm.setExactAndAllowWhileIdle(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), pendingIntent);
} else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
alarm.setExact(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), pendingIntent);
} else {
alarm.set(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), pendingIntent);
}
我的接收器
public class AlarmTask extends WakefulBroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equalsIgnoreCase("STOP_SERVICE")) {
System.out.println("service : got stop instruction");
if (isMyServiceRunning(context, ScheduleOffsetService.class)) {
context.stopService(new Intent(context, ScheduleOffsetService.class));
}
} else if (intent.getAction().equalsIgnoreCase("START_SERVICE")) {
System.out.println("service : got start instruction");
if (!isMyServiceRunning(context, ScheduleOffsetService.class)) {
context.startService(new Intent(context, ScheduleOffsetService.class));
}
}
}
private boolean isMyServiceRunning(Context context, Class<?> serviceClass) {
ActivityManager manager = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
for (ActivityManager.RunningServiceInfo service : manager.getRunningServices(Integer.MAX_VALUE)) {
if (serviceClass.getName().equals(service.service.getClassName())) {
return true;
}
}
return false;
}
}
我的服务:
public class ScheduleOffsetService extends Service {
private LocationManager mLocationManager;
private ArrayList<Location> locations = new ArrayList<>();
private String token;
public ScheduleOffsetService() {
}
private class LocationListener implements android.location.LocationListener {
Location mLastLocation;
public LocationListener(String provider) {
mLastLocation = new Location(provider);
}
@Override
public void onLocationChanged(Location location) {
System.out.println("Scheduler location : " + location);
mLastLocation.set(location);
locations.add(location);
}
@Override
public void onStatusChanged(String provider, int status, Bundle extras) {
}
@Override
public void onProviderEnabled(String provider) {
}
@Override
public void onProviderDisabled(String provider) {
}
}
LocationListener[] mLocationListeners = new LocationListener[] {
new LocationListener(LocationManager.GPS_PROVIDER),
new LocationListener(LocationManager.NETWORK_PROVIDER)
};
@Nullable
@Override
public IBinder onBind(Intent intent) {
return null;
}
@Override
public void onCreate() {
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
stopSelf();
}
if (mLocationManager == null) {
mLocationManager = (LocationManager) getApplicationContext().getSystemService(Context.LOCATION_SERVICE);
}
try {
mLocationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 1000 * 60, 10f, mLocationListeners[1]);
} catch (java.lang.SecurityException ex) {
} catch (IllegalArgumentException ex) {
}
try {
mLocationManager.requestLocationUpdates(
LocationManager.GPS_PROVIDER, 1000 * 60, 10f, mLocationListeners[0]);
} catch (java.lang.SecurityException ex) {
} catch (IllegalArgumentException ex) {
}
PropertyApp app = new PropertyApp(this);
System.out.println("ScheduleOffset token : " + app.getToken());
if (app.getToken() != null) {
token = app.getToken();
} else {
stopSelf();
}
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
System.out.println("Scheduler : created");
return START_STICKY;
}
private boolean gpsIsEnable() {
LocationManager manager = (LocationManager) getSystemService(LOCATION_SERVICE);
return manager.isProviderEnabled(LocationManager.GPS_PROVIDER);
}
@Override
public void onDestroy() {
if (mLocationManager != null) {
for (int i = 0; i < mLocationListeners.length; i++) {
try {
mLocationManager.removeUpdates(mLocationListeners[i]);
} catch (Exception ex) {
}
}
}
onEnd();
System.out.println("Scheduler : got destroyed");
super.onDestroy();
}
private void onEnd() {
if (locations.isEmpty()) {
return;
}
Gson gson = new GsonBuilder()
.setLenient()
.create();
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(/*URL*/)
.addConverterFactory(GsonConverterFactory.create(gson))
.build();
WebServiceInterface webServiceInterface = retrofit.create(WebServiceInterface.class);
JsonObject object = new JsonObject();
for (int i = 0; i < locations.size(); i++) {
JsonObject content = new JsonObject();
content.addProperty("lat", locations.get(i).getLatitude());
content.addProperty("lng", locations.get(i).getLongitude());
Date c = Calendar.getInstance().getTime();
SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd");
String formattedDate = df.format(c);
content.addProperty("date", formattedDate);
object.add(String.valueOf(i), content);
}
String data = object.toString();
Call<ResponseRetrofitIreby> call = webServiceInterface.jetLagService(token, PropertyApp.PARNTER_ID, data);
call.enqueue(new Callback<ResponseRetrofitIreby>() {
@Override
public void onResponse(Call<ResponseRetrofitIreby> call, Response<ResponseRetrofitIreby> response) {
if (response.isSuccessful()) {
System.out.println("RESPONSE : " + response.body().getTrackingPosition().getErreur());
}
}
@Override
public void onFailure(Call<ResponseRetrofitIreby> call, Throwable t) {
t.printStackTrace();
}
});
}
}
问题是:当用户要求进行跟踪时,不再调用我的服务的侦听器。 而且,如果用户终止了该应用程序,则该服务似乎会重新启动,从而清空我的位置列表。
有人可以向我解释吗?