I'm trying to learn SmartLocationLibrary for Android to get location and the location I get from it is always null, so I get null object reference errors when I try to do something with it.
I made a Utility class for SmartLocatonLibrary
public class LocationUtil implements OnLocationUpdatedListener, OnActivityUpdatedListener {
private final String TAG = "LocationUtil: ";
private Location location;
private DetectedActivity activity;
private LocationGooglePlayServicesProvider provider;
private Context context;
public LocationUtil(Context context) {
this.context = context;
}
/**
* If lastLocation is not null then the location is set to last location recorded by phone
*/
public void getLastLocation(){
Location lastLocation = SmartLocation.with(context).location().getLastLocation();
if(lastLocation != null){
location = lastLocation;
}
DetectedActivity detectedActivity = SmartLocation.with(context).activity().getLastActivity();
if(detectedActivity != null) activity = detectedActivity;
}
/**
* Basically this starts the location tracking
* If you want one tick of location use .oneFix() on the smartLocation builder
* If you want continous tracking just don't add the .oneFix()
*/
public void startLocation(){
provider = new LocationGooglePlayServicesProvider();
provider.setCheckLocationSettings(true);
SmartLocation smartLocation = new SmartLocation.Builder(context).logging(true).build();
smartLocation.location(provider)
.continuous()
.start(this);
smartLocation.activity()
.start(this);
}
/**
* This stops the tracking
*/
public void stopLocation(){
SmartLocation.with(context).location().stop();
Log.d(TAG, "stopLocation: Location Stopped");
SmartLocation.with(context).activity().stop();
Log.d(TAG, "stopLocation: Activity Recognition Stopped");
}
@Override
public void onActivityUpdated(DetectedActivity detectedActivity) {
this.activity = detectedActivity;
}
@Override
public void onLocationUpdated(Location location) {
this.location = location;
}
//--------SETTERS----------
public void setProvider(LocationGooglePlayServicesProvider provider) {
this.provider = provider;
}
//--------GETTERS----------
public Location getLocation() {
return location;
}
public LocationGooglePlayServicesProvider getProvider() {
return provider;
}
}
And here is the Maps Activity that use it
public class MapsActivity extends FragmentActivity implements OnMapReadyCallback {
private final String TAG = "MAPY";
private int LOCATION_PERMISSION_ID = 1001;
private GoogleMap mMap;
Location location;
LocationUtil locationUtil = new LocationUtil(MapsActivity.this);
Button centerButton;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_maps);
// Obtain the SupportMapFragment and get notified when the map is ready to be used.
SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager()
.findFragmentById(R.id.map);
mapFragment.getMapAsync(this);
centerButton = findViewById(R.id.centerCameraBtn);
centerButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if(location != null)
mMap.moveCamera((CameraUpdateFactory.newLatLng(new LatLng(location.getLatitude(), location.getLongitude()))));
}
});
}
@Override
protected void onStop() {
super.onStop();
locationUtil.stopLocation();
}
@Override
public void onMapReady(GoogleMap googleMap) {
mMap = googleMap;
//Check for permissions if they are not granted request them
if (ContextCompat.checkSelfPermission(MapsActivity.this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED){
ActivityCompat.requestPermissions(MapsActivity.this, new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, LOCATION_PERMISSION_ID);
return;
} else{
locationUtil.startLocation();
}
locationUtil.getLastLocation();
Log.d(TAG, "onMapsReady.lat: " + location.getLatitude() + " onMapsReady.lng: " + location.getLongitude());
location = locationUtil.getLocation();
LatLng currentLocation = new LatLng(location.getLatitude(), location.getLongitude());
mMap.addMarker(new MarkerOptions().position(currentLocation).title("My current location").snippet("This is a sinppet"));
mMap.moveCamera(CameraUpdateFactory.newLatLng(currentLocation));
}
@Override
protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if(locationUtil.getProvider() != null){
locationUtil.getProvider().onActivityResult(requestCode, resultCode, data);
}
}
}
I did it like the author of the library showed here but it doesn't work. And the funny thing is it worked yesterday. I'm testing it on my personal phone. The location, mobile data and wifi are turned on and working fine. I got the permissions, i added the permissions to the manifest(both FINE and COARSED) and in my dependencies are
implementation 'com.android.support:appcompat-v7:28.0.0' implementation 'com.android.support:support-v4:28.0.0' implementation 'com.android.support:support-media-compat:28.0.0' implementation 'io.nlopez.smartlocation:library:3.3.3' implementation 'com.google.android.gms:play-services-maps:16.0.0' implementation 'com.google.android.gms:play-services-location:16.0.0' testImplementation 'junit:junit:4.12' androidTestImplementation 'com.android.support.test:runner:1.0.2' androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2' implementation 'com.android.support.constraint:constraint-layout:1.1.3'
I really don't know whats going on, please help me.
OK so this doesn't work because I want to log the value of the location variable that hasn't been initialised. Debugging it with debugger shows that I'm getting the location. But to be more funny since this is a project just to test the library in the main app the same Utility class won't fetch me a location even if I'm doing everything same as here...
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.