I have been trying to receive location updates when my phone is locked I am using a service that is launched by my main activity. I receive location updates when the application is open just fine but when locking the phone the service continues to run but the location stored is the same every time.
import static com.example.kromby.mapsapplication.featureOptions.date;
public class BackgroundLocationUpdate extends Service implements GoogleApiClient.ConnectionCallbacks, LocationListener {
// I've removed code that does not relate to the question so please ignore most imports.
private GoogleApiClient mClient;
private boolean connected = false;
private LocationRequest mLocationRequest;
public static List<LatLng> globalLatLng = Collections.synchronizedList(new ArrayList<LatLng>());
public static GoogleMap mMap;
Location mLastLocation;
private static double latitude;
private static double longitude;
public LatLng mLatLng = new LatLng(latitude, longitude);
private static final String TAG = "MapActivity";
#Override
public IBinder onBind(Intent intent) {
return null;
}
#TargetApi(Build.VERSION_CODES.O)
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
Runnable r = new Runnable() {
#Override
public void run() {
buildGoogleApiClient();
}
};
Runnable q = new Runnable() {
#Override
public void run() {
long p = System.currentTimeMillis() + 4000;
boolean continueLooping = true;
while (continueLooping) {
if (System.currentTimeMillis() >= p) {
locationUpdates();
continueLooping = false;
}
}
}
};
Thread mThread = new Thread(r);
Thread mThreadTwo = new Thread(q);
mThread.start();
mThreadTwo.start();
return Service.START_STICKY;
}
public void locationUpdates() {
long i = System.currentTimeMillis();
while (true) {
if (System.currentTimeMillis() == i) {
i = System.currentTimeMillis() + 3000;
// Checks that the application has user permissions to location.
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED
&& ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
return;
}
mLastLocation = LocationServices.FusedLocationApi.getLastLocation(mClient);
// Once the phone is locked this will return the same location each time and not change.
Log.d(TAG, "Client is working " + mClient.isConnected() + "\n Current mLastLocation LatLng " + mLastLocation.getLatitude() + "," + mLastLocation.getLatitude());
latitude = mLastLocation.getLatitude();
longitude = mLastLocation.getLongitude();
Log.d(TAG, "latitude = " + String.valueOf(latitude) );
mLatLng = new LatLng(latitude, longitude);
globalLatLng.add(mLatLng);
Log.d(TAG, "Global List = " + globalLatLng);
}
}
}
protected synchronized void buildGoogleApiClient() {
mClient = new GoogleApiClient.Builder(this)
.addConnectionCallbacks(this)
.addApi(LocationServices.API).build();
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED
&& ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
return;
}
mClient.connect();
}
#Override
public void onConnected(#Nullable Bundle bundle) {
connected = true;
mLocationRequest = new LocationRequest();
mLocationRequest.setInterval(3000);
mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED
&& ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
return;
}
LocationServices.FusedLocationApi.requestLocationUpdates(mClient, mLocationRequest, this);
}
#Override
public void onConnectionSuspended(int i) {
mClient.connect();
}
#Override
public void onDestroy() {
Log.i(TAG, "OnDestroy method called");
}
}
My aim is to receive a location save that into a Latlng list and store it into a text file, that can be read and shown on the map in a polyline. I am running them on two seperate threads because googles api clients does not finish so it wont reach any other code.
Related
This is the error I'm getting: java.lang. Attempt to call the virtual method 'double android.location.Location.getLatitude()' on a null object reference results in a NullPointerException.Can anyone guide me on how to achieve this?
public class MapsActivity extends FragmentActivity implements OnMapReadyCallback,
GoogleApiClient.ConnectionCallbacks ,
GoogleApiClient.OnConnectionFailedListener,
LocationListener {
private GoogleMap mMap;
private ActivityMapsBinding binding;
private static final int MY_PERMISSION_REQUEST_CODE =71922 ;
private static final int PLAY_SERVICES_RESOLUTION_REQUEST = 300193;
private LocationRequest locationRequest;
private GoogleApiClient googleApiClient;
private Location mLastLocation ;
private static int UPDATE_INTERVAL =5000;
private static int FARTEST_INTERVAL =5000;
private static int DISPLACEMENT =10;
Marker marker;
DatabaseReference ref ;
GeoFire geoFire;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
binding = ActivityMapsBinding.inflate(getLayoutInflater());
setContentView(binding.getRoot());
// 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);
ref = FirebaseDatabase.getInstance().getReference("Test");
setupLocation();
}
#Override
public void onRequestPermissionsResult(int requestCode, #NonNull String[] permissions, #NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
switch (requestCode)
{
case MY_PERMISSION_REQUEST_CODE:
if(grantResults.length>0 && grantResults[0] == PackageManager.PERMISSION_GRANTED)
{
if(checkPlayServices())
{
buildGoogleApiCLient();
createLocationRequest();
displayLocation();
}
}
break;
}
}
private void setupLocation() {
try {
if (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION)
!= PackageManager.PERMISSION_GRANTED && ContextCompat.checkSelfPermission(this, android.Manifest.permission.ACCESS_FINE_LOCATION)
!= PackageManager.PERMISSION_GRANTED )
{
ActivityCompat.requestPermissions(this, new String[]{
Manifest.permission.ACCESS_COARSE_LOCATION,
Manifest.permission.ACCESS_FINE_LOCATION
}, MY_PERMISSION_REQUEST_CODE);
}
else {
if(checkPlayServices())
{
buildGoogleApiCLient();
createLocationRequest();
displayLocation();
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
private void displayLocation() {
if (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION)
!= PackageManager.PERMISSION_GRANTED && ContextCompat.checkSelfPermission(this, android.Manifest.permission.ACCESS_FINE_LOCATION)
!= PackageManager.PERMISSION_GRANTED )
{
return;
}
mLastLocation = LocationServices.FusedLocationApi.getLastLocation(googleApiClient);
if(mLastLocation != null)
{
double latitude = mLastLocation.getLatitude();
double longitude = mLastLocation.getLongitude();
Log.d("EDMDEV",String.format("your location was changed: %f %f ",latitude,longitude));
// upDate to firebase
geoFire.setLocation("You", new GeoLocation(latitude, longitude), new GeoFire.CompletionListener() {
#Override
public void onComplete(String key, DatabaseError error) {
if(marker != null){
marker.remove(); //remove old marker
marker = mMap.addMarker(new MarkerOptions()
.position(new LatLng(latitude,longitude))
.title("Ele"));
mMap.animateCamera(CameraUpdateFactory.newLatLngZoom(new LatLng(latitude,longitude),12.0f));
}
}
});
}
else {
Log.d("EDMDEV","cannot get ur location");
}
}
private void createLocationRequest() {
locationRequest = new LocationRequest();
locationRequest.setInterval(UPDATE_INTERVAL);
locationRequest.setFastestInterval(FARTEST_INTERVAL);
locationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
}
private void buildGoogleApiCLient() {
googleApiClient = new GoogleApiClient.Builder(this)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.addApi(LocationServices.API)
.build();
googleApiClient.connect();
}
private boolean checkPlayServices() {
int resultCode = GooglePlayServicesUtil.isGooglePlayServicesAvailable(this);
if (resultCode != ConnectionResult.SUCCESS)
{
if(GooglePlayServicesUtil.isUserRecoverableError(resultCode))
GooglePlayServicesUtil.getErrorDialog(resultCode,this,PLAY_SERVICES_RESOLUTION_REQUEST).show();
else {
Toast.makeText(this, "this device is not support", Toast.LENGTH_SHORT).show();
finish();
}
return false ;
}
return true;
}
/**
* Manipulates the map once available.
* This callback is triggered when the map is ready to be used.
* This is where we can add markers or lines, add listeners or move the camera. In this case,
* we just add a marker near Sydney, Australia.
* If Google Play services is not installed on the device, the user will be prompted to install
* it inside the SupportMapFragment. This method will only be triggered once the user has
* installed Google Play services and returned to the app.
*/
#Override
public void onMapReady(GoogleMap googleMap) {
mMap = googleMap;
// LatLng syd = new LatLng( -34,151);
// mMap.addMarker(new MarkerOptions().position(syd).title("mar in syd"));
// mMap.moveCamera(CameraUpdateFactory.newLatLng(syd));
//Create area
LatLng village = new LatLng(35.7533,-122.4056);
mMap.addCircle(new CircleOptions()
.center(village)
.radius(500) // in meter
.strokeColor(Color.BLUE)
.fillColor(0x220000FF)
.strokeWidth(5.0f)
);
// 0.5f = 0.5km = 500 m
GeoQuery geoQuery = geoFire .queryAtLocation(new GeoLocation(village.latitude,village.longitude),0.5f);
geoQuery.addGeoQueryEventListener(new GeoQueryEventListener() {
#Override
public void onKeyEntered(String key, GeoLocation location) {
sendNotification("EDKDD",String.format("%s entered village area ",key ));
}
#Override
public void onKeyExited(String key) {
sendNotification("EDKDD",String.format("%s no longer village area ",key ));
}
#Override
public void onKeyMoved(String key, GeoLocation location) {
sendNotification("Move",String.format("%s moved within the village area [%f/%f]",key,location.latitude, location.longitude ));
}
#Override
public void onGeoQueryReady() {
}
#Override
public void onGeoQueryError(DatabaseError error) {
Log.e("Error","" + error);// 36.46
}
});
}
private void sendNotification(String title, String content) {
Notification.Builder builder = new Notification.Builder(this)
.setSmallIcon(R.mipmap.ic_launcher_round)
.setContentTitle(title)
.setContentText(content);
NotificationManager notificationManager = (NotificationManager) this.getSystemService(Context.NOTIFICATION_SERVICE);
Intent intent = new Intent(this,MapsActivity.class);
PendingIntent contentIntent = PendingIntent.getActivity(this,0,intent,PendingIntent.FLAG_IMMUTABLE);
builder.setContentIntent(contentIntent);
Notification notification = builder.build();
notification.flags = Notification.DEFAULT_SOUND;
notificationManager.notify(new Random().nextInt(),notification);
}
#Override
public void onConnected(#Nullable Bundle bundle) {
displayLocation();
startLocationUpdate();
}
private void startLocationUpdate() {
if (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION)
!= PackageManager.PERMISSION_GRANTED && ContextCompat.checkSelfPermission(this, android.Manifest.permission.ACCESS_FINE_LOCATION)
!= PackageManager.PERMISSION_GRANTED )
{
return;
}
LocationServices.FusedLocationApi.requestLocationUpdates(googleApiClient,locationRequest,this);
}
#Override
public void onConnectionSuspended(int i) {
}
#Override
public void onConnectionFailed(#NonNull ConnectionResult connectionResult) {
}
#Override
public void onLocationChanged(Location location) {
mLastLocation = location;
displayLocation();
}
}
java.lang.NullPointerException Error
E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.newapp.elephantapplication, PID: 3267
java.lang.NullPointerException: Attempt to invoke virtual method 'com.firebase.geofire.GeoQuery com.firebase.geofire.GeoFire.queryAtLocation(com.firebase.geofire.GeoLocation, double)' on a null object reference
at com.newapp.elephantapplication.MapsActivity.onMapReady(MapsActivity.java:224)
at com.google.android.gms.maps.zzat.zzb(com.google.android.gms:play-services-maps##18.0.0:1)
at com.google.android.gms.maps.internal.zzaq.zza(com.google.android.gms:play-services-maps##18.0.0:5)
at com.google.android.gms.internal.maps.zzb.onTransact(com.google.android.gms:play-services-maps##18.0.0:3)
at android.os.Binder.transact(Binder.java:387)
at eg.aZ(:com.google.android.gms.dynamite_mapsdynamite#220920047#22.09.20 (040308-0):2)
at com.google.maps.api.android.lib6.impl.bk.run(:com.google.android.gms.dynamite_mapsdynamite#220920047#22.09.20 (040308-0):1)
at android.os.Handler.handleCallback(Handler.java:739)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:158)
at android.app.ActivityThread.main(ActivityThread.java:7224)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1230)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1120)
Just getting used to Java and Android and I've got the above error.
Can anyone guide me on how to achieve this?
I write a simple code to show and update the latitude and longitude through GPS. The problem is they remain unchanged when I change the location of AVD.
public class PocketSphinxActivity extends Activity implements
RecognitionListener {
boolean updateOn = false;
private static final int PERMISSIONS_FINE_LOCATION = 99;
TextView tv_lat, tv_lon, tv_add, tv_sen, tv_ud;
#SuppressLint("UseSwitchCompatOrMaterialCode")
Switch sw_locationupdates, sw_GPS;
LocationRequest locationRequest;
LocationCallback locationCallback;
FusedLocationProviderClient fusedLocationProviderClient;
/* Named searches allow to quickly reconfigure the decoder */
private static final String KWS_SEARCH = "wakeup";
private static final String STORE_SEARCH = "store";
private static final String LIBRARY_SEARCH = "library";
private static final String MUSEUM_SEARCH = "museum";
private static final String MENU_SEARCH = "menu";
/* Keyword we are looking for to activate menu */
private static final String KEYPHRASE = "guide me";
/* Used to handle permission request */
private static final int PERMISSIONS_REQUEST_RECORD_AUDIO = 1;
private SpeechRecognizer recognizer;
private TextToSpeech tts;
private HashMap<String, Integer> captions;
#SuppressLint("SetTextI18n")
#Override
public void onCreate(Bundle state) {
super.onCreate(state);
setContentView(R.layout.main);
// Prepare the data for UI
tv_lat = findViewById(R.id.tv_lat);
tv_lon = findViewById(R.id.tv_lon);
tv_add = findViewById(R.id.tv_add);
sw_locationupdates = findViewById(R.id.sw_locationupdates);
tv_sen = findViewById(R.id.tv_sen);
sw_GPS = findViewById(R.id.sw_GPS);
tv_ud = findViewById(R.id.tv_ud);
captions = new HashMap<>();
captions.put(KWS_SEARCH, R.string.kws_caption);
captions.put(MENU_SEARCH, R.string.menu_caption);
captions.put(LIBRARY_SEARCH, R.string.digits_caption);
captions.put(MUSEUM_SEARCH, R.string.phone_caption);
captions.put(STORE_SEARCH, R.string.forecast_caption);
((TextView) findViewById(R.id.caption_text))
.setText("Preparing the recognizer");
// set properties of LocationRequest
locationRequest = LocationRequest.create();
locationRequest.setInterval(1000 * 5);
locationRequest.setFastestInterval(1000 * 1);
locationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
// triggered whenever update interval is met
locationCallback = new LocationCallback() {
#Override
public void onLocationResult(#NonNull LocationResult locationResult) {
super.onLocationResult(locationResult);
Location location = locationResult.getLastLocation();
updateUI(location);
}
};
sw_GPS.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (sw_GPS.isChecked()) {
locationRequest.setPriority(LocationRequest.PRIORITY_BALANCED_POWER_ACCURACY);
tv_sen.setText("Using Tower + Wifi");
} else {
locationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
tv_sen.setText("Using GPS");
}
}
});
//StartLocUpdates();
sw_locationupdates.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (sw_locationupdates.isChecked()) {
//start tracking
StartLocUpdates();
} else {
//stop tracking
StopLocUpdates();
}
}
});
// Check if user has given permission to record audio
int permissionCheck = ContextCompat.checkSelfPermission(getApplicationContext(), Manifest.permission.RECORD_AUDIO);
if (permissionCheck != PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.RECORD_AUDIO}, PERMISSIONS_REQUEST_RECORD_AUDIO);
return;
}
// Recognizer initialization is a time-consuming and it involves IO,
// so we execute it in async task
new SetupTask(this).execute();
updateGPS();
}
private void StopLocUpdates() {
tv_lat.setText("Not tracking location");
tv_lon.setText("Not tracking location");
tv_add.setText("Not tracking location");
tv_ud.setText("Location stop tracking");
fusedLocationProviderClient.removeLocationUpdates(locationCallback);
}
private void StartLocUpdates() {
//tv_ud.setText("stop ");
tv_ud.setText("Location is being tracked");
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
return;
}
fusedLocationProviderClient.requestLocationUpdates(locationRequest,locationCallback,null);
updateGPS();
}
#Override
public void onRequestPermissionsResult(int requestCode, #NonNull String[] permissions, #NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
//PERMISSIONS_REQUEST_RECORD_AUDIO
if (requestCode == PERMISSIONS_FINE_LOCATION || requestCode == PERMISSIONS_REQUEST_RECORD_AUDIO) {
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
// Recognizer initialization is a time-consuming and it involves IO,
// so we execute it in async task
updateGPS();
new SetupTask(this).execute();
} else {
Toast.makeText(this, "This app permission to be granted in order to work properly", Toast.LENGTH_SHORT).show();
finish();
}
}
}
private void updateGPS() {
//get permission
//get current location
//update UI
fusedLocationProviderClient = LocationServices.getFusedLocationProviderClient(PocketSphinxActivity.this);
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED) {
fusedLocationProviderClient.getLastLocation().addOnSuccessListener(this, new OnSuccessListener<Location>() {
#Override
public void onSuccess(Location location) {
//put values into UI
updateUI(location);
}
});
} else {
//
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
requestPermissions(new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, PERMISSIONS_FINE_LOCATION);
}
}
}
private void updateUI(Location location) {
tv_lat.setText(String.valueOf(location.getLatitude()));
tv_lon.setText(String.valueOf(location.getLongitude()));
Geocoder geocoder = new Geocoder(PocketSphinxActivity.this);
try{
List<Address>addresses=geocoder.getFromLocation(location.getLatitude(),location.getLongitude(),1);
tv_add.setText(addresses.get(0).getAddressLine(0));
}
catch(Exception e){
tv_add.setText("Unable to get address");
}
}
}
It seems that the location generated by fusedLocationProviderClient.getLastLocation() in method updateGPS() never changed. I wonder why.
private void updateGPS() {
//get permission
//get current location
//update UI
fusedLocationProviderClient = LocationServices.getFusedLocationProviderClient(PocketSphinxActivity.this);
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED) {
fusedLocationProviderClient.getLastLocation().addOnSuccessListener(this, new OnSuccessListener<Location>() {
#Override
public void onSuccess(Location location) {
//put values into UI
updateUI(location);
}
});
} else {
//
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
requestPermissions(new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, PERMISSIONS_FINE_LOCATION);
}
}
Am trying to set up an app that would notify the user when his/her location is with in the polygon.
I have read about using polyutils library but have not been successful in implementing them.
Here is what i Tried
#Override
public void onMapReady(GoogleMap googleMap) {
mMap = googleMap;
if (checkSelfPermission(Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && checkSelfPermission(Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
return;
}
buildGoogleApiClient();
mMap.setMyLocationEnabled(true);
mMap.setMapType(mMap.MAP_TYPE_SATELLITE);
mMap.moveCamera(CameraUpdateFactory.newLatLng(new LatLng(48.146536, 16.291830)));
mMap.animateCamera(CameraUpdateFactory.zoomTo(18));
DrawPolygon();
// Log.i(TAG, "onLocationChanged: location" + latLng);
}
#Override
public void onConnected(#Nullable Bundle bundle) {
mLocationRequest = new LocationRequest();
mLocationRequest.setInterval(INTERVAL);
mLocationRequest.setFastestInterval(FASTEST_INTERVAL);
mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
if (checkSelfPermission(Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && checkSelfPermission(Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
return;
}
LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient, mLocationRequest, (com.google.android.gms.location.LocationListener) this, null);
Log.d(TAG, "onConnected - isConnected ...............: " + mGoogleApiClient.isConnected());
}
private void DrawPolygon() {
mPolygon1 = mMap.addPolygon(new PolygonOptions()
.strokeColor(COLOR_PURPLE_ARGB)
.add(
new LatLng(48.146536, 16.291830),
new LatLng(48.146772, 16.290146),
new LatLng(48.147397, 16.290380),
new LatLng(48.147177, 16.291970)));
// Store a data object with the polygon, used here to indicate an arbitrary type.
mPolygon1.setTag("alpha");
// Style the polygon.
// stylePolygon(polygon1);
mPolygon2 = mMap.addPolygon(new PolygonOptions()
.strokeColor(COLOR_BLUE_ARGB)
.add(
new LatLng(48.146491, 16.290989),
new LatLng(48.146265, 16.290898),
new LatLng(48.146171, 16.291819),
new LatLng(48.146359, 16.291870)));
mPolygon2.setTag("beta");
}
#Override
public void onConnectionSuspended(int i) {
}
#Override
public void onLocationChanged(Location location) {
mLastLocation = location;
LatLng latLng = new LatLng(location.getLatitude(), location.getLongitude());
mMap.moveCamera(CameraUpdateFactory.newLatLng(latLng));
for (Polygon polgon : getPolygons()) {
if (PolyUtil.containsLocation(latLng, polgon.getPoints(), true)) {
// found it open a info window
Log.i(LOG_TAG, "Your Currently in : " + polgon);
return;
}
}
}
public Collection<Polygon> getPolygons() {
Collection<Polygon> polygons = new ArrayList<Polygon>();
((ArrayList<Polygon>) polygons).add(1, mPolygon1);
((ArrayList<Polygon>) polygons).add(2, mPolygon2);
return polygons;
}
When i run the app the IDE throws an error pointing at the lines indexoutofBounds Exception and the app does not run.
I'm trying to display my current location but I have this problem. I don't know in what part is the error, I put Common.mLastLocation, AND ACCESS_COARSE_LOCATION. Could you help me, please. My Location is resturn NULL, I recently changed my library 'com.google.android.gms:play-services-maps:11.8.0'. My logcat is: Attempt to invoke virtual method 'double android.location.Location.getLatitude()
First part:
public class Home_rider extends AppCompatActivity
implements NavigationView.OnNavigationItemSelectedListener ,
OnMapReadyCallback{
SupportMapFragment mapFragment;
FusedLocationProviderClient fusedLocationProviderClient;
LocationCallback locationCallback;
//Location
private GoogleMap mMap;
private static final int MY_PERMISSION_REQUEST_CODE = 7192; // MY Birthday
private static final int PLAY_SERVICES_RESOLUTION_REQUEST = 300193; // MY CODE
private LocationRequest mLocationRequest;
private GoogleApiClient mGoogleApiClient;
private Location mLastLocation;
private static int UPDATE_INTERVAL = 5000; // 5 secs
private static int FATEST_INTERVAL = 3000;
private static int DISPLACEMENT = 10;
DatabaseReference ref;
GeoFire geoFire;
Marker mUserMarker,markerDestination;
boolean isDriverFound=false;
String driverId="";
int radius = 1; //1km
int distance = 1; //3km
private static final int LIMIT = 3;
//BottomSheet
ImageView imgExpandable;
BottomSheetRiderFragment mBottomSheet;
Button btnPickupRequest;
//Presense system
DatabaseReference driversAvailable;
//Send Alert
IFCMService mService;
PlaceAutocompleteFragment place_location,place_destination;
String mPlaceLocation,mPlaceDestination;
//New Update Information
CircleImageView imageAvatar;
TextView txtRiderName,txtStars;
//Declare FireStorage to upload avatar
FirebaseStorage storage;
StorageReference storageReference;
Get location:
private void setUpLocation() {
//Copy code from Driver APP
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED &&
ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED)
{
//Request runtime permission
ActivityCompat.requestPermissions(this, new String[]{
Manifest.permission.ACCESS_COARSE_LOCATION,
Manifest.permission.ACCESS_FINE_LOCATION
},MY_PERMISSION_REQUEST_CODE);
}
else
{
buildLocationCallBack();
createLocationRequest();
displayLocation();
}
}
private void displayLocation() {
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED &&
ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED)
{
return;
}
fusedLocationProviderClient.getLastLocation().addOnSuccessListener(new OnSuccessListener<Location>() {
#Override
public void onSuccess(Location location) {
Common.mLastLocation = location;
if (Common.mLastLocation != null)
{
//Create LatLng from mLastLocation and this is center point
LatLng center = new LatLng(Common.mLastLocation.getLatitude(),Common.mLastLocation.getLongitude());
//Distance in meters
//Heading 0 is northside , 90 is east, 180 is south and 270 is west
//Base compat
LatLng northSide = SphericalUtil.computeOffset(center,100000,0);
LatLng southSide = SphericalUtil.computeOffset(center,100000,180);
LatLngBounds bounds = LatLngBounds.builder()
.include(northSide)
.include(southSide)
.build();
place_location.setBoundsBias(bounds);
place_destination.setBoundsBias(bounds);
//Presense System
driversAvailable = FirebaseDatabase.getInstance().getReference(Common.driver_tbl);
driversAvailable.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
//If have any change from Drivers table , we will reload all drivers available
loadAllAvailableDriver(new LatLng(Common.mLastLocation.getLatitude(),Common.mLastLocation.getLongitude()));
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
final double latitude = Common.mLastLocation.getLatitude();
final double longitude = Common.mLastLocation.getLongitude();
loadAllAvailableDriver(new LatLng(Common.mLastLocation.getLatitude(),Common.mLastLocation.getLongitude()));
Log.d("MoaguiTaxi",String.format("No se pudo encontrar su ubicación : %f / %f", latitude, longitude));
}
else
{
Log.d("MoaguiTaxi","No se pudo encontrar su ubicación");
}
}
});
}
private void createLocationRequest() {
mLocationRequest = new LocationRequest();
mLocationRequest.setInterval(UPDATE_INTERVAL);
mLocationRequest.setFastestInterval(FATEST_INTERVAL);
mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
mLocationRequest.setSmallestDisplacement(DISPLACEMENT);
}
#Override
public void onMapReady(GoogleMap googleMap) {
try {
boolean isSucces = googleMap.setMapStyle(
MapStyleOptions.loadRawResourceStyle(this,R.raw.my_map_style)
);
if (!isSucces)
Log.e("ERROR","No se cargó el mapa");
}
catch (Resources.NotFoundException ex)
{
ex.printStackTrace();
}
mMap = googleMap;
mMap.getUiSettings().setZoomControlsEnabled(true);
mMap.getUiSettings().setZoomGesturesEnabled(true);
mMap.setInfoWindowAdapter(new CustomInfoWindow(this));
mMap.setOnMapClickListener(new GoogleMap.OnMapClickListener() {
#Override
public void onMapClick(LatLng latLng) {
//First , check markerDestination
//If is not null , just remove available marker
if (markerDestination != null)
markerDestination.remove();
markerDestination = mMap.addMarker(new MarkerOptions()
.icon(BitmapDescriptorFactory.fromResource(R.drawable.destination_marker))
.position(latLng)
.title("Destination"));
mMap.animateCamera(CameraUpdateFactory.newLatLngZoom(latLng,15.0f));
//Show bottom sheet
BottomSheetRiderFragment mBottomSheet = BottomSheetRiderFragment.newInstance(String.format("%f,%f",mLastLocation.getLatitude(),mLastLocation.getLongitude()),
String.format("%f,%f",latLng.latitude,latLng.longitude)
,true);
mBottomSheet.show(getSupportFragmentManager(),mBottomSheet.getTag());
}
});
//Copy code from Driver APP
if (ActivityCompat.checkSelfPermission(Home_rider.this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED &&
ActivityCompat.checkSelfPermission(Home_rider.this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED)
{
return;
}
buildLocationCallBack();
fusedLocationProviderClient.requestLocationUpdates(mLocationRequest,locationCallback, Looper.myLooper());
}
}
It is because you are using mLastLocation.getLatitude() instead of Common.mLastLocation.getLatitude() in your setOnMapClickListener.
The error is basically getLatitude() is being called on null reference.
This is a simple GPS logger. The latitude and longitude values get logged into an SQLite database every 10 seconds.
This works when my app is run for the first time, but when the app is run again the location values are null and my table never gets updated with the values.
public class GPSService extends Service {
public static final String TAG = GPSService.class.getSimpleName();
private static final int ONGOING_NOTIFICATION_ID = 1000;
public static final String GPS_WAKE_LOCK = "GPSWakeLock";
public static final int GPS_TIME_THRESHOLD = 10000; // 10 sec
public static final int GPS_DISTANCE_THRESHOLD = 10; // 10 meters
public static EventBus bus = EventBus.getDefault();
private LocationManager lm;
private LocationManager locationManager2;
private LocationListener locationListener;
private Location location = null;
private Timer timer;
private DumpTask dumpTask = null;
private DatabaseHelper myDb = null;
private static boolean active = false;
private PowerManager.WakeLock wakeLock = null;
public static Double Latitude;
public static Double Longitude;
public static int TotalNoOfStations;
public float[] result = new float[2];
public int k;
public static Boolean SwitchOffAlarmService=false;
#Override
public void onCreate() {
super.onCreate();
bus.register(this);
timer = new Timer();
myDb = DatabaseHelper.getInstance(this);
lm = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
locationManager2 = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
locationListener = new MyLocationListener();
Log.d(TAG, "onCreate ");
k=0;
}
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public void onDestroy() {
Log.d(TAG, "destroyed");
bus.unregister(this);
timer.cancel();
stopService(new Intent(this,GPSService.class));
super.onDestroy();
}
#SuppressWarnings("unused")
public void onEvent(GPSLoggerCommand e) {
if (e.command == GPSLoggerCommand.START && !active) {
Log.d(TAG, "start gps logger");
getRouteDetails();
MainActivity.LocationServiceStarted=true;
getLatLonFromDB();
try {
lm.requestLocationUpdates(LocationManager.GPS_PROVIDER, GPS_TIME_THRESHOLD, GPS_DISTANCE_THRESHOLD, locationListener);
}catch (SecurityException ex){
Log.e(TAG, "onEvent " + ex.toString());
}
dumpTask = new DumpTask();
timer.schedule(dumpTask, GPS_TIME_THRESHOLD, GPS_TIME_THRESHOLD);
active = true;
} else if (e.command == GPSLoggerCommand.STOP && active) {
Log.d(TAG, "stop gps logger");
dumpTask.cancel();
try {
lm.removeUpdates(locationListener);
}catch(SecurityException ex){
Log.e(TAG, "onEvent " + ex);
}
bus.post(new StatusReply("total rows " + myDb.getRowsCount()));
stopForeground(true);
active = false;
locationManager2.sendExtraCommand(LocationManager.GPS_PROVIDER,"delete_aiding_data",null);
Bundle bundle = new Bundle();
locationManager2.sendExtraCommand("gps","force_xtra_injection",bundle);
locationManager2.sendExtraCommand("gps","fource_time_injection",bundle);
stopService(new Intent(this,GPSService.class));
} else if (e.command == GPSLoggerCommand.STATUS) {
Log.d(TAG, "onEvent send message " + active);
bus.post(new GPSLoggerStatus(active));
}
}
public class MyLocationListener implements LocationListener {
public void onLocationChanged(Location loc) {
if (loc != null) {
Log.d(TAG, "onLocationChanged " + loc.getLatitude() + ":" + loc.getLongitude());
location = loc;
}
}
public void onProviderDisabled(String provider) {
Log.d(TAG, "onProviderDisabled");
Toast.makeText(GPSService.this, "Service Canceled due to GPS being Disabled!!", Toast.LENGTH_SHORT).show();
GPSLoggerCommand c;
c = new GPSLoggerCommand(GPSLoggerCommand.STOP);
bus.post(c);
MainActivity.GPServiceStarted=false;
MainActivity.LocationServiceStarted=false;
}
public void onProviderEnabled(String provider) {
Log.d(TAG, "onProviderEnabled");
}
public void onStatusChanged(String provider, int status, Bundle extras) {
String showStatus = null;
if (status == LocationProvider.AVAILABLE)
showStatus = "Available";
if (status == LocationProvider.TEMPORARILY_UNAVAILABLE)
showStatus = "Temporarily Unavailable";
if (status == LocationProvider.OUT_OF_SERVICE)
showStatus = "Out of Service";
Log.d(TAG, "onStatusChanged " + showStatus);
}
}
public class DumpTask extends TimerTask {
#Override
public void run() {
Log.d(TAG, "dump to base");
if (location != null) {
// write to database
}
}
}
public static void StopServiceFunction()
{
GPSLoggerCommand c;
c = new GPSLoggerCommand(GPSLoggerCommand.STOP);
bus.post(c);
MainActivity.GPServiceStarted=false;
MainActivity.LocationServiceStarted=false;
active = false;
}
}
implement GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener, LocationListener
in your activity and past below code in override methods
#Override
public void onConnected(#Nullable Bundle bundle) {
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
// TODO: Consider calling
// ActivityCompat#requestPermissions
// here to request the missing permissions, and then overriding
// public void onRequestPermissionsResult(int requestCode, String[] permissions,
// int[] grantResults)
// to handle the case where the user grants the permission. See the documentation
// for ActivityCompat#requestPermissions for more details.
return;
}
Location location = LocationServices.FusedLocationApi.getLastLocation(mGoogleApiClient);
if (location == null) {
LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient, mLocationRequest, (com.google.android.gms.location.LocationListener) this);
} else {
mCurrentLatitude = location.getLatitude();
mCurrentLongitude = location.getLongitude();
Toast.makeText(this, mCurrentLongitude + " * ********"+mCurrentLatitude, Toast.LENGTH_LONG).show();
}
}