i have class implements Serializable :
public class LocationUtilGPSNetwork implements Serializable
{
private Context mContext;
private LocationManager mLocationManager;
// private LocationListener mListenerPassive;
private LocationListener mListenerNetwork;
private LocationListener mListenerGPS;
private Location mLocation;
private long mTimeLimit;
public LocationUtilGPSNetwork(Context context)
{
mContext = context;
mLocationManager = (LocationManager) mContext.getSystemService(Context.LOCATION_SERVICE);
mListenerNetwork = new LocationListener()
{
#Override
public void onLocationChanged(Location location)
{
updateLocation(location);
Log.i("Location", "Network:" + location);
}
#Override
public void onStatusChanged(String s, int i, Bundle bundle)
{
}
#Override
public void onProviderEnabled(String s)
{
}
#Override
public void onProviderDisabled(String s)
{
}
};
mListenerGPS = new LocationListener()
{
#Override
public void onLocationChanged(Location location)
{
updateLocation(location);
Log.i("Location", "GPS:" + location);
}
#Override
public void onStatusChanged(String s, int i, Bundle bundle)
{
}
#Override
public void onProviderEnabled(String s)
{
}
#Override
public void onProviderDisabled(String s)
{
}
};
}
public void startLocationListeners(long minTimeUpdate, float minDistanceUpdate, long timeLimit)
{
mTimeLimit = timeLimit;
mLocationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, minTimeUpdate,
minDistanceUpdate, mListenerNetwork);
mLocationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, minTimeUpdate,
minDistanceUpdate, mListenerGPS);
}
private void updateLocation(Location location)
{
if (location != null && isBetterLocation(location, mLocation))
{
mLocation = location;
}
}
private boolean isBetterLocation(Location location, Location currentBestLocation)
{
if (currentBestLocation == null)
{
// A new location is always better than no location
return true;
}
// Check whether the new location fix is newer or older
long timeDelta = location.getTime() - currentBestLocation.getTime();
boolean isSignificantlyNewer = timeDelta > mTimeLimit;
boolean isSignificantlyOlder = timeDelta < -mTimeLimit;
boolean isNewer = timeDelta > 0;
// If it's been more than two minutes since the current location, use the new location
// because the user has likely moved
if (isSignificantlyNewer)
{
return true;
}
// If the new location is more than two minutes older, it must be worse
else if (isSignificantlyOlder)
{
return false;
}
// Check whether the new location fix is more or less accurate
int accuracyDelta = (int) (location.getAccuracy() - currentBestLocation.getAccuracy());
boolean isLessAccurate = accuracyDelta > 0;
boolean isMoreAccurate = accuracyDelta < 0;
boolean isSignificantlyLessAccurate = accuracyDelta > 200;
// Check if the old and new location are from the same provider
boolean isFromSameProvider = isSameProvider(location.getProvider(),
currentBestLocation.getProvider());
// Determine location quality using a combination of timeliness and accuracy
if (isMoreAccurate)
{
return true;
}
else if (isNewer && !isLessAccurate)
{
return true;
}
else if (isNewer && !isSignificantlyLessAccurate && isFromSameProvider)
{
return true;
}
return false;
}
private boolean isSameProvider(String provider1, String provider2)
{
if (provider1 == null)
{
return provider2 == null;
}
return provider1.equals(provider2);
}
public Location getLocation()
{
return mLocation;
}
public void stopLocationListeners()
{
mLocationManager.removeUpdates(mListenerNetwork);
mLocationManager.removeUpdates(mListenerGPS);
}
}
And when i put it into bundle :
bundle.putSerializable(MenuActivity.locationID, mLocationUtil);
i have this error
10-10 12:27:42.970: E/AndroidRuntime(20130): Caused by:
java.io.NotSerializableException:
com.pattindo.tilangapp.activity.MenuActivity
Why??
Because some members are not serializable!
You have other options,
Write your own serialize methods. see here
Create a class that includes only members that can be serializable and you really use as data, then instantiate and put it to bundle.
It is not serializable. Please, read more about serializable objects. It must have a non parameter public constructor. Must use serializable properties. Must follow java bean notation.
In no way you can serialize such a monster with, even, the context within!!!
Related
I am running a sensor and location service, the data is passed to the TraceManager file which where it is dealt with and passed to the TraceCWrapper to be mapped to a shared C library .so , It seems the sensor and location data is fine and received in TraceManager, it then is passed into TraceCWrapper, however the app crashes after a few seconds, and the only error line i get is:
A/libc: Fatal signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 0x8 in tid 29938 (AsyncTask #1), pid 29870 (pp.traceandroid)
public class TraceManager extends AppCompatActivity {
private String TAG = "TraceManager";
private int phoneAngle = 0;
private double initialStepCalibrationOffset;
private int initialPointingAngleDeg = 0;
private int initialAlignmentMode = 0;
private int startingFloorID = 0;
private LatLng startingLatLong;
private double startingAccuracy = 1.0;
private Context context;
private boolean isMagConsistentAtInit = false;
private boolean isMagValid = true;
private Timer callBackTimer;
private String[] contentsStatic;
private String[] contentsDynamic;
private boolean isRunning = false;
private TraceCWrapper traceCWrapper = new TraceCWrapper();
Handler callbackHandler = new Handler();
Runnable callbackRunnable;
//internal use only
private boolean _traceCDontActuallyUse;
// The interval, in seconds, for providing trace updates.
public ObservableDouble updateCallbackInterval = new ObservableDouble(0){
#Override
public void addOnPropertyChangedCallback(#NonNull OnPropertyChangedCallback callback) {
if(isRunning){
stopCallbackTimer();
startCallbackTimer();
}
super.addOnPropertyChangedCallback(callback);
}
};
private double updateCallBackIntervalValue = updateCallbackInterval.get();
/// A Boolean value
public ObservableBoolean allowsBackgroundExecution = new ObservableBoolean(false){
#Override
public void addOnPropertyChangedCallback(#NonNull OnPropertyChangedCallback callback) {
if(isRunning){
stopUpdatingTrace();
startUpdatingTrace();
}
super.addOnPropertyChangedCallback(callback);
}
};
private boolean allowsBackgroundExecutionValue = allowsBackgroundExecution.get();
public TraceManager(Context context){
this.context=context;
}
public TraceManager(){
}
public void initialiseTrace(String[] mapFloors,
String[] initialDynamicMaps,
int phoneRelativeToBodyDegree, //this comes from onboarding?
double updateCallBackIntervalValue,
boolean allowsBackgroundExecutionValue,
double initialStepCalibrationOffset, //standard
String[] iBeaconUUIDs,
int startingFloorID,
LatLng startingLatLong, //this is form the starting node
double startingAccuracy, //
boolean _traceCDontActuallyUse,
int phoneOrientation,
int phoneOrientationUse,
boolean magntometerValid
){
this.contentsStatic = mapFloors;
this.contentsDynamic = initialDynamicMaps;
this.phoneAngle = phoneRelativeToBodyDegree;
this.initialStepCalibrationOffset = initialStepCalibrationOffset;
this.updateCallbackInterval = updateCallbackInterval;
this.allowsBackgroundExecution = allowsBackgroundExecution;
this.isMagValid = magntometerValid;
if(!(iBeaconUUIDs.length <=0)){
LocationProvider.arrayOfUUIDsToDetect = iBeaconUUIDs;
}else{
Log.i(TAG, "TraceManager.init: ignoring ibeaconUIDs, because it is empty. Default used");
};
this.startingFloorID = startingFloorID;
this.startingLatLong = startingLatLong;
this.startingAccuracy = startingAccuracy;
this.initialPointingAngleDeg = phoneOrientation;
this.initialAlignmentMode = phoneOrientationUse;
//internal use only
this._traceCDontActuallyUse = _traceCDontActuallyUse;
}
//Functions
/// Broadcast Receiver to get readings from MotionProvider/service
public void startUpdatingSensors(){
//Start sensor service
Intent startService = new Intent(TraceManager.this, SensorService.class);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
startForegroundService(startService);
} else {
startService(startService);
}
}
/// Starts the generation of trace updates.
public void startUpdatingTrace(){
//Start Sensors
//startUpdatingSensors();
//register for sensorBroadcast
BroadcastReceiver sensorReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
Log.d(TAG, "imu Received");
TCIMUEvent tcimuEvent = (TCIMUEvent) intent.getSerializableExtra("imu");
traceCWrapper.provideDeviceMotion(tcimuEvent, 1, 90, RotationMode.PortraitYUp);
}
};
LocalBroadcastManager.getInstance(context).registerReceiver(
sensorReceiver, new IntentFilter("imuCreated")
);
//register for locationBroadcast
//register for sensorBroadcast
BroadcastReceiver locationReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
Log.d(TAG, "location Received");
TCLocationEvent tcLocationEvent = (TCLocationEvent) intent.getSerializableExtra("locationCreated");
Log.d(TAG, "Inlocation reciever");
traceCWrapper.provideLocation(tcLocationEvent);
}
};
LocalBroadcastManager.getInstance(context).registerReceiver(
locationReceiver, new IntentFilter("locationCreated")
);
Log.d(TAG, "inside updating trace");
//Start CallbackTimer
startCallbackTimer();
}
private void CallbackUpdate() {
/* callbackRunnable = new Runnable(){
#Override
public void run() {
Log.d(TAG, "calling callback");
traceCWrapper.getLatestTraceResult();
callbackHandler.postDelayed(this, 1000);
}
};*/
}
private void startCallbackTimer(){
Log.d(TAG, "I get in here callback");
callbackRunnable = new Runnable(){
#Override
public void run() {
Log.d(TAG, "calling callback");
traceCWrapper.getLatestTraceResult();
callbackHandler.postDelayed(this, 1000);
}
};
callbackHandler.postDelayed(callbackRunnable, 1000);
}
private void stopCallbackTimer(){
callbackHandler.removeCallbacks(callbackRunnable);
}
//Calls TraceCWrapper upadate maps and passes the dynamic maps
/* public void updateMaps(String[] dynamicMaps){
traceCWrapper.updateMaps(dynamicMaps dynamicmaps){
}
}*/
public void stopUpdatingTrace(){
boolean stopSensors = true;
if(stopSensors){
stopUpdatingSensors();
}
//Callback Timer
stopCallbackTimer();
//State
isRunning = false;
//Trace terminate
if (_traceCDontActuallyUse == false){
traceCWrapper.terminate();
}
}
private void stopUpdatingSensors() {
//todo
//stop the event bus
//stop the service
}
#RequiresApi(api = Build.VERSION_CODES.O)
public void provideManualLocation(TraceManualLocation manualLocation){
if(isRunning){
}else{
Log.e(TAG, "Calling provideManualLocation, but is running is set to false");
}
if(!_traceCDontActuallyUse){
traceCWrapper.provideManualLocation(manualLocation);
}
}
#RequiresApi(api = Build.VERSION_CODES.O)
public void provideManualHeadingCorrection(TraceManualHeading traceManualHeading){
if(isRunning){
}else{
Log.e(TAG, "Calling provideHeadingCorrection, but is running is set to false");
}
if (!_traceCDontActuallyUse){
traceCWrapper.provideManualHeading(traceManualHeading);
}
}
public void updateParameter(TraceCVarParameter traceCVarParameter, double value){
if(isRunning){
}else{
Log.e(TAG, "Calling updateparameter, but is running is set to false");
}
//todo
//callback async
}
//Private [START]
boolean isInitialised = false;
public boolean isInitialised() {
if(!isInitialised){
}else{
//todo
//send to didfinishinitialisation? confirm isMagConsistentAtInit is true
}
return isInitialised;
}
private boolean isMagConsistantAtInit = false;
private Timer callbackTimer;
/* public traceCallBack(int seconds){
callBackTimer = new Timer();
callBackTimer.schedule(new callUpdate(), seconds*1000);
}*/
class callUpdate extends TimerTask{
#Override
public void run() {
//traceCWrapper.getLatestTraceResult();
}
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_trace_manager);
}
}
I do not have enough room to add the TraceCWrapper file however the library is loaded as:
static CLibrary lib = Native.loadLibrary("com.waymap.app.traceandroid", CLibrary.class);
And as the main example the method, traceCWrapper.provideDeviceMotion() is received in TraceCWrapper as:
//Provide Device Motion
public static boolean provideDeviceMotion(TCIMUEvent mTCIMUEvent, int Status, double userHeadingDeg, float rotationMode){
DeviceMotion dM = new DeviceMotion();
dM.setTcimuEvent(mTCIMUEvent);
dM.setStatus(Status);
dM.setUserHeadingDeg(userHeadingDeg);
dM.setRotationMode(rotationMode);
if(isRunning) {
new sendToTraceHandleImuEvent().execute(dM);
isInitalized = true;
return isInitalized;
}else{
Log.i(TAG, "IMU update ignored as not running");
isInitalized = false;
return isInitalized;
}
}
public static class sendToTraceHandleImuEvent extends AsyncTask<DeviceMotion,Void,Void>{
#Override
protected Void doInBackground(DeviceMotion... devicemotions) {
/*public class Arg extends Structure {
public devicemotions[] var1 = new byte[9];
public devicemotions[] var2 = new byte[5];
}*/
Log.d(TAG, "InTraceCwrapper Again, provideIMU");
lib.TraceHandleImuEvent(devicemotions[0].getTcimuEvent(), devicemotions[0].getStatus(), devicemotions[0].getUserHeadingDeg(), devicemotions[0].getRotationMode());
return null;
}
}
You will have to excuse the large amount of Logging and excess code as i have been wrestling with this for a while.
When passing my TCIMUEvent i am using the structure annotation as below:
#Structure.FieldOrder({ "time", "accel", "accelValid", "mag", "magValid", "gyro", "gyroValid", "pressure", "pressureValid", "temperature", "temperatureValid"})
public class TCIMUEvent extends Structure implements Serializable {
public double time;
public float[] accel = new float[3];
public boolean accelValid;
public float[] mag = new float[3];
public boolean magValid;
public float[] gyro = new float[3];
public boolean gyroValid;
public float pressure;
public boolean pressureValid;
public float temperature;
public boolean temperatureValid;
public TCIMUEvent(double time, float[] accel, boolean accelValid, float[] mag, boolean magValid, float[] gyro, boolean gyroValid, float pressure, boolean pressureValid, float temperature, boolean temperatureValid) {
this.time = time;
this.accel = accel;
this.accelValid = accelValid;
this.mag = mag;
this.magValid = magValid;
this.gyro = gyro;
this.gyroValid = gyroValid;
this.pressure = pressure;
this.pressureValid = pressureValid;
this.temperature = temperature;
this.temperatureValid = temperatureValid;
}
}
The Java C Mappings that are required:
My Java Library to map:
void TracehandleLocationEvent(TCLocationEvent tcLocationEvent);
void TracehandleManualLocationEvent(TCManualLocationEvent tcManualLocationEvent);
void TracehandleManualHeadingEvent(TCManualHeadingEvent tcManualHeadingEvent);
void TracehandleManualInitialLocation(TCLocationEvent initialLocationEvent);
void TraceHandleImuEvent(TCIMUEvent tcimuEvent, int Status, double userHeadingDeg, float rotationMode);
void TraceGetResult(Double uptime, Pointer traceResult_out);
-------- These map retrospectively to C:---------
void TraceHandleLocationEvent (const Trace_locationSample_t *locationSample)
void TraceHandleManualLocationEvent(const Trace_manualLocationSample_t
*manualLocationSample)
void TraceHandleManualHeadingEvent(const Trace_manualHeadingSample_t
*manualHeadingSample)
void TraceHandleLocationEvent (const Trace_locationSample_t *locationSample)
void TraceHandleImuEvent(Trace_imuDataSample_t *imuDataSample, int *status,
double *userHeadingDeg, StrapdownStreaming_RotationMode *currentRotateMode)
void TraceGetResult(double time, Trace_Result_t *TraceResult)
The new Mappings look like this, the structures for the objects are all the same format as above in the original question:
void TracehandleLocationEvent(TCLocationEvent tcLocationEvent);
void TracehandleManualLocationEvent(TCManualLocationEvent tcManualLocationEvent);
void TracehandleManualHeadingEvent(TCManualHeadingEvent tcManualHeadingEvent);
void TracehandleManualInitialLocation(TCLocationEvent initialLocationEvent);
void TraceGetResult(DoubleByReference uptime, TCResult traceResult_out);
void TraceHandleImuEvent(TCIMUEvent tcimuEvent, IntByReference status, DoubleByReference heading, FloatByReference rotationMode);
The error being thrown now in relation to the empty constructors in my Structure objects:
java.lang.Error: Structure.getFieldOrder() on class com.dataTypes.TCLocationEvent returns names ([altitude, coordinate, horizontalAccuracy, timestamp, verticalAccuracy]) which do not match declared field names ([])
at com.sun.jna.Structure.getFields(Structure.java:1089)
at com.sun.jna.Structure.deriveLayout(Structure.java:1232)
at com.sun.jna.Structure.calculateSize(Structure.java:1159)
at com.sun.jna.Structure.calculateSize(Structure.java:1111)
at com.sun.jna.Structure.allocateMemory(Structure.java:414)
at com.sun.jna.Structure.<init>(Structure.java:205)
at com.sun.jna.Structure.<init>(Structure.java:193)
at com.sun.jna.Structure.<init>(Structure.java:180)
at com.sun.jna.Structure.<init>(Structure.java:172)
at com.dataTypes.TCLocationEvent.<init>(TCLocationEvent.java:30)
at com.locationGetter.LocationService.<clinit>(LocationService.java:39)
SIGSEGV errors with JNA mappings are frequently caused by accessing native memory you don't own. Problems vary, but the first place to look is your structure type mappings and method/function argument mappings.
As one specific example (there may be more), your code includes this mapping:
void TraceHandleImuEvent(TCIMUEvent tcimuEvent, int Status,
double userHeadingDeg, float rotationMode);
However, the native mapping does not expect an int, double, and float here. It expects pointers:
void TraceHandleImuEvent(Trace_imuDataSample_t *imuDataSample, int *status,
double *userHeadingDeg, StrapdownStreaming_RotationMode *currentRotateMode)
(Structures like TCIMUEvent are automatically mapped to their pointers when passed as arguments, so that one's okay.)
What is happening is that you are passing an int for status (e.g., 8) but the native code is thinking "There's an integer stored at memory location 0x8." You don't own that memory, and thus the error.
IntByReference would be the correct type mapping here, and for many of those function arguments.
This question already has answers here:
What is a NullPointerException, and how do I fix it?
(12 answers)
Closed 2 years ago.
I get user current location by using override method
public void onSuccess(LocationEngineResult result) {
location = Point.fromLngLat(result.getLastLocation().getLongitude(),result.getLastLocation().getLatitude());
}
but I don't know how to replace the latitude and longitude on variable
private final Point ROUTE_ORIGIN=Point.fromLngLat(location.longitude(),location.latitude());
with the location i get from public void onSuccess(LocationEngineResult result) is there any solution for this?
The app crashed with error
Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'double com.mapbox.geojson.Point.longitude()' on a null object reference
Can anyone give me some idea or solution? I tried to find sources but still can't solve it.
public class ArActivity extends BaseActivity implements RouteListener, ProgressChangeListener, OffRouteListener {
private static final String TAG = ArActivity.class.getSimpleName();
// Handles navigation.
private MapboxNavigation mapboxNavigation;
// Fetches route from points.
private RouteFetcher routeFetcher;
private RouteProgress lastRouteProgress;
private PermissionsManager permissionsManager;
private LocationEngine locationEngine;
private LocationEngineCallback<LocationEngineResult> locationCallback;
public Point location;
private boolean visionManagerWasInit = false;
private boolean navigationWasStarted = false;
TextView tvlocation;
// This dummy points will be used to build route. For real world test this needs to be changed to real values for
// source and target location
private final Point ROUTE_ORIGIN=Point.fromLngLat(location.longitude(),location.latitude());
private final Point ROUTE_DESTINATION = Point.fromLngLat(101.769116, 2.923220);
#Override
protected void initViews() {
setContentView(R.layout.activity_ar_navigation);
tvlocation = findViewById(R.id.location);
}
#Override
protected void onPermissionsGranted() {
startVisionManager();
startNavigation();
}
#Override
protected void onStart() {
super.onStart();
startVisionManager();
startNavigation();
}
#Override
protected void onStop() {
super.onStop();
stopVisionManager();
stopNavigation();
}
private void startVisionManager() {
if (allPermissionsGranted() && !visionManagerWasInit) {
// Create and start VisionManager.
VisionManager.create();
VisionManager.setModelPerformanceConfig(new Merged(new On(ModelPerformanceMode.DYNAMIC, ModelPerformanceRate.LOW)));
VisionManager.start();
VisionManager.setVisionEventsListener(new VisionEventsListener() {
#Override
public void onAuthorizationStatusUpdated(#NotNull AuthorizationStatus authorizationStatus) {
}
#Override
public void onFrameSegmentationUpdated(#NotNull FrameSegmentation frameSegmentation) {
}
#Override
public void onFrameDetectionsUpdated(#NotNull FrameDetections frameDetections) {
}
#Override
public void onFrameSignClassificationsUpdated(#NotNull FrameSignClassifications frameSignClassifications) {
}
#Override
public void onRoadDescriptionUpdated(#NotNull RoadDescription roadDescription) {
}
#Override
public void onWorldDescriptionUpdated(#NotNull WorldDescription worldDescription) {
}
#Override
public void onVehicleStateUpdated(#NotNull VehicleState vehicleState) {
}
#Override
public void onCameraUpdated(#NotNull Camera camera) {
}
#Override
public void onCountryUpdated(#NotNull Country country) {
}
#Override
public void onUpdateCompleted() {
}
});
VisionArView visionArView = findViewById(R.id.mapbox_ar_view);
// Create VisionArManager.
VisionArManager.create(VisionManager.INSTANCE);
visionArView.setArManager(VisionArManager.INSTANCE);
visionArView.setFenceVisible(true);
visionManagerWasInit = true;
}
}
private void stopVisionManager() {
if (visionManagerWasInit) {
VisionArManager.destroy();
VisionManager.stop();
VisionManager.destroy();
visionManagerWasInit = false;
}
}
private void startNavigation() {
if (allPermissionsGranted() && !navigationWasStarted) {
// Initialize navigation with your Mapbox access token.
mapboxNavigation = new MapboxNavigation(
this,
getString(R.string.mapbox_access_token),
MapboxNavigationOptions.builder().build()
);
// Initialize route fetcher with your Mapbox access token.
routeFetcher = new RouteFetcher(this, getString(R.string.mapbox_access_token));
routeFetcher.addRouteListener(this);
locationEngine = LocationEngineProvider.getBestLocationEngine(this);
LocationEngineRequest arLocationEngineRequest = new LocationEngineRequest.Builder(0)
.setPriority(LocationEngineRequest.PRIORITY_HIGH_ACCURACY)
.setFastestInterval(1000)
.build();
locationCallback = new LocationEngineCallback<LocationEngineResult> () {
#Override
public void onSuccess(LocationEngineResult result) {
location = Point.fromLngLat(result.getLastLocation().getLongitude(),result.getLastLocation().getLatitude());
}
#Override
public void onFailure(#NonNull Exception exception) {
}
};
try {
locationEngine.requestLocationUpdates(arLocationEngineRequest, locationCallback, Looper.getMainLooper());
} catch (SecurityException se) {
VisionLogger.Companion.e(TAG, se.toString());
}
initDirectionsRoute();
// Route need to be reestablished if off route happens.
mapboxNavigation.addOffRouteListener(this);
mapboxNavigation.addProgressChangeListener(this);
navigationWasStarted = true;
}
}
private void stopNavigation() {
if (navigationWasStarted) {
locationEngine.removeLocationUpdates(locationCallback);
mapboxNavigation.removeProgressChangeListener(this);
mapboxNavigation.removeOffRouteListener(this);
mapboxNavigation.stopNavigation();
navigationWasStarted = false;
}
}
private void initDirectionsRoute() {
// Get route from predefined points.
NavigationRoute.builder(this)
.accessToken(getString(R.string.mapbox_access_token))
.origin(ROUTE_ORIGIN)
.destination(ROUTE_DESTINATION)
.build()
.getRoute(new Callback<DirectionsResponse>() {
#Override
public void onResponse(Call<DirectionsResponse> call, Response<DirectionsResponse> response) {
if (response.body() == null || response.body().routes().isEmpty()) {
return;
}
// Start navigation session with retrieved route.
DirectionsRoute route = response.body().routes().get(0);
mapboxNavigation.startNavigation(route);
// Set route progress.
VisionArManager.setRoute(new Route(
getRoutePoints(route),
route.duration().floatValue(),
"",
""
));
}
#Override
public void onFailure(Call<DirectionsResponse> call, Throwable t) {
}
});
}
#Override
public void onErrorReceived(Throwable throwable) {
if (throwable != null) {
throwable.printStackTrace();
}
mapboxNavigation.stopNavigation();
Toast.makeText(this, "Can not calculate the route requested", Toast.LENGTH_SHORT).show();
}
#Override
public void onResponseReceived(#NotNull DirectionsResponse response, RouteProgress routeProgress) {
mapboxNavigation.stopNavigation();
if (response.routes().isEmpty()) {
Toast.makeText(this, "Can not calculate the route requested", Toast.LENGTH_SHORT).show();
} else {
DirectionsRoute route = response.routes().get(0);
mapboxNavigation.startNavigation(route);
// Set route progress.
VisionArManager.setRoute(new Route(
getRoutePoints(route),
(float) routeProgress.durationRemaining(),
"",
""
));
}
}
#Override
public void onProgressChange(Location location, RouteProgress routeProgress) {
lastRouteProgress = routeProgress;
}
#Override
public void userOffRoute(Location location) {
routeFetcher.findRouteFromRouteProgress(location, lastRouteProgress);
}
private RoutePoint[] getRoutePoints(#NotNull DirectionsRoute route) {
ArrayList<RoutePoint> routePoints = new ArrayList<>();
List<RouteLeg> legs = route.legs();
if (legs != null) {
for (RouteLeg leg : legs) {
List<LegStep> steps = leg.steps();
if (steps != null) {
for (LegStep step : steps) {
RoutePoint point = new RoutePoint((new GeoCoordinate(
step.maneuver().location().latitude(),
step.maneuver().location().longitude()
)), mapToManeuverType(step.maneuver().type()));
routePoints.add(point);
List<Point> geometryPoints = buildStepPointsFromGeometry(step.geometry());
for (Point geometryPoint : geometryPoints) {
point = new RoutePoint((new GeoCoordinate(
geometryPoint.latitude(),
geometryPoint.longitude()
)), ManeuverType.None);
routePoints.add(point);
}
}
}
}
}
return routePoints.toArray(new RoutePoint[0]);
}
private List<Point> buildStepPointsFromGeometry(String geometry) {
return PolylineUtils.decode(geometry, Constants.PRECISION_6);
}
private ManeuverType mapToManeuverType(#Nullable String maneuver) {
if (maneuver == null) {
return ManeuverType.None;
}
switch (maneuver) {
case "turn":
return ManeuverType.Turn;
case "depart":
return ManeuverType.Depart;
case "arrive":
return ManeuverType.Arrive;
case "merge":
return ManeuverType.Merge;
case "on ramp":
return ManeuverType.OnRamp;
case "off ramp":
return ManeuverType.OffRamp;
case "fork":
return ManeuverType.Fork;
case "roundabout":
return ManeuverType.Roundabout;
case "exit roundabout":
return ManeuverType.RoundaboutExit;
case "end of road":
return ManeuverType.EndOfRoad;
case "new name":
return ManeuverType.NewName;
case "continue":
return ManeuverType.Continue;
case "rotary":
return ManeuverType.Rotary;
case "roundabout turn":
return ManeuverType.RoundaboutTurn;
case "notification":
return ManeuverType.Notification;
case "exit rotary":
return ManeuverType.RotaryExit;
default:
return ManeuverType.None;
}
}
At the point of instantiating this line (i.e. when the class loads):
private final Point ROUTE_ORIGIN=Point.fromLngLat(location.longitude(),location.latitude());
The location variable you are using is set to nothing:
public Point location;
Aka, it is null and you are getting a NullPointerException.
You should either not try to use the location object until it is instantiated, setting your routeOrigin later on. Or change the ROUTE_ORIGIN to use a static location, the same way you have for ROUTE_DESTINATION.
I am trying to get the current latitude and longitude using an example i found on the following link: http://gabesechansoftware.com/location-tracking/
There are two classes :The first class:
package com.example.marinamapseg;
import android.content.Context;
import android.location.Location;
import android.location.LocationManager;
public class FallbackLocationTracker implements LocationTracker, LocationTracker.LocationUpdateListener {
private boolean isRunning;
private ProviderLocationTracker gps;
private ProviderLocationTracker net;
private LocationUpdateListener listener;
Location lastLoc;
long lastTime;
public FallbackLocationTracker(Context context) {
gps = new ProviderLocationTracker(context, ProviderLocationTracker.ProviderType.GPS);
net = new ProviderLocationTracker(context, ProviderLocationTracker.ProviderType.NETWORK);
}
public void start(){
if(isRunning){
//Already running, do nothing
return;
}
//Start both
gps.start(this);
net.start(this);
isRunning = true;
}
public void start(LocationUpdateListener update) {
start();
listener = update;
}
public void stop(){
if(isRunning){
gps.stop();
net.stop();
isRunning = false;
listener = null;
}
}
public boolean hasLocation(){
//If either has a location, use it
return gps.hasLocation() || net.hasLocation();
}
public boolean hasPossiblyStaleLocation(){
//If either has a location, use it
return gps.hasPossiblyStaleLocation() || net.hasPossiblyStaleLocation();
}
public Location getLocation(){
Location ret = gps.getLocation();
if(ret == null){
ret = net.getLocation();
}
return ret;
}
public Location getPossiblyStaleLocation(){
Location ret = gps.getPossiblyStaleLocation();
if(ret == null){
ret = net.getPossiblyStaleLocation();
}
return ret;
}
public void onUpdate(Location oldLoc, long oldTime, Location newLoc, long newTime) {
boolean update = false;
//We should update only if there is no last location, the provider is the same, or the provider is more accurate, or the old location is stale
if(lastLoc == null){
update = true;
}
else if(lastLoc != null && lastLoc.getProvider().equals(newLoc.getProvider())){
update = true;
}
else if(newLoc.getProvider().equals(LocationManager.GPS_PROVIDER)){
update = true;
}
else if (newTime - lastTime > 5 * 60 * 1000){
update = true;
}
if(update){
lastLoc = newLoc;
lastTime = newTime;
if(listener != null){
listener.onUpdate(lastLoc, lastTime, newLoc, newTime);
}
}
}
}
The second class:
package com.example.marinamapseg;
import android.content.Context;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Bundle;
public class ProviderLocationTracker implements LocationListener, LocationTracker {
// The minimum distance to change Updates in meters
private static final long MIN_UPDATE_DISTANCE = 0;
// The minimum time between updates in milliseconds
private static final long MIN_UPDATE_TIME = 0;
private LocationManager lm;
public enum ProviderType{
NETWORK,
GPS
};
private String provider;
private Location lastLocation;
private long lastTime;
private boolean isRunning;
private LocationUpdateListener listener;
public ProviderLocationTracker(Context context, ProviderType type) {
lm = (LocationManager)context.getSystemService(Context.LOCATION_SERVICE);
if(type == ProviderType.NETWORK){
provider = LocationManager.NETWORK_PROVIDER;
}
else{
provider = LocationManager.GPS_PROVIDER;
}
}
public void start(){
if(isRunning){
//Already running, do nothing
return;
}
//The provider is on, so start getting updates. Update current location
isRunning = true;
lm.requestLocationUpdates(provider, MIN_UPDATE_TIME, MIN_UPDATE_DISTANCE,this);
lastLocation = null;
lastTime = 0;
//lm.requestLocationUpdates(provider, MIN_UPDATE_TIME, MIN_UPDATE_DISTANCE,this);
//return;
}
public void start(LocationUpdateListener update) {
start();
listener = update;
}
public void stop(){
if(isRunning){
lm.removeUpdates(this);
isRunning = false;
listener = null;
}
}
public boolean hasLocation(){
if(lastLocation == null){
return false;
}
if(System.currentTimeMillis() - lastTime > 5 * MIN_UPDATE_TIME){
return false; //stale
}
return true;
}
public boolean hasPossiblyStaleLocation(){
if(lastLocation != null){
return true;
}
return lm.getLastKnownLocation(provider)!= null;
}
public Location getLocation(){
if(lastLocation == null){
return null;
}
if(System.currentTimeMillis() - lastTime > 5 * MIN_UPDATE_TIME){
return null; //stale
}
return lastLocation;
}
public Location getPossiblyStaleLocation(){
if(lastLocation != null){
return lastLocation;
}
return lm.getLastKnownLocation(provider);
}
public void onLocationChanged(Location newLoc) {
long now = System.currentTimeMillis();
if(listener != null){
listener.onUpdate(lastLocation, lastTime, newLoc, now);
}
lastLocation = newLoc;
lastTime = now;
}
public void onProviderDisabled(String arg0) {
}
public void onProviderEnabled(String arg0) {
}
public void onStatusChanged(String arg0, int arg1, Bundle arg2) {
}
}
What i tried doing was to create an object of the first class and check whether the location can be found as follows:
fobj=new FallbackLocationTracker(MainActivity.this);
fobj.start();
if(fobj.hasLocation())
{
Location locobj=fobj.getLocation();
current_latitude=locobj.getLatitude();
current_longitude=locobj.getLongitude();
Toast.makeText(getApplicationContext(),current_latitude+" "+current_longitude,Toast.LENGTH_LONG).show();
placemarkersonmap();
}
The issue is as follows:
The haslocation() method will return false as the lastlocation object is null.But the lastlocation object gets a value only in the onlocationchanged method.So how do i ensure that the onlocationchanged method runs before i call my haslocation method?
So how do i ensure that the onlocationchanged method runs before i call my haslocation method?
onLocationChanged() may never be called. Just because you want a location does not mean that the user has to allow you to get one (e.g., user has both providers disabled). And, just because you want a location does not mean that it is physically possible to get one (e.g., user has GPS disabled and has airplane mode enabled). And, just because you want a location does not mean one will be ready yet.
Hence, your application already needs to deal with not having a location, so add that logic to your app.
You are certainly welcome to also do something more event-driven, starting up some application logic from onLocationChanged(), once you have demonstrated you are at least temporarily able to get location fixes.
I have tried using androidhive's standard tutorial for finding location,but it fails at certain times.So i found another tutorial on this link:
http://gabesechansoftware.com/location-tracking/
He uses two classes which implement an interface:
The first class:
package com.example.marinamapseg;
import android.content.Context;
import android.location.Location;
import android.location.LocationManager;
public class FallbackLocationTracker implements LocationTracker, LocationTracker.LocationUpdateListener {
private boolean isRunning;
private ProviderLocationTracker gps;
private ProviderLocationTracker net;
private LocationUpdateListener listener;
Location lastLoc;
long lastTime;
public FallbackLocationTracker(Context context) {
gps = new ProviderLocationTracker(context, ProviderLocationTracker.ProviderType.GPS);
net = new ProviderLocationTracker(context, ProviderLocationTracker.ProviderType.NETWORK);
}
public void start(){
if(isRunning){
//Already running, do nothing
return;
}
//Start both
gps.start(this);
net.start(this);
isRunning = true;
}
public void start(LocationUpdateListener update) {
start();
listener = update;
}
public void stop(){
if(isRunning){
gps.stop();
net.stop();
isRunning = false;
listener = null;
}
}
public boolean hasLocation(){
//If either has a location, use it
return gps.hasLocation() || net.hasLocation();
}
public boolean hasPossiblyStaleLocation(){
//If either has a location, use it
return gps.hasPossiblyStaleLocation() || net.hasPossiblyStaleLocation();
}
public Location getLocation(){
Location ret = gps.getLocation();
if(ret == null){
ret = net.getLocation();
}
return ret;
}
public Location getPossiblyStaleLocation(){
Location ret = gps.getPossiblyStaleLocation();
if(ret == null){
ret = net.getPossiblyStaleLocation();
}
return ret;
}
public void onUpdate(Location oldLoc, long oldTime, Location newLoc, long newTime) {
boolean update = false;
//We should update only if there is no last location, the provider is the same, or the provider is more accurate, or the old location is stale
if(lastLoc == null){
update = true;
}
else if(lastLoc != null && lastLoc.getProvider().equals(newLoc.getProvider())){
update = true;
}
else if(newLoc.getProvider().equals(LocationManager.GPS_PROVIDER)){
update = true;
}
else if (newTime - lastTime > 5 * 60 * 1000){
update = true;
}
if(update){
lastLoc = newLoc;
lastTime = newTime;
if(listener != null){
listener.onUpdate(lastLoc, lastTime, newLoc, newTime);
}
}
}
}
The second class:
package com.example.marinamapseg;
import android.content.Context;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Bundle;
public class ProviderLocationTracker implements LocationListener, LocationTracker {
// The minimum distance to change Updates in meters
private static final long MIN_UPDATE_DISTANCE = 0;
// The minimum time between updates in milliseconds
private static final long MIN_UPDATE_TIME = 0;
private LocationManager lm;
public enum ProviderType{
NETWORK,
GPS
};
private String provider;
private Location lastLocation;
private long lastTime;
private boolean isRunning;
private LocationUpdateListener listener;
public ProviderLocationTracker(Context context, ProviderType type) {
lm = (LocationManager)context.getSystemService(Context.LOCATION_SERVICE);
if(type == ProviderType.NETWORK){
provider = LocationManager.NETWORK_PROVIDER;
}
else{
provider = LocationManager.GPS_PROVIDER;
}
}
public void start(){
if(isRunning){
//Already running, do nothing
return;
}
//The provider is on, so start getting updates. Update current location
isRunning = true;
lm.requestLocationUpdates(provider, MIN_UPDATE_TIME, MIN_UPDATE_DISTANCE, this);
lastLocation = null;
lastTime = 0;
return;
}
public void start(LocationUpdateListener update) {
start();
listener = update;
}
public void stop(){
if(isRunning){
lm.removeUpdates(this);
isRunning = false;
listener = null;
}
}
public boolean hasLocation(){
if(lastLocation == null){
return false;
}
if(System.currentTimeMillis() - lastTime > 5 * MIN_UPDATE_TIME){
return false; //stale
}
return true;
}
public boolean hasPossiblyStaleLocation(){
if(lastLocation != null){
return true;
}
return lm.getLastKnownLocation(provider)!= null;
}
public Location getLocation(){
if(lastLocation == null){
return null;
}
if(System.currentTimeMillis() - lastTime > 5 * MIN_UPDATE_TIME){
return null; //stale
}
return lastLocation;
}
public Location getPossiblyStaleLocation(){
if(lastLocation != null){
return lastLocation;
}
return lm.getLastKnownLocation(provider);
}
public void onLocationChanged(Location newLoc) {
long now = System.currentTimeMillis();
if(listener != null){
listener.onUpdate(lastLocation, lastTime, newLoc, now);
}
lastLocation = newLoc;
lastTime = now;
}
public void onProviderDisabled(String arg0) {
}
public void onProviderEnabled(String arg0) {
}
public void onStatusChanged(String arg0, int arg1, Bundle arg2) {
}
}
But the issue is that he has not mentioned as how to use the following two classes in the android app.So i tried the following:
FallbackLocationTracker fobj;
fobj=new FallbackLocationTracker(MainActivity.this);
fobj.start();
if(fobj.hasLocation())
{
Location locobj=fobj.getLocation();
current_latitude=locobj.getLatitude();
current_longitude=locobj.getLongitude();
Toast.makeText(getApplicationContext(),current_latitude+" "+current_longitude,Toast.LENGTH_LONG).show();
placemarkersonmap();
}
When i debug the code the hasLocation method returns false, Because the onLocationChanged method in the first class is getting called only after the haslocation method is called.So the lastlocation object will be null and false would be returned.
But why doesnt onlocationchanged get called as soon as the following line runs:
lm.requestLocationUpdates(provider, MIN_UPDATE_TIME, MIN_UPDATE_DISTANCE, this);
Or is there any way somenone can tell me as how to use the code.Please help!!
onLocationChanged is a callback, meaning that it is event driven and does not run until the device detects a change of location. If you are taking location only from GPS, then it can take several minutes before you get a fix. If you are indoors without a clear view of the sky, then it may never run.
You may add the following in your actitvity's onCreate method:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
textViewHeading = (TextView) this.findViewById(R.id.text_heading);
textViewLong = (TextView) this.findViewById(R.id.text_long);
textViewLat = (TextView) this.findViewById(R.id.text_lat);
textViewHeight = (TextView) this.findViewById(R.id.text_height);
textViewAccuracy = (TextView) this.findViewById(R.id.text_accuracy);
counter = (long) 0;
gps = new ProviderLocationTracker(this,
ProviderLocationTracker.ProviderType.GPS);
listener = new LocationUpdateListener() {
#Override
public void onUpdate(Location oldLoc, long oldTime, Location newLoc,
long newTime) {
// TODO Auto-generated method stub
counter = counter + (long) 1;
if (gps.hasLocation()) {
text1="GPS has location ( " + counter.toString() + " )";
} else {
text1="GPS has no location ( " + counter.toString() + " )";
}
if (gps.hasPossiblyStaleLocation()) {
text1 = text1 + " plus stale location";
}
Double longitude = newLoc.getLongitude();
Double latitude = newLoc.getLatitude();
Double height = newLoc.getAltitude();
Float accuracy = newLoc.getAccuracy();
text2 = "Longitude = " + longitude.toString();
text3 = "Latitude = " + latitude.toString();
text4 = "Altitude = " + height.toString();
text5 = "Accuracy = " + accuracy.toString();
textViewHeading.setText(text1);
textViewLong.setText(text2);
textViewLat.setText(text3);
textViewHeight.setText(text4);
textViewAccuracy.setText(text5);
}
};
gps.start(listener);
} // end method onCreate
It seems that this post already has an answer that shows how to use the ProviderLocationTracker. I am putting in my answer just to show how easy it get's with the FallbackLocationTracker.
I do not remember making any significant changes to the FallbackLocationTracker so I am not going to post the whole code.
public class MainActivity extends AppCompatActivity {
private FallbackLocationTracker tracker;
private Location location;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
tracker = new FallbackLocationTracker(MainActivity.this);
}
#Override
protected void onResume() {
super.onResume();
// Check for permission to access location and start location
// tracking if permissions are granted and location services
// are enabled
if (locationPermissionGranted && locationServicesEnabled) {
startLocationUpdates();
} else {
// Handle accordingly
}
}
#Override
protected void onPause() {
super.onPause();
stopLocationUpdates();
}
private void startLocationUpdates() {
tracker.start(new LocationTracker.LocationUpdateListener() {
#Override
public void onUpdate(Location oldLocation, long oldTime,
Location newLocation, long newTime) {
// You will receive updated changes to your location here
location = newLocation;
}
});
}
private void stopLocationUpdates() {
tracker.stop();
}
}
That's it.
public class NativeGeolocation extends Plugin {
public long maximumAge = 1000 * 30; // ms
public long timeout = 1000 * 30; // ms
public Location lastPosition = null;
public static final String ACTION_GETCURRENTPOSITION="getCurrentPosition";
protected String callbackId = null;
#Override
public PluginResult execute(String action, JSONArray data, String callbackId)
{
JSONObject options = data.optJSONObject(0);
Log.i("Myactivity","options : "+options);
this.timeout = timeout;
this.callbackId = callbackId;
Log.i("Myactivity","callbackId : "+this.callbackId);
PluginResult result = new PluginResult(Status.NO_RESULT, callbackId);
result.setKeepCallback(true);
final LocationManager locationManager = (LocationManager) ctx.getSystemService(Context.LOCATION_SERVICE);
Criteria criteria = new Criteria();
String provider = locationManager.getBestProvider(criteria,false);
if (ACTION_GETCURRENTPOSITION.equals(action)) {
Log.i("Myactivity","inside getcurrentposition action");
Location lastKnownLocation = locationManager.getLastKnownLocation(provider);
lastPosition = lastKnownLocation;
Log.i("Myactivity","last location "+lastKnownLocation);
if ((null != lastKnownLocation) && lastKnownLocation.getTime() + this.maximumAge > new Date().getTime()) {
Log.i("Myactivity","inside b4 gotLocation");
gotLocation(lastKnownLocation);
} else {
ctx.runOnUiThread(new RunnableLocationListener(this, callbackId, locationManager, provider));
}
} else {
error(new PluginResult(Status.INVALID_ACTION), callbackId);
}
return result;
}
public void gotLocation (Location location) {
Log.i("Myactivity","inside gotLocation");
try {
Log.i("Myactivity","inside try");
JSONObject geoposition = new JSONObject();
JSONObject coords = new JSONObject();
coords.put("latitude", location.getLatitude());
coords.put("longitude", location.getLongitude());
coords.put("altitude", location.getAltitude());
coords.put("accuracy", location.getAccuracy());
coords.put("altitudeAccuracy", null);
coords.put("heading", null);
coords.put("speed", location.getSpeed());
geoposition.put("coords", coords);
geoposition.put("timestamp", location.getTime());
geoposition.put("provider", location.getProvider());
geoposition.put("lastPos", lastPosition);
success(new PluginResult(Status.OK, geoposition), callbackId);
} catch (JSONException jsonEx) {
error(new PluginResult(Status.JSON_EXCEPTION), callbackId);
}
}
protected String getBestProvider (LocationManager locationManager) {
String provider = LocationManager.PASSIVE_PROVIDER;
if (locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER)) {
provider = LocationManager.GPS_PROVIDER;
}
else if (locationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER)) {
provider = LocationManager.NETWORK_PROVIDER;
}
return provider;
}
class RunnableLocationListener extends Thread {
protected final NativeGeolocation plugin;
protected final LocationManager locationManager;
protected final String provider;
protected final String callbackId;
public Boolean ended = null;
public RunnableLocationListener (NativeGeolocation plugin, String callbackId, LocationManager locationManager, String provider) {
Log.i("Myactivity","inside runnabl");
this.plugin = plugin;
this.locationManager = locationManager;
this.provider = provider;
this.callbackId = callbackId;
}
public void run () {
ended = false;
PluginResult result = null;
final LocationListener locationListener = new LocationListener() {
public void onLocationChanged (Location location) {
Log.i("Myactivity","calling getlocation again1");
if ( false == ended ) {
Log.i("Myactivity","calling getlocation again2");
plugin.gotLocation(location);
locationManager.removeUpdates(this);
}
}
public void onStatusChanged (String provider, int status, Bundle extras) {
Log.i("Myactivity","inside onStatus Changed");
}
public void onProviderEnabled(String provider) {
Log.i("Myactivity","inside onProvider Enabled");
}
public void onProviderDisabled(String provider) {
Log.i("Myactivity","inside onProvider Disabled");
}
};
locationManager.requestLocationUpdates(provider,1, 10, locationListener);//1 minutes and 10 meters
Thread timeouter = new Thread() {
public void run () {
try {
Thread.sleep(plugin.timeout);
ended = true;
locationManager.removeUpdates(locationListener);
plugin.error(new PluginResult(Status.ERROR, "timeout"), callbackId);
} catch (java.lang.InterruptedException ex) {
error(new PluginResult(Status.JSON_EXCEPTION), callbackId);
}
}
};
timeouter.start();
}
}
}
This is java plugin n I am calling through phonegap .
But It gives location only if internet is available. I need to get location only using gps hardware and not through internet . Any help??
I refferred some of the stackoverflow questions related to this. So i got know that GPS will not work inside the building . Ok , but in my case it is not working outside also. Until and unless it is not getting last known location it is not working . Once it has last location some how then it starts working . Any help ??
EDIT : According to this link Android - Trouble in getting location coordinates by only using GPS provider , i can use libwlocate . But how to use that as phonegap plugin ?? Any help ??
Any help is greatly appreciated.
EDIT: How about if i put some dummy lastKnownLocation for the first time. Then it will requestForNew one right??
You can request "ONLY GPS" like this...
LocationProvider gpsProvider = locationManager.getProvider(LocationManager.GPS_PROVIDER);
if(gpsProvider != null){
locationManager.requestLocationUpdates(gpsProvider.getName(), 0, 0, this);
}
Boolean isGPSEnabled = locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER);
Location lastLocation = null, gpsLocation = null;
if (isGPSEnabled)
gpsLocation = locationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER);