Getting location updates when in idle mode

514 views Asked by At

I have to find a solution to get location updates when in doze mode. It doesn't matter if the updates are continuous or for every 5 min or more. At the moment I have a foreground service that acquires a wake lock with a LocationListener in it. The app is also whitelisted. My service doesn't get killed when in doze but the gps signal is. I can't find a solution to get a location update. I also tried to start the service with AlarmManager.setExactAndAllowWhileIdle and the service starts in doze but still no locationupdates.

MainActivity that starts the service with button:

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    Button startTrackingServiceButton = (Button) findViewById(R.id.startTrackingServiceButton);
    Button stopTrackingServiceButton = (Button) findViewById(R.id.stopTrackingServiceButton);
    askForWhitelistingApp();

    if (permissionsGranted()) {
        startTrackingServiceButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                askForWhitelistingApp();
                startTrackUserForegroundService();
                //setServiceWithAlarmManager();
            }
        });
        stopTrackingServiceButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                stopTrackUserForegroundService();
            }
        });
    }else{
        ActivityCompat.requestPermissions(this, new String[] {
                        Manifest.permission.ACCESS_FINE_LOCATION,
                        Manifest.permission.ACCESS_COARSE_LOCATION },
                10);
    }
}

private void setServiceWithAlarmManager(){
    Intent intent = new Intent(MainActivity.this, TrackUserForegroundService.class);
    intent.setAction(TrackUserForegroundService.ACTION_START_FOREGROUND_SERVICE);
    PendingIntent pintent = PendingIntent.getService(MainActivity.this, 0, intent, 0);
    AlarmManager alarm = (AlarmManager)getSystemService(Context.ALARM_SERVICE);
    Calendar calendar = new GregorianCalendar();

    calendar.set(Calendar.MINUTE, 40);
    calendar.set(Calendar.SECOND, 20);
    calendar.set(Calendar.HOUR, 3);

    Long time = calendar.getTimeInMillis();
    alarm.setExactAndAllowWhileIdle(AlarmManager.RTC_WAKEUP, time, pintent);
}

private void startTrackUserForegroundService(){
    Intent intent = new Intent(MainActivity.this, TrackUserForegroundService.class);
    intent.setAction(TrackUserForegroundService.ACTION_START_FOREGROUND_SERVICE);
    startService(intent);
}

private void stopTrackUserForegroundService(){
    Intent intent = new Intent(MainActivity.this, TrackUserForegroundService.class);
    intent.setAction(TrackUserForegroundService.ACTION_STOP_FOREGROUND_SERVICE);
    startService(intent);
}

private boolean permissionsGranted() {
    return ContextCompat.checkSelfPermission(this, android.Manifest.permission.ACCESS_FINE_LOCATION) ==
            PackageManager.PERMISSION_GRANTED &&
            ContextCompat.checkSelfPermission(this, android.Manifest.permission.ACCESS_COARSE_LOCATION) ==
                    PackageManager.PERMISSION_GRANTED;
}

private void askForWhitelistingApp(){
    Intent intent = new Intent();
    String packageName = this.getPackageName();
    PowerManager powerManager = (PowerManager) this.getSystemService(Context.POWER_SERVICE);
    if (!powerManager.isIgnoringBatteryOptimizations(packageName)) {
        intent.setAction(Settings.ACTION_REQUEST_IGNORE_BATTERY_OPTIMIZATIONS);
        intent.setData(Uri.parse("package:" + packageName));
        this.startActivity(intent);
    }
}

private PowerManager.WakeLock aquireWakelock(){
    PowerManager pm = (PowerManager) getSystemService(POWER_SERVICE);
    PowerManager.WakeLock wakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "WakeLock");

    return wakeLock;
}

ForegroundService:

@Override
public void onCreate() {
    Log.e(TAG, "onCreate");
    initializeLocationManager();
    try {
        mLocationManager.requestLocationUpdates(
                LocationManager.NETWORK_PROVIDER, LOCATION_INTERVAL, LOCATION_DISTANCE,
                mLocationListeners[1]);
    } catch (java.lang.SecurityException ex) {
        Log.i(TAG, "No right permissions", ex);
    } catch (IllegalArgumentException ex) {
        Log.d(TAG, "Network " + ex.getMessage());
    }
    try {
        mLocationManager.requestLocationUpdates(
                LocationManager.GPS_PROVIDER, LOCATION_INTERVAL, LOCATION_DISTANCE,
                mLocationListeners[0]);
    } catch (java.lang.SecurityException ex) {
        Log.i(TAG, "No right permissions", ex);
    } catch (IllegalArgumentException ex) {
        Log.d(TAG, "Does not have a gps provider" + ex.getMessage());
    }
}

@Override
public int onStartCommand(Intent intent, int flags, int startId) {
    Log.e(TAG, "onStartCommand");
    String action = intent.getAction();

    switch (action){
        case ACTION_START_FOREGROUND_SERVICE:
            Log.d(TAG, "Start tracking user with foreground service.");
            Intent mainActivityIntent = new Intent(this, MainActivity.class);
            PendingIntent mainActivityPendingIntent = PendingIntent.getActivity(this, 0, mainActivityIntent, 0);

            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
                NotificationChannel mChannel = new NotificationChannel("0", "notification_channel", NotificationManager.IMPORTANCE_DEFAULT);
                mChannel.setDescription("Track user service channel");
                mChannel.setShowBadge(true);

                NotificationManager notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
                notificationManager.createNotificationChannel(mChannel);
            }

            NotificationCompat.Builder builder = new NotificationCompat.Builder(this, "0")
                    .setSmallIcon(R.drawable.ic_launcher_foreground)
                    .setContentTitle("Tracking user")
                    .setContentText("Track user with foreground")
                    .setContentInfo("Track user with service")
                    .setAutoCancel(false)
                    .setOngoing(true)
                    .setContentIntent(mainActivityPendingIntent);

            Notification notification = builder.build();

            startForeground(1, notification);
            PowerManager pm = (PowerManager) getSystemService(POWER_SERVICE);
            wakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "WakeLock");
            wakeLock.acquire();

            break;
        case ACTION_STOP_FOREGROUND_SERVICE:
            wakeLock.release();
            stopForeground(true);
            break;
    }
    return START_STICKY;
}

@Override
public void onDestroy() {
    Log.e(TAG, "onDestroy");
    super.onDestroy();
    if (mLocationManager != null) {
        for (int i = 0; i < mLocationListeners.length; i++) {
            try {
                mLocationManager.removeUpdates(mLocationListeners[i]);
            } catch (Exception ex) {
                Log.i(TAG, "Exception:", ex);
            }
        }
    }
}

private void stopTrackUserForegroundService()
{
    Log.d(TAG, "Stop tracking user with foreground service.");

    wakeLock.release();
    stopForeground(true);
    String hallo = "";
}

TrackUserForegroundService.LocationListener[] mLocationListeners = new TrackUserForegroundService.LocationListener[]{
        new TrackUserForegroundService.LocationListener(LocationManager.GPS_PROVIDER),
        new TrackUserForegroundService.LocationListener(LocationManager.NETWORK_PROVIDER)
};

private class LocationListener implements android.location.LocationListener {
    Location mLastLocation;

    public LocationListener(String provider) {
        Log.e(TAG, "LocationListener " + provider);
        mLastLocation = new Location(provider);
    }

    @Override
    public void onLocationChanged(Location location) {
        Log.e(TAG, "onLocationChanged: " + location);
        mLastLocation.set(location);
    }

    @Override
    public void onProviderDisabled(String provider) {
        Log.e(TAG, "onProviderDisabled: " + provider);
    }

    @Override
    public void onProviderEnabled(String provider) {
        Log.e(TAG, "onProviderEnabled: " + provider);
    }

    @Override
    public void onStatusChanged(String provider, int status, Bundle extras) {
        Log.e(TAG, "onStatusChanged: " + provider);
    }
}


private void initializeLocationManager() {
    Log.e(TAG, "initializeLocationManager");
    if (mLocationManager == null) {
        mLocationManager = (LocationManager) getApplicationContext().getSystemService(Context.LOCATION_SERVICE);
    }
}
0

There are 0 answers