I am making the prototype app, and it's only function is to recieve location updates from foreground service. I think I already read everything in Stackoverflow and in documentation about how to get location updates from foreground service. But app still recieve location updates ONLY when it is visible on the screen. App has only one activity with two buttons - start and stop service, and TextView where I show location updates. I have this permissions in manifest:
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION" />
this is my LocationService declaration in manifest:
<service
android:name=".LocationService"
android:enabled="true"
android:exported="true"
android:foregroundServiceType="location" />
here is my LocationService java class code:
public class LocationService extends Service implements LocationListener {
private Binder binder;
public LocationUpdateListener getUpdateListener() {
return updateListener;
}
private LocationUpdateListener updateListener;
private LocationManager locationManager;
private String locations = "";
public final static String NOTIFICATION_CHANEL_ID = "LocationServiceChannelRu";
@Nullable
@Override
public IBinder onBind(Intent intent) {
return binder;
}
@Override
public void onCreate() {
super.onCreate();
binder = new Binder();
locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
Criteria locationCriteria = new Criteria();
locationCriteria.setAccuracy(Criteria.NO_REQUIREMENT);
locationCriteria.setPowerRequirement(Criteria.NO_REQUIREMENT);
String provider = locationManager.getBestProvider(locationCriteria, true);
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED
&& ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) == PackageManager.PERMISSION_GRANTED) {
locationManager.requestLocationUpdates(provider, 20000, 0, this);
}
Notification notification = new NotificationCompat.Builder(this, NOTIFICATION_CHANEL_ID).setContentTitle("LocationTracker")
.setContentText("Фоновый режим запущен").setPriority(PRIORITY_DEFAULT)
.setCategory(NotificationCompat.CATEGORY_SERVICE).build();
startForeground(1411, notification);
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
Notification notification = new NotificationCompat.Builder(this, NOTIFICATION_CHANEL_ID).setContentTitle("LocationTracker")
.setContentText("Фоновый режим запущен").setPriority(PRIORITY_DEFAULT)
.setCategory(NotificationCompat.CATEGORY_SERVICE).build();
startForeground(1411, notification);
if (locationManager == null) {
locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
Criteria locationCriteria = new Criteria();
locationCriteria.setAccuracy(Criteria.NO_REQUIREMENT);
locationCriteria.setPowerRequirement(Criteria.NO_REQUIREMENT);
String provider = locationManager.getBestProvider(locationCriteria, true);
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED
&& ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) == PackageManager.PERMISSION_GRANTED) {
locationManager.requestLocationUpdates(provider, 20000, 0, this);
}
}
return Service.START_STICKY;
}
public void setListener(LocationUpdateListener updateListener) {
this.updateListener = updateListener;
}
@Override
public void onLocationChanged(@NonNull Location location) {
if (updateListener != null) {
locations += formatMillisToHours(System.currentTimeMillis()) + ": " + location.getLatitude() + ", " + location.getLongitude() + "\n";
updateListener.onLocationUpdated(locations);
}
}
@Override
public void onStatusChanged(String provider, int status, Bundle extras) {
}
@Override
public void onProviderEnabled(@NonNull String provider) {
}
@Override
public void onProviderDisabled(@NonNull String provider) {
}
public void removeListener(LocationUpdateListener updateListener) {
if (this.updateListener != null) {
this.updateListener = null;
}
}
public class Binder extends android.os.Binder {
public LocationService getService() {
return LocationService.this;
}
}
public static String formatMillisToHours(long millis) {
@SuppressLint("SimpleDateFormat")
DateFormat formatter = new SimpleDateFormat("HH:mm:ss");
Date date = new Date(millis);
return formatter.format(date);
}
@Override
public void onDestroy() {
super.onDestroy();
locationManager.removeUpdates(this);
}
my application class onCreate:
@Override
public void onCreate() {
super.onCreate();
NotificationChannel channel;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
channel = new NotificationChannel(LocationService.NOTIFICATION_CHANEL_ID,
"LocationTrackerChannel", NotificationManager.IMPORTANCE_DEFAULT);
((NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE)).createNotificationChannel(channel);
}