A LocationSource is defined in Google Maps Android API v2.
It is used for googlemap as the location provider. By default, the location source is provided by the gps module on the phone.
But now I want to use a another Location source, the location data will be sent to android device periodically.
I have no idea how to implement this interface. Are there any example out there? Can anyone help me with it? The document did not say anything about it.
Here is a simple implementation of LocationSource interface. In my case I'm registering both GPS and Network location providers. As mentioned by #CommonsWare, implementation may very depending on your needs. I would suggest reading official documentation about Location service in order to better understand how to utilize your needs and save some battery power
public class CurrentLocationProvider implements LocationSource, LocationListener
{
private OnLocationChangedListener listener;
private LocationManager locationManager;
public CurrentLocationProvider(Context context)
{
locationManager = (LocationManager) context.getSystemService(Context.LOCATION_SERVICE);
}
#Override
public void activate(OnLocationChangedListener listener)
{
this.listener = listener;
LocationProvider gpsProvider = locationManager.getProvider(LocationManager.GPS_PROVIDER);
if(gpsProvider != null)
{
locationManager.requestLocationUpdates(gpsProvider.getName(), 0, 10, this);
}
LocationProvider networkProvider = locationManager.getProvider(LocationManager.NETWORK_PROVIDER);;
if(networkProvider != null) {
locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 1000 * 60 * 5, 0, this);
}
}
#Override
public void deactivate()
{
locationManager.removeUpdates(this);
}
#Override
public void onLocationChanged(Location location)
{
if(listener != null)
{
listener.onLocationChanged(location);
}
}
#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
}
}
And here is how I would use this class:
protected void setUpMap() {
//init routine
.......
this.map.setLocationSource(new CurrentLocationProvider(this));
.......
}
EDIT Please not that this solution is obsolete! You need to use FusedLocationProviderApi in conjunction with GoogleApiClient for tracking current location
Are there any example out there?
There is not much to the interface, and its implementation is very dependent upon your app.
This sample project implements the LocationSource interface on the main activity:
#Override
public void activate(OnLocationChangedListener listener) {
this.mapLocationListener=listener;
}
#Override
public void deactivate() {
this.mapLocationListener=null;
}
All I do is hold onto the OnLocationChangedListener that we are handed in activate(). Then, when you have a location fix that you wish to feed to the map, call onLocationChanged() on that listener, supplying a Location object (the same Location object you might get back from LocationManager).
Here is the solution using the FusedLocationProviderApi:
Android: Google Maps location with low battery usage
Related
when used GPS_PROVIDER the application work fine, but when used NETWORK_PROVIDER the application was stopped by force. Why? are my permissions not complete?? please help me by making my code working, thanx
public class My_location extends Activity implements LocationListener {
EditText ET1,ET2;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.my_location);
// Log.i("onCreate_My_location", "begin");
ET1=(EditText)this.findViewById(R.id.editText1);
ET2=(EditText)this.findViewById(R.id.editText2);
ET1.setText("1.0000");
ET2.setText("1.0000");
LocationManager LM1=(LocationManager) getSystemService(Context.LOCATION_SERVICE);
LM1.requestLocationUpdates(LocationManager.NETWORK_PROVIDER,0,1,this);
//Log.i("onCreate_my_location", "End");
}
#Override
public void onLocationChanged(Location L1) {
// TODO Auto-generated method stub
//Log.i("onLocationChanged",String.valueOf(L1.getLongitude()));
//Log.i("onLocationChanged",String.valueOf(L1.getLatitude()));
//Log.i("onLocationChanged",String.valueOf(L1.getAltitude()));
ET1.setText("C.0000");
ET2.setText("C.0000");
ET1.setText(String.valueOf(L1.getLongitude()));
ET2.setText(String.valueOf(L1.getLatitude()));
}
#Override
public void onProviderDisabled(String arg0) {
}
#Override
public void onProviderEnabled(String arg0) {
}
#Override
public void onStatusChanged(String arg0, int arg1, Bundle arg2) {
}
}
instead of using specific provider use best provider, which will give you more accuracy in your location
use code given below which will give you location by choosing best provider automatically :
LocationManager LM1=(LocationManager) getSystemService(Context.LOCATION_SERVICE);
Criteria criteria = new Criteria();
String provider=LM1.getBestProvider(criteria, true);
LM1.requestLocationUpdates(provider,0,1,this);
Edit:
for Your Code you Can Check network State before requestLocationUpdates
i think this can avoid the crash :
if(LM1.isProviderEnabled(LocationManager.NETWORK_PROVIDER))
{
LM1.requestLocationUpdates(LocationManager.NETWORK_PROVIDER,0,1,this);
}
Check whether the network location provider is enabled or not.
try {
network_enabled = locManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER);
} catch(Exception ex) {
ex.printStackTrace();
}
If the provider is enabled then only you can use that. Also, for location updates using a network provider, I think giving the minDistance value as 1 is meaningless as coarse location is anyway not very accurate. You might want to change that value to 50 or 100 meters.
I'm trying to have a background gps location listener as a service that can be used by all activities in my app. It should also be scanning for locations until I "kill" it. However I realized that after a couple of hours the gps service gets killed and I can't get anymore locations.
How do I keep this service alive (the locationManager and location listener at least) until I want it off?
Thanks
public class GPS extends IntentService {
public static LocationListener loc_listener = null;
public static LocationManager locationManager = null;
public GPS() {
super("GPS");
}
#Override
protected void onHandleIntent(Intent intent) {
locationManager = (LocationManager) getSystemService(LOCATION_SERVICE);
if (loc_listener == null) {
loc_listener = new LocationListener() {
#Override
public void onStatusChanged(String provider, int status,
Bundle extras) {
// TODO Auto-generated method stub
}
#Override
public void onProviderEnabled(String provider) {
// TODO Auto-generated method stub
}
#Override
public void onProviderDisabled(String provider) {
// TODO Auto-generated method stub
}
#Override
public void onLocationChanged(Location location) {
// TODO Auto-generated method stub
}
};
}
locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0,
0, loc_listener);
}
public static void killGPS() {
if (locationManager != null && loc_listener != null) {
locationManager.removeUpdates(loc_listener);
}
}
}
However I realized that after a couple of hours the gps service gets killed and I can't get anymore locations.
First, it is an exceptionally bad idea to keep GPS powered on all of the time, as the user's battery life will suffer greatly. Your application needs to offer tremendous value (e.g., Google Navigation) to warrant this power cost.
Second, never register a listener from an IntentService. Once onHandleIntent() ends, the service shuts down... but you leak your registered listener. This effectively keeps a background thread going. However, since you have no active components, Android eventually will terminate your process.
Because I don't want to confuse, I will try to explain with the SDK example-code.
Everything works fine - except the "onMyLocationChange" Callback.
- API 16 & 17 tested
- updated Play Services Rev.5
- Tested with ICS Tablet&Phone
I just added what is needed to receive location-updates:
UiSettingsDemoActivity implements OnMyLocationChangeListener
attached it to the map:
mMap.setOnMyLocationChangeListener(this);
and implemented the callback
#Override
public void onMyLocationChange(Location arg0) {
....
}
But this method is never triggered.
Release Notes from 26. Feb: https://groups.google.com/d/msg/google-maps-android-api-notify/va_IsjNu5-M/QPtoSn69UMgJ - So I thought this is working.
EDIT: http://code.google.com/p/gmaps-api-issues/issues/detail?id=4644
Have you added a LocationListener in your application?:
locationListener = new MyLocationListener();
locationManager = (LocationManager) getSystemService(LOCATION_SERVICE);
locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, locationListener);
MyLocationListener:
public class MyLocationListener implements LocationListener
{
static final String TAG = MyLocationListener.class.getSimpleName();
#Override
public void onLocationChanged(Location location) {
SGTasksListAppObj.getInstance().currentUserLocation = location;
Log.d(TAG, "New location was set to currentUserLocation: "+location.toString());
}
#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
}
}
Update:
Maybe you should try the:
map.setMyLocationEnabled(boolean boolean);
method, and check this link:
How to get My Location changed event with Google Maps android API v2?
How are you testing whether your location have changed? I would assume it would involve moving around or using dummy data and change the location manually. Does your gps need to be turned on?
I use the following code to get Current Location from a Network provider in my application:
LocationManager mgr = (LocationManager) getSystemService(LOCATION_SERVICE);
boolean network_enabled = mgr.isProviderEnabled(LocationManager.NETWORK_PROVIDER);
if(network_enabled){
Location location = mgr.getLastKnownLocation(LocationManager.NETWORK_PROVIDER);
But it gives a location approximately 300-700 meters away from my actual location.
This is expected from a Network provider. But the problem is:
with only this Network provider enabled, and no GPS, I openned Foursquare
application where it shows my current location exactly where I am. Now
when I come back to my application, it shows the accurate current
location or say the same location which Foursquare showed.
Same thing happens with Google apps like Navigator, Maps etc..,
How can this be done? How are other apps able to get the exact location, based on just the Network provider?
Complete Code:
public class MyLocationActivity extends Activity implements LocationListener {
private LocationManager mgr;
private String best;
Location location;
public static double myLocationLatitude;
public static double myLocationLongitude;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mgr = (LocationManager) getSystemService(LOCATION_SERVICE);
Criteria criteria = new Criteria();
best = mgr.getBestProvider(criteria, true);
location = mgr.getLastKnownLocation(LocationManager.GPS_PROVIDER);
dumpLocation(location);
}
public void onLocationChanged(Location location) {
dumpLocation(location);
}
public void onProviderDisabled(String provider) {
// TODO Auto-generated method stub
}
public void onProviderEnabled(String provider) {
// TODO Auto-generated method stub
}
public void onStatusChanged(String provider, int status, Bundle extras) {
// TODO Auto-generated method stub
}
#Override
protected void onPause() {
super.onPause();
mgr.removeUpdates(this);
}
#Override
protected void onResume() {
super.onResume();
mgr.requestLocationUpdates(best, 15000, 10, this);
}
private void dumpLocation(Location l) {
if (l != null){
myLocationLatitude = l.getLatitude();
myLocationLongitude = l.getLongitude();
}
}
}
Thank You
You are getting just the last known location. You should request location updates from the LocationManager. Use LocationManager.getLocationUpdates.
On your LocationListener on the onLocationChanged(Location location) method, you can check on the Location object, how accurate this location is, like this :
float accuracy=location.getAccuracy();
then, if this Location is accurate enough for you, you can stop receiving location updates from the LocationManager using removeUpdates() , and use the received Location. If the Location is not accurate enough, you can wait for a more precise Location, and stop the updates latter on.
I'm trying to have a background gps location listener as a service that can be used by all activities in my app. It should also be scanning for locations until I "kill" it. However I realized that after a couple of hours the gps service gets killed and I can't get anymore locations.
How do I keep this service alive (the locationManager and location listener at least) until I want it off?
Thanks
public class GPS extends IntentService {
public static LocationListener loc_listener = null;
public static LocationManager locationManager = null;
public GPS() {
super("GPS");
}
#Override
protected void onHandleIntent(Intent intent) {
locationManager = (LocationManager) getSystemService(LOCATION_SERVICE);
if (loc_listener == null) {
loc_listener = new LocationListener() {
#Override
public void onStatusChanged(String provider, int status,
Bundle extras) {
// TODO Auto-generated method stub
}
#Override
public void onProviderEnabled(String provider) {
// TODO Auto-generated method stub
}
#Override
public void onProviderDisabled(String provider) {
// TODO Auto-generated method stub
}
#Override
public void onLocationChanged(Location location) {
// TODO Auto-generated method stub
}
};
}
locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0,
0, loc_listener);
}
public static void killGPS() {
if (locationManager != null && loc_listener != null) {
locationManager.removeUpdates(loc_listener);
}
}
}
However I realized that after a couple of hours the gps service gets killed and I can't get anymore locations.
First, it is an exceptionally bad idea to keep GPS powered on all of the time, as the user's battery life will suffer greatly. Your application needs to offer tremendous value (e.g., Google Navigation) to warrant this power cost.
Second, never register a listener from an IntentService. Once onHandleIntent() ends, the service shuts down... but you leak your registered listener. This effectively keeps a background thread going. However, since you have no active components, Android eventually will terminate your process.