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.
Related
I have tried to get this code sorted couple of times. Here’s the scenario I have tried so far…
Scenario:
Once the activity is started I want to get the coordinates (long & lat) based on network/gps provider. This should run in background and it should keep checking until long & lat is not null or “0.0”. Thus, I have tried the following code with AsyncTask and thereby using LocationListener in doInBackground method.
Source Code:
public class GetLocation extends AsyncTask<String, String, String>
{
private myTest test;
boolean running =true;
private Context cont;
String addressString;
public GetLocation(myTest fr, Context contxt)
{
test = fr;
cont = contxt;
}
#Override
protected void onPreExecute()
{
super.onPreExecute();
}
#Override
protected void onProgressUpdate(String... values) {
super.onProgressUpdate(values);
}
#Override
protected void onPostExecute(String result)
{
test.GetContent();
}
#Override
protected String doInBackground(String... params) {
Looper.myLooper().prepare();
LocationManager locationManager;
locationManager = (LocationManager) cont
.getSystemService(Context.LOCATION_SERVICE);
Criteria crta = new Criteria();
crta.setAccuracy(Criteria.ACCURACY_FINE);
crta.setAltitudeRequired(false);
crta.setBearingRequired(false);
crta.setCostAllowed(true);
crta.setPowerRequirement(Criteria.POWER_LOW);
String provider = locationManager.getBestProvider(crta, true);
Location location = locationManager.getLastKnownLocation(provider);
updateWithNewLocation(location);
LocationListener locationListener = new LocationListener() {
#Override
public void onLocationChanged(Location location) {
updateWithNewLocation(location);
}
#Override
public void onProviderDisabled(String provider) {
updateWithNewLocation(null);
}
#Override
public void onProviderEnabled(String provider) {
}
#Override
public void onStatusChanged(String provider, int status,
Bundle extras) {
}
};
locationManager.requestLocationUpdates(provider, 0, 0,
locationListener);
Looper.loop();
return addressString;
}
private void updateWithNewLocation(Location location) {
Constants.lat = Double.toString(location.getLatitude());
Constants.long = Double.toString(location.getLongitude());
}
}
Problem:
However, I also know that Looper’s can help to keep the thread active. I want to be able to get valid coordinates and this should loop until its received. How do i call to get the locations over and over again until valid one's are received? (I could put conditions within the loops i have provided but im not aware as to how and what methods i should call to achieve this). Please provide a code snippet if possible.
Cheers!
You have implemented this wrong. There is no need to create the AsyncTask. The LocationManager will asynchronously fetch locations for you and deliver them on your LocationListener.onLocationChanged. Once you get a proper Location you can call LocationManager.removeUpdates() and this will stop for further delivery of Locations.
Do not use AsyncTask for this. You just registered the LocationManager that is listen by LocationListener and use progressbar for that. Once call LocationListner.onLocationChanged try to get Lat and Long and dismiss the progress bar. OnLocationChanged will be call at you move your device for a short distance.
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 am using the routine requestSingleUpdate() reoutine of the android LocationManager library with a LocationListener. The functionality I am trying to implement is that the user can press a button and the app will get their current location and perform reverse geocoding to get the approximate address.
My problem is that depending on the network situation of the device, getting a location fix may take a long time. How can I implement a timeout that will cause my 'requestSingleUpdate()' to give up and tell the user to find out their own bloody address?
my code:
LocationManager locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
Criteria criteria = new Criteria();
criteria.setAccuracy(Criteria.ACCURACY_FINE);
criteria.setPowerRequirement(Criteria.POWER_HIGH);
locationManager.requestSingleUpdate(criteria, new LocationListener(){
#Override
public void onLocationChanged(Location location) {
// reverse geo-code 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
}
}, null);
LocationManager doesn't seem to have a timeout mechanism. But LocationManager does have a method named removeUpdates(LocationListener listener) which you can use to cancel any callbacks on the specified LocationListener.
So, you could implement your own timeout with something like the following pseudo-code:
final LocationManager locationManager
= (LocationManager) getSystemService(Context.LOCATION_SERVICE);
// ...
final LocationListener myListener = new LocationListener() {
//... your LocationListener's methods, as above
}
Looper myLooper = Looper.myLooper();
locationManager.requestSingleUpdate(criteria, myListener, myLooper);
final Handler myHandler = new Handler(myLooper);
myHandler.postDelayed(new Runnable() {
public void run() {
locationManager.removeUpdates(myListener);
}
}, MY_TIMEOUT_IN_MS);
I'm not certain what happens if you call locationManager.removeUpdates(myListener) after you get the Location. You might want to check for that before you call removeUpdates. Or, you could add something like this to the onLocationChanged method in your callback (and possibly to the other methods as well) :
myHandler.removeCallbacks(myRunnable); // where myRunnable == the above Runnable
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
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
db = new DbAdapter(getBaseContext());
db.open();
android_id = Secure.getString(getBaseContext().getContentResolver(), Secure.ANDROID_ID);
locmgr = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
Toast.makeText(getBaseContext(), "Waiting for location..." , Toast.LENGTH_SHORT).show();
}
LocationListener onLocationChange=new LocationListener() {
public void onLocationChanged(Location loc) {
//sets and displays the lat/long when a location is provided
String latlong = "Lat: " + loc.getLatitude() + " Long: " + loc.getLongitude();
Toast.makeText(getBaseContext(), latlong, Toast.LENGTH_SHORT).show();
db.insertGPSCoordinates(android_id, Double.toString(loc.getLatitude()), Double.toString(loc.getLongitude()));
}
public void onProviderDisabled(String provider) {
// required for interface, not used
}
public void onProviderEnabled(String provider) {
// required for interface, not used
}
public void onStatusChanged(String provider, int status,
Bundle extras) {
// required for interface, not used
}
};
//pauses listener while app is inactive
#Override
public void onPause() {
super.onPause();
locmgr.removeUpdates(onLocationChange);
}
//reactivates listener when app is resumed
#Override
public void onResume() {
super.onResume();
locmgr.requestLocationUpdates(LocationManager.GPS_PROVIDER,0,10000.0f,onLocationChange);
}
This code is working for me but it gets Lats and Longs only once. I would like to know how "LocationListener" works ? I fired up the app and took a walk, it only stored 1 set. What am I doing wrong...
public void requestLocationUpdates (String provider, long minTime, float minDistance, LocationListener listener)
Your application only will update location change when your difference of position be of 10000m, 10km. Try with:
locmgr.requestLocationUpdates(LocationManager.GPS_PROVIDER,0,0,onLocationChange);
You can put the GPS thing in a timer thread to force it to update. Different devices behave differently with the GPS listener.
Also make sure your insertDBCoordinates isn't simply doing an update to the same row every time