The problem is that you haven't used the recommended approach for an app that tracks the location of assets. And you've tried to update the location manually by the getCurrentLocation
method. As matter of fact, the getCurrentLocation
method is used when you won't need location updates constantly. For example, you only need just a single fresh location of a user, for registration, nearby search, etc.
When you need to track an asset constantly, you should listen for location updates by the requestLocationUpdates
method. According to official recommendation
Appropriate use of location information can be beneficial to users of
your app. For example, if your app helps the user find their way while
walking or driving, or if your app tracks the location of assets, it
needs to get the location of the device at regular intervals.
Here I've implemented a full example
package com.example.locationtracker;
import android.Manifest;
import android.content.pm.PackageManager;
import android.location.Location;
import android.os.Bundle;
import android.os.Looper;
import android.view.View;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.ActivityCompat;
import androidx.recyclerview.widget.LinearLayoutManager;
import com.example.locationtracker.databinding.ActivityMainBinding;
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.material.snackbar.Snackbar;
import java.util.ArrayList;
public class MainActivity extends AppCompatActivity {
private boolean isTracking = false;
private FusedLocationProviderClient fusedLocationClient;
private LocationCallback locationCallback;
private LocationRequest locationRequest;
private LocationRecycleViewAdapter locationRecycleViewAdapter;
private final ArrayList<String> locations = new ArrayList<>();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
com.example.locationtracker.databinding.ActivityMainBinding binding = ActivityMainBinding.inflate(getLayoutInflater());
setContentView(binding.getRoot());
binding.location.setLayoutManager(new LinearLayoutManager(getApplicationContext()));
locationRecycleViewAdapter = new LocationRecycleViewAdapter(getApplicationContext(), locations);
binding.location.setAdapter(locationRecycleViewAdapter);
fusedLocationClient = LocationServices.getFusedLocationProviderClient(this);
locationRequest = LocationRequest.create();
locationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
locationRequest.setInterval(12000);
locationRequest.setFastestInterval(2000);
locationRequest.setWaitForAccurateLocation(true);
locationRequest.setSmallestDisplacement(0);
locationCallback = new LocationCallback() {
@Override
public void onLocationResult(@NonNull LocationResult locationResult) {
for (Location location : locationResult.getLocations()) {
System.out.println("New Location Received");
String loc = String.format("lat: %s, lon: %s", location.getLatitude(), location.getLongitude());
locations.add(loc);
locationRecycleViewAdapter.notifyDataSetChanged();
/*locationRecycleViewAdapter = new LocationRecycleViewAdapter(getApplicationContext(), locations);
binding.location.setAdapter(locationRecycleViewAdapter);*/
}
}
};
binding.fab.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
if (!isTracking) {
Snackbar.make(view, "Starting Location Tracking", Snackbar.LENGTH_LONG)
.show();
startLocationUpdates();
} else {
Snackbar.make(view, "Stopping Location Tracking", Snackbar.LENGTH_LONG)
.show();
stopLocationUpdates();
}
}
});
}
@Override
protected void onResume() {
super.onResume();
if (isTracking) {
startLocationUpdates();
}
}
private static final int PERMISSION_REQUEST_CODE = 200;
private void startLocationUpdates() {
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED || ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
requestPermissions(new String[]{Manifest.permission.ACCESS_FINE_LOCATION, Manifest.permission.ACCESS_COARSE_LOCATION}, PERMISSION_REQUEST_CODE);
return;
}
fusedLocationClient.requestLocationUpdates(locationRequest,
locationCallback,
Looper.getMainLooper());
isTracking = true;
}
private void stopLocationUpdates() {
fusedLocationClient.removeLocationUpdates(locationCallback);
isTracking = false;
}
}
AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.locationtracker">
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<application
android:allowBackup="false"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/Theme.LocationTracker">
<activity
android:name=".MainActivity"
android:exported="true"
android:label="@string/app_name"
android:theme="@style/Theme.LocationTracker.NoActionBar">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
Output

Important Notes
Make sure that you have both FINE and COARSE location permissions
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
COARSE Location and PRIORITY_HIGH_ACCURACY are VERY IMPORTANT if you want to retrieve the asset's location in the fastest interval. the below settings are very important as well.
locationRequest = LocationRequest.create();
locationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
locationRequest.setInterval(12000);
locationRequest.setFastestInterval(2000);
locationRequest.setWaitForAccurateLocation(true);
locationRequest.setSmallestDisplacement(0);