Share LocationListener with another Activity Android - java

I am trying to build an application that needs to use the GPS API's on android. I have two activities that need to use the gps.
The first one is just an activity that has a LocationListener and when it gets the location it gets weather for that location from a web API and saves it somewhere.
After doing that, it starts an intent that starts another activity. The other activity on other hand, needs to get speed from gps and update in realtime.
Now my question is, is it possible to use the same LocationListener from another activity on the second activity without having to reconnect to gps and do all that stuff again? Or is there any other alternatives than reconnecting again on the second activity as well?
Any help is appreciated. Thanks.

#KSubedi -- create a class for location listener & use objects of class in both your activity.
You can create class like below or you can edit below as per you requirement or create new one.
import java.util.Timer;
import java.util.TimerTask;
import android.content.Context;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Bundle;
public abstract class MyLocation {
Timer timer1;
static LocationManager lm;
LocationResult locationResult;
boolean gps_enabled = false;
boolean network_enabled = false;
public boolean getLocation(Context context, LocationResult result)
{
//I use LocationResult callback class to pass location value from MyLocation to user code.
locationResult=result;
if(MyLocation.lm == null)
MyLocation.lm = (LocationManager) context.getSystemService(Context.LOCATION_SERVICE);
//exceptions will be thrown if provider is not permitted.
try
{
gps_enabled = MyLocation.lm.isProviderEnabled(LocationManager.GPS_PROVIDER);
}
catch(Exception ex)
{}
try
{
network_enabled = MyLocation.lm.isProviderEnabled(LocationManager.NETWORK_PROVIDER);
}
catch(Exception ex)
{}
//don't start listeners if no provider is enabled
if(!gps_enabled && !network_enabled)
return false;
if(gps_enabled)
MyLocation.lm.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, locationListenerGps);
if(network_enabled)
MyLocation.lm.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 0, 0, locationListenerNetwork);
timer1=new Timer();
// timer1.schedule(new GetLastLocation(), 20000);
timer1.scheduleAtFixedRate(new GetLastLocation(), 0,50000);
return true;
}
LocationListener locationListenerGps = new LocationListener() {
public void onLocationChanged(Location location) {
timer1.cancel();
locationResult.gotLocation(location);
MyLocation.lm.removeUpdates(this);
MyLocation.lm.removeUpdates(locationListenerNetwork);
}
public void onProviderDisabled(String provider) {}
public void onProviderEnabled(String provider) {}
public void onStatusChanged(String provider, int status, Bundle extras) {}
};
LocationListener locationListenerNetwork = new LocationListener() {
public void onLocationChanged(Location location) {
timer1.cancel();
locationResult.gotLocation(location);
MyLocation.lm.removeUpdates(this);
MyLocation.lm.removeUpdates(locationListenerGps);
}
public void onProviderDisabled(String provider) {}
public void onProviderEnabled(String provider) {}
public void onStatusChanged(String provider, int status, Bundle extras) {}
};
class GetLastLocation extends TimerTask {
#Override
public void run() {
// lm.removeUpdates(locationListenerGps);
// lm.removeUpdates(locationListenerNetwork);
Location net_loc=null, gps_loc=null;
if(gps_enabled)
gps_loc = MyLocation.lm.getLastKnownLocation(LocationManager.GPS_PROVIDER);
if(network_enabled)
net_loc = MyLocation.lm.getLastKnownLocation(LocationManager.NETWORK_PROVIDER);
//if there are both values use the latest one
if(gps_loc!=null && net_loc!=null){
if(gps_loc.getTime()>net_loc.getTime())
locationResult.gotLocation(gps_loc);
else
locationResult.gotLocation(net_loc);
return;
}
if(gps_loc!=null){
locationResult.gotLocation(gps_loc);
return;
}
if(net_loc!=null){
locationResult.gotLocation(net_loc);
return;
}
locationResult.gotLocation(null);
}
}
public void closeListeners(){
timer1.cancel();
lm.removeUpdates(locationListenerGps);
lm.removeUpdates(locationListenerNetwork);
}
public static abstract class LocationResult{
public abstract void gotLocation(Location location);
}
public abstract void locationClick() ;
}

For this purpose use Services to get locations instead of using two activites.

Related

Android gps provider work when emulated but not on mobile

I think I know the issue for why when running my code the gps tracking only works on emulated devices. It has something to do with the location listener being inside the onCreate() function. I just don't know how I would be able to edit my existing code so Locationlistener still works when placed outside of the onCreate() function.
I want to test the code on a mobile device because the getSpeed() function does not work when emulating.
Here is the code that fetches the location:
private LocationListener listener;
private LocationManager location;
private Float speedStr;
private Boolean boolSpeed;
#Nullable
#Override
public IBinder onBind(Intent intent) {
return null;
}
#SuppressLint("MissingPermission")
#Override
public void onCreate() { //Get coords and send to main activity. Also get speed.
listener = new LocationListener() {
#Override
public void onLocationChanged(Location location) {
Intent i = new Intent("location update");
i.putExtra("coords",location.getLatitude());
i.putExtra("coords2",location.getLongitude());
sendBroadcast(i);
Toast.makeText(GPS_Service.this,"reading",Toast.LENGTH_SHORT).show();
speedStr = location.getSpeed();
boolSpeed = location.hasSpeed();
Log.i("speed",speedStr.toString());
Log.i("speed",boolSpeed.toString());
}
#Override
public void onProviderDisabled(String s) {
Intent i = new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS);
i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(i);
}
};
location = (LocationManager) getApplicationContext().getSystemService(Context.LOCATION_SERVICE);
location.requestLocationUpdates(LocationManager.GPS_PROVIDER,3000,200,listener); //set min distance proper units
}
#SuppressLint("MissingPermission")
#Override
public void onDestroy() {
super.onDestroy();
if(location != null) {
location.removeUpdates(listener);
}
}
}

Update users location continuously without external Library

I am creating a Navigation application using mapbox. I am struggling with updating the users current location continuously. Currently I am using a class MyLocation
to get the users current location.
originLocation is defined as private Location
Not quite sure what to do. I have tried locationEngine.requestLocationUpdates(); which does not seem to work.
MyLocation class code: Got the code from Geolocation post
import java.util.Timer;
import java.util.TimerTask;
import android.content.Context;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Bundle;
public class MyLocation {
Timer timer1;
LocationManager lm;
LocationResult locationResult;
boolean gps_enabled=false;
boolean network_enabled=false;
public boolean getLocation(Context context, LocationResult result)
{
//I use LocationResult callback class to pass location value from MyLocation to user code.
locationResult=result;
if(lm==null)
lm = (LocationManager) context.getSystemService(Context.LOCATION_SERVICE);
//exceptions will be thrown if provider is not permitted.
try{gps_enabled=lm.isProviderEnabled(LocationManager.GPS_PROVIDER);}catch(Exception ex){}
try{network_enabled=lm.isProviderEnabled(LocationManager.NETWORK_PROVIDER);}catch(Exception ex){}
//don't start listeners if no provider is enabled
if(!gps_enabled && !network_enabled)
return false;
if(gps_enabled)
lm.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, locationListenerGps);
if(network_enabled)
lm.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 0, 0, locationListenerNetwork);
timer1=new Timer();
timer1.schedule(new GetLastLocation(), 20000);
return true;
}
LocationListener locationListenerGps = new LocationListener() {
public void onLocationChanged(Location location) {
timer1.cancel();
locationResult.gotLocation(location);
lm.removeUpdates(this);
lm.removeUpdates(locationListenerNetwork);
}
public void onProviderDisabled(String provider) {}
public void onProviderEnabled(String provider) {}
public void onStatusChanged(String provider, int status, Bundle extras) {}
};
LocationListener locationListenerNetwork = new LocationListener() {
public void onLocationChanged(Location location) {
timer1.cancel();
locationResult.gotLocation(location);
lm.removeUpdates(this);
lm.removeUpdates(locationListenerGps);
}
public void onProviderDisabled(String provider) {}
public void onProviderEnabled(String provider) {}
public void onStatusChanged(String provider, int status, Bundle extras) {}
};
class GetLastLocation extends TimerTask {
#Override
public void run() {
lm.removeUpdates(locationListenerGps);
lm.removeUpdates(locationListenerNetwork);
Location net_loc=null, gps_loc=null;
if(gps_enabled)
gps_loc=lm.getLastKnownLocation(LocationManager.GPS_PROVIDER);
if(network_enabled)
net_loc=lm.getLastKnownLocation(LocationManager.NETWORK_PROVIDER);
//if there are both values use the latest one
if(gps_loc!=null && net_loc!=null){
if(gps_loc.getTime()>net_loc.getTime())
locationResult.gotLocation(gps_loc);
else
locationResult.gotLocation(net_loc);
return;
}
if(gps_loc!=null){
locationResult.gotLocation(gps_loc);
return;
}
if(net_loc!=null){
locationResult.gotLocation(net_loc);
return;
}
locationResult.gotLocation(null);
}
}
public static abstract class LocationResult{
public abstract void gotLocation(Location location);
}
}
How I am using the class:
#SuppressWarnings("MissingPermission")
private void initializeLocationEngine() {
try{
locationEngine = new LocationEngineProvider(this).obtainBestLocationEngineAvailable();
locationEngine.setPriority(LocationEnginePriority.HIGH_ACCURACY);
locationEngine.activate();
locationEngine.addLocationEngineListener(this);
locationEngine.setInterval(0);
locationEngine.setFastestInterval(500);
MyLocation.LocationResult locationResult = new
MyLocation.LocationResult(){
#Override
public void gotLocation(Location location){
originLocation = location;
}
};
MyLocation myLocation = new MyLocation();
myLocation.getLocation(this, locationResult);
}catch (Exception e){
Log.d(TAG, "Error" + e);
}
}
OnLocationChanged method code:
#Override
public void onLocationChanged(Location location) {
try{
locationEngine = new LocationEngineProvider(this).obtainBestLocationEngineAvailable();
locationEngine.setPriority(LocationEnginePriority.HIGH_ACCURACY);
locationEngine.activate();
locationEngine.addLocationEngineListener(this);
locationEngine.setInterval(0);
locationEngine.setFastestInterval(500);
MyLocation.LocationResult locationResult = new MyLocation.LocationResult(){
#Override
public void gotLocation(Location location){
originLocation = location;
}
};
MyLocation myLocation = new MyLocation();
myLocation.getLocation(this, locationResult);
}catch (Exception e){
Log.d(TAG, "Error" + e);
Toast.makeText(Home.this,"Error initializeLocationEngine", Toast.LENGTH_SHORT).show();
}
}

When I try to get device location from my class I get error "Can't create handler inside thread that has not called Looper.prepare()

Here is my very simple class to get coordinates, it works if I launch from Activity, but when I try to get coordinates from service I get this error in constructor DeviceLocation
public class DeviceLocation implements LocationListener {
private Context mContext;
private LocationManager locationManager;
public DeviceLocation(Context context) {
mContext = context;
locationManager =
(LocationManager) mContext.getSystemService(Context.LOCATION_SERVICE);
try {
locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 1000 * 3, 0, this);
} catch (SecurityException e) {
e.printStackTrace();
}
}
#Override
public void onLocationChanged(Location location) {
}
#Override
public void onProviderDisabled(String provider) {
}
#Override
public void onProviderEnabled(String provider) {
}
#Override
public void onStatusChanged(String provider, int status, Bundle extras){
}
}
I solved the problem, I should have written this line
locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 1000 * 3, 0, this, Looper.getMainLooper());
instead of
locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 1000 * 3, 0, this);

onlocationchanged function never called-> PhoneGap

I have an application written in HTML5 and wrapped in PhoneGap.
I have a map on an application and I want to find a user's location by GPS.
I tried it the following way:
In JS I have a function that changes the position of the marker:
function GPS(lat, lon) {
alert('Now U move');
var CurrentPosition = new google.maps.LatLng(lat, lon);
markerMyLoc.setPosition(CurrentPosition);
}
In Java, I have functions that care on location and send the JS function:
public class MainActivity extends DroidGap {
private LocationManager locationManager;
private LocationListener locationListener;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
super.setIntegerProperty("splashscreen", R.drawable.splash);
super.loadUrl("file:///android_asset/www/XXX.html", 10000);
locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
locationListener = new GPSLocationListener();
locationManager.requestLocationUpdates(
LocationManager.GPS_PROVIDER,
0,
0,
locationListener);
}
}
GPSLocationListener class:
public class GPSLocationListener implements LocationListener
{
#Override
public void onLocationChanged(Location location) {
if (location != null) {
GPScls MyGPS= new GPScls();
MyGPS.GPS(location.getLatitude(),location.getLongitude());
}
}
#Override
public void onProviderDisabled(String provider) {
// TODO Auto-generated method stub
}
#Override
public void onProviderEnabled(String provider) {
// TODO Auto-generated method stub
}
#Override
public void onStatusChanged(String provider, int status, Bundle extras) {
// TODO Auto-generated method stub
}
}
GPScls class:
public class GPScls extends DroidGap {
public void GPS(double latitude,double longitude) {
super.loadUrl("javascript:GPS("+latitude+","+longitude+")");
}
}
the alert: alert('Now U move'); Not shown, can anyone help me solve this?
I realized that, I did not go enough to return an answer from GPS
Look at the following question:
Is the function onLocationChanged called every movement of Android device?

Android onLocationChanged and MainActivity class

I have the following code:
public class MyLocationListener implements LocationListener {
#Override
public void onLocationChanged(Location loc) {
// called when the listener is notified with a location update from the GPS
Log.d("Latitude", Double.toString(loc.getLatitude()));
Log.d("Longitude", Double.toString(loc.getLongitude()));
}
#Override
public void onProviderDisabled(String provider) {
// called when the GPS provider is turned off (user turning off the GPS on the phone)
}
#Override
public void onProviderEnabled(String provider) {
// called when the GPS provider is turned on (user turning on the GPS on the phone)
}
#Override
public void onStatusChanged(String provider, int status, Bundle extras) {
}
and in my MainActivity
LocationListener locationListener = new MyLocationListener();
LocationManager lm = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
lm.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, locationListener);
Now, all I want is to receive the current position of the device ONCE to the MainActivity class (get altitude and longitude variables to use later in the application).
A. how do I stop receiving the location after a single time? The function lm.removeUpdates(listener) can only be called in the MainActivity class.
B. basically the same. How do I connect between the MyLocationListener class and the MainActivity one?
Sorry, I'm a newbie to Android and Java development.
And thanks!
You may use the following sample code:
public class LocationGetter {
private final Context context;
private Location location = null;
private final Cordinate gotLocationLock = new Cordinate();
private final LocationResult locationResult = new LocationResult() {
#Override
public void gotLocation(Location location) {
synchronized (gotLocationLock) {
LocationGetter.this.location = location;
gotLocationLock.notifyAll();
Looper.myLooper().quit();
}
}
};
public LocationGetter(Context context) {
if (context == null)
throw new IllegalArgumentException("context == null");
this.context = context;
}
public void getLocation(int maxWaitingTime, int updateTimeout) {
try {
final int updateTimeoutPar = updateTimeout;
synchronized (gotLocationLock) {
new Thread() {
public void run() {
Looper.prepare();
LocationResolver locationResolver = new LocationResolver();
locationResolver.prepare();
locationResolver.getLocation(context, locationResult, updateTimeoutPar);
Looper.loop();
}
}.start();
gotLocationLock.wait(maxWaitingTime);
}
} catch (InterruptedException e1) {
e1.printStackTrace();
}
gteAddress ();
}
public double getLatitude() {
return location.getLatitude();
}
public double getLongitude() {
return location.getLongitude();
}
In your activity use:
_locationGetter=new LocationGetter(context);
_locationGetter.getLocation(200000000, 10000000);
_locationGetter.getLongitude();
_locationGetter.getLatitude();
You can also use LocationManager.removeUpdates after obtining the coordinates (and possibly checking if the coordinates are sufficient for your needs):
#Override
public void onLocationChanged(Location loc) {
// called when the listener is notified with a location update from the GPS
Log.d("Latitude", Double.toString(loc.getLatitude()));
Log.d("Longitude", Double.toString(loc.getLongitude()));
lm.removeUpdates(this);
}

Categories