'How to access location in background Android 12?

I am making an application that fetch last known location when user clicked power key two times. I am using foreground service to register the broadcast receiver and for location I am using fusedlocationproviderclient. The user can fetch the location while app is in background. My problem is I am only able to fetch location for one time only. Second time location is null. How can I solve it?

Note: It is working fine in android 7 version.

Service:

public class ScreenOnOffBackgroundService extends Service {
private ScreenOnOffReceiver screenOnOffReceiver = null;

@Override
public IBinder onBind(Intent intent) {
    return null;
}

@Override
public int onStartCommand(Intent intent, int flags, int startId) {
    createNotificationChannel();
    Intent mainIntent = new Intent(this, DashboardActivity.class);
    PendingIntent pendingIntent = PendingIntent.getActivity(this,0,mainIntent, 0);
    Notification notification = new NotificationCompat.Builder(this,"safetyId")
            .setContentTitle("Safety Service")
            .setContentText("Press power key to send alert")
            .setSmallIcon(R.drawable.android)
            .setContentIntent(pendingIntent)
            .build();
    startForeground(1,notification);
    return START_STICKY;
}

@Override
public void onCreate() {
    super.onCreate();
    // Create an IntentFilter instance.
    IntentFilter intentFilter = new IntentFilter();
    // Add network connectivity change action.
    intentFilter.addAction("android.intent.action.SCREEN_ON");
    // Set broadcast receiver priority.
    intentFilter.setPriority(100);
    screenOnOffReceiver = new ScreenOnOffReceiver();
    HandlerThread broadcastHandlerThread = new HandlerThread("SafetyThread");
    broadcastHandlerThread.start();
    Looper looper = broadcastHandlerThread.getLooper();
    Handler broadcastHandler = new Handler(looper);
    registerReceiver(screenOnOffReceiver,intentFilter,null,broadcastHandler);
}

private void createNotificationChannel() {

    if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.O ){
        NotificationChannel channel = new NotificationChannel(
                "safetyId",
                "Safety Service",
                NotificationManager.IMPORTANCE_DEFAULT
        );
        NotificationManager manager = getSystemService(NotificationManager.class);
        manager.createNotificationChannel(channel);
    }
}


@Override
public void onDestroy() {

    stopForeground(true);
    stopSelf();
    // Unregister screenOnOffReceiver when destroy.
    if(screenOnOffReceiver!=null)
    {
        unregisterReceiver(screenOnOffReceiver);
    }
}
}

Broadcast Receiver:

public class ScreenOnOffReceiver extends BroadcastReceiver {

private int count = 0;

@Override
public void onReceive(Context context, Intent intent) {
    String action = intent.getAction();
    if (Intent.ACTION_SCREEN_ON.equals(action) || Intent.ACTION_SCREEN_OFF.equals(action)) {
        count++;
        if (count == 2) {
            count = 0;
            DashboardActivity.getInstance().getLastLocation();
        }
    }
}
}

Dashboard Activity:

public class DashboardActivity extends AppCompatActivity {
public Button btnAlert;
private static DashboardActivity instance;
private final static int REQUEST_CODE = 123;
private FusedLocationProviderClient locationProviderClient;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_dashboard);
    instance = this;
    registerService();
    btnAlert = findViewById(R.id.btnAlert);
    locationProviderClient = LocationServices.getFusedLocationProviderClient(this);
    btnAlert.setOnClickListener(view -> getLastLocation());
}

public static DashboardActivity getInstance(){
    return instance;
}

public void registerService(){
    if(!foregroundServiceRunning()){
        Intent backgroundService = new Intent(this, ScreenOnOffBackgroundService.class);
        ContextCompat.startForegroundService(this,backgroundService);
    }
}

public boolean foregroundServiceRunning(){
    ActivityManager manager = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);
    for(ActivityManager.RunningServiceInfo service : manager.getRunningServices(Integer.MAX_VALUE)){
        if(ScreenOnOffBackgroundService.class.getName().equals(service.service.getClassName())){
            return true;
        }
    }
    return false;
}

@SuppressLint("MissingPermission")
public void getLastLocation() {
    // check if permissions are given
    if (checkPermissions()) {
        // check if location is enabled
        if (isLocationEnabled()) {

            locationProviderClient.getLastLocation().addOnCompleteListener(task -> {
                Location location = task.getResult();
                if (location == null) {
                    requestNewLocationData();
                } else {
                    Toast.makeText(this, "Latitude: "+location.getLatitude(), Toast.LENGTH_LONG).show();
                }
            });
        } else {
            Toast.makeText(this, "Please turn on your location", Toast.LENGTH_LONG).show();
            Intent intent = new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS);
            startActivity(intent);
        }
    } else {
        requestPermissions();
    }
}


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

private void requestPermissions() {

    String[] permissionArray = new String[]{
            android.Manifest.permission.ACCESS_COARSE_LOCATION,
            android.Manifest.permission.ACCESS_FINE_LOCATION,};
    ActivityCompat.requestPermissions(this, permissionArray, REQUEST_CODE);
}

@SuppressLint("MissingPermission")
private void requestNewLocationData() {

    LocationRequest mLocationRequest = LocationRequest.create()
            .setInterval(100)
            .setFastestInterval(3000)
            .setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY)
            .setMaxWaitTime(100).setNumUpdates(1);

    locationProviderClient = LocationServices.getFusedLocationProviderClient(this);
    locationProviderClient.requestLocationUpdates(mLocationRequest, mLocationCallback, Looper.myLooper());
}

private final LocationCallback mLocationCallback = new LocationCallback() {

    @Override
    public void onLocationResult(LocationResult locationResult) {
        Location mLastLocation = locationResult.getLastLocation();
    }
};

private boolean isLocationEnabled() {
    LocationManager locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
    return locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER) || locationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER);
}

@Override
public void
onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
    super.onRequestPermissionsResult(requestCode, permissions, grantResults);

    if (requestCode == REQUEST_CODE) {
        if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
            getLastLocation();
        }
    }

    if (requestCode == 0) {
        if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
            notifyPolice();
        }
    }
}

}



Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source