I am working with some application which starts a service.
When I close app under Android 7.0.0 its service is continue working fine.
But under Android 6.0.0 it does not.
I use this snippet to keep working service
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
// We want this service to continue running until it is explicitly
// stopped, so return sticky.
return START_STICKY;
}
What do I missing here?
Code of the service class
import android.Manifest;
//import android.app.LoaderManager;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
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.provider.Settings;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v4.app.ActivityCompat;
//import android.support.v4.content.ContextCompat;
//import android.telephony.TelephonyManager;
import android.text.format.DateFormat;
import android.util.Log;
import com.google.android.gms.location.FusedLocationProviderClient;
import com.google.android.gms.location.LocationCallback;
import com.google.android.gms.location.LocationRequest;
import com.google.android.gms.location.LocationResult;
import com.google.android.gms.location.LocationServices;
import com.google.android.gms.location.LocationSettingsRequest;
import com.google.android.gms.location.SettingsClient;
import com.google.android.gms.tasks.OnFailureListener;
import com.google.android.gms.tasks.OnSuccessListener;
import com.google.gson.Gson;
import java.util.Date;
import java.util.Timer;
//import java.util.TimerTask;
import java.io.*;
import java.net.*;
//import java.util.Timer;
//import java.util.TimerTask;
import static com.google.android.gms.location.LocationServices.getFusedLocationProviderClient;
public class gps_service extends Service {
private static final String TAG = "MyService";
private LocationListener listener;
private LocationManager locationManager;
private Timer timer = new Timer();
// private DLocation dLocation;
private final Object lock = new Object();
Context context;
private LocationRequest mLocationRequest;
private long UPDATE_INTERVAL = 60 * 1000; /* 60 secs */
private long FASTEST_INTERVAL = 10000; /* 10 sec */
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
// We want this service to continue running until it is explicitly
// stopped, so return sticky.
startLocationUpdates();
return START_STICKY;
}
@Override
public void onCreate() {
super.onCreate();
context = this;
}
// Trigger new location updates at interval
protected void startLocationUpdates() {
// Create the location request to start receiving updates
mLocationRequest = new LocationRequest();
mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
mLocationRequest.setInterval(UPDATE_INTERVAL);
mLocationRequest.setFastestInterval(FASTEST_INTERVAL);
// Create LocationSettingsRequest object using location request
LocationSettingsRequest.Builder builder = new LocationSettingsRequest.Builder();
builder.addLocationRequest(mLocationRequest);
LocationSettingsRequest locationSettingsRequest = builder.build();
// Check whether location settings are satisfied
// https://developers.google.com/android/reference/com/google/android/gms/location/SettingsClient
SettingsClient settingsClient = LocationServices.getSettingsClient(this);
settingsClient.checkLocationSettings(locationSettingsRequest);
// new Google API SDK v11 uses getFusedLocationProviderClient(this)
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
return;
}
getFusedLocationProviderClient(this).requestLocationUpdates(mLocationRequest, new LocationCallback() {
@Override
public void onLocationResult(LocationResult locationResult) {
// do work here
onLocationChanged(locationResult.getLastLocation());
}
}, Looper.myLooper());
}
public void getLastLocation() {
// Get last known recent location using new Google Play Services SDK (v11+)
FusedLocationProviderClient locationClient = getFusedLocationProviderClient(this);
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
return;
}
locationClient.getLastLocation()
.addOnSuccessListener(new OnSuccessListener<Location>() {
@Override
public void onSuccess(Location location) {
// GPS location can be null if GPS is switched off
if (location != null) {
onLocationChanged(location);
}
}
})
.addOnFailureListener(new OnFailureListener() {
@Override
public void onFailure(@NonNull Exception e) {
Log.d(TAG, "Ошибка получения последнего GPS позиции");
e.printStackTrace();
}
});
}
public void onLocationChanged(Location location) {
// New location has now been determined
try
{
ComplexPreferences complexPreferences = ComplexPreferences.getComplexPreferences(context, "App_Settings", 0);
AppSettings appSettings = complexPreferences.getObject("App_Settings", AppSettings.class);
if (appSettings != null) {
LocationItem locationItem = new LocationItem();
locationItem.DeviceID = appSettings.getDeviceID();
locationItem.Latitude = Double.toString(location.getLatitude());
locationItem.Longitude = Double.toString(location.getLongitude());
Date d = new Date();
CharSequence timeOfRequest = DateFormat.format("yyyy-MM-dd HH:mm:ss", d.getTime()); // YYYY-MM-DD HH:mm:ss
locationItem.TimeOfRequest = timeOfRequest.toString();
locationItem.SerialNumber = appSettings.getSerialNumber();
//**************** Отправка сообщения в окно *********************
Intent i = new Intent("location_update");
Log.d(TAG, "Рассылка по слушателям в окнах");
DLocation dLocation = new DLocation();
dLocation.Latitude = locationItem.Latitude;
dLocation.Longitude = locationItem.Longitude;
dLocation.TimeOfRequest = locationItem.TimeOfRequest;
dLocation.Errors = "Данные передаются...";
i.putExtra("coordinates", dLocation);
sendBroadcast(i);
//**************** Отправка сообщения в окно *********************
Gson gson = new Gson();
String requestObject = gson.toJson(locationItem);
Log.d(TAG, "Формирование URL API сервера");
String url = appSettings.getIpAddress() + "/api/staff/savedata";
makeRequest(url, requestObject, dLocation);
}
}
catch (Exception ex)
{
Log.d(TAG, "Ошибка: " + ex.getMessage());
}
}
@Override
public void onDestroy() {
super.onDestroy();
if (locationManager != null) {
locationManager.removeUpdates(listener);
}
}
@Nullable
@Override
public IBinder onBind(Intent intent) {
return null;
}
public void makeRequest(String uri, String json, DLocation dLocation) {
HandlerThread handlerThread = new HandlerThread("URLConnection");
handlerThread.start();
Handler mainHandler = new Handler(handlerThread.getLooper());
Runnable myRunnable = createRunnable(uri, json, dLocation);
mainHandler.post(myRunnable);
}
private Runnable createRunnable(final String uri, final String data,final DLocation dLocation){
Runnable aRunnable = new Runnable(){
public void run(){
try {
Log.d(TAG, "Перед запросом HTTP");
//Connect
HttpURLConnection urlConnection;
urlConnection = (HttpURLConnection) ((new URL(uri).openConnection()));
urlConnection.setDoOutput(true);
urlConnection.setRequestProperty("Content-Type", "application/json");
urlConnection.setRequestProperty("Accept", "application/json");
urlConnection.setRequestMethod("POST");
urlConnection.connect();
//Write
OutputStream outputStream = urlConnection.getOutputStream();
BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(outputStream, "UTF-8"));
try {
writer.write(data);
} catch (IOException e) {
e.printStackTrace();
Log.d(TAG,"Ошибка записи в буфер для пережачи по HTTP");
}
writer.close();
outputStream.close();
//Read
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(urlConnection.getInputStream(), "UTF-8"));
String line = null;
StringBuilder sb = new StringBuilder();
while ((line = bufferedReader.readLine()) != null) {
sb.append(line);
}
bufferedReader.close();
String result = sb.toString();
Log.d(TAG, "После запроса HTTP");
Log.d(TAG, result);
// Log.d(TAG, "Результат передачи: " + result);
//**************** Отправка сообщения в окно *********************
Intent iResult = new Intent("location_update");
Log.d(TAG, "Рассылка по слушателям в окнах");
DLocation dLocation = new DLocation();
if(result.equals("true"))
{
dLocation.Errors = "Данные успешно переданы.";
}
else
{
dLocation.Errors = "Ошибка передачи данных.";
}
iResult.putExtra("result", dLocation);
sendBroadcast(iResult);
//**************** Отправка сообщения в окно *********************
}catch( Exception err){
err.printStackTrace();
Log.d(TAG, "Ошибка HTTP " + err.getMessage());
}
}
};
return aRunnable;
}
}
Use attribute android:stopWithTask="false" in manifest, if its true (By default its false if you are not using this in manifest).
restart the service on onTaskRemoved().
As documentation says