i'm new in java/android app and i'm creating an app that uses user-location. I want the location to be updated at the begining of the app.
The problem is that my location class is an activity and i don't want to show another contentview for this class.
Actually, i want the location thing to be done in background, without changing the UI, in a separated class.
Is it possible? How?
Thanks :P
There is no need to put the location in a different activity, the LocationManager already does it in the background:
public void getLocation(){
lm = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
gpsLocationListener = 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) {
//do something with the new location
if (location != null)
gpsLocation = location;
}
};
gpsLocation = lm.getLastKnownLocation(LocationManager.GPS_PROVIDER);
lm.requestLocationUpdates(LocationManager.GPS_PROVIDER, 1, 0, gpsLocationListener);
}
Using the LocationManager you should be able to use what ever kind of activity (or service) you want.
Related
I want after open dialog and click on location button, detect user's location and show user's location and then user dismiss dialog, location listener removes and not get location from onLocationChanged, I try used locationManager.removeUpdate(locListener)on override dismiss but not any chance and location after dismiss again shows! why? How can i detect user's location after show dialog and after detect location, location listener remove? Thanks
EDIT:
public class DialogTest extends Dialog implements
android.view.View.OnClickListener {
Context context;
LocationManager locationManager;
LocationListener locationListener;
Location location;
public DialogTest(Context context) {
super(context);
// TODO Auto-generated constructor stub
requestWindowFeature(Window.FEATURE_NO_TITLE);
this.context = context;
setContentView(R.layout.profile_dialog);
getWindow().setBackgroundDrawableResource(R.drawable.background_dialog);
firstAccessLocation=true;
setCancelable(true);
initialize();
}
#Override
public void onClick(View arg0) {
// TODO Auto-generated method stub
findAddress();
}
private void findAddress() {
// if (gpsCheckBox.isChecked()) {
locationManager = (LocationManager) context
.getSystemService(Context.LOCATION_SERVICE);
locationListener = new GPSLocationListener();
locationManager.requestLocationUpdates(locationManager.GPS_PROVIDER, 0,
0, locationListener);
locationManager.requestLocationUpdates(
locationManager.NETWORK_PROVIDER, 0, 0, locationListener);
// }
}
private void stopTracking(){
if(locationManager!=null){
locationManager.removeUpdates(locationListener);
}
}
#Override
public void dismiss() {
// TODO Auto-generated method stub
stopTracking();
gpsTurnOff();
super.dismiss();
}
public class GPSLocationListener implements LocationListener {
#Override
public void onLocationChanged(Location loc) {
// TODO Auto-generated method stub
if(location!=null)
Log.e("location", location.getLatitude()+"");
location = loc;
if (location != null&& firstAccessLocation) {
setAddress(location.getLatitude(), location.getLongitude());
firstAccessLocation=false;
}
Toast.makeText(context, "changed", Toast.LENGTH_LONG).show();
Log.e("location", "changed");
}
#Override
public void onProviderDisabled(String arg0) {
// TODO Auto-generated method stub
}
#Override
public void onProviderEnabled(String arg0) {
// TODO Auto-generated method stub
}
#Override
public void onStatusChanged(String arg0, int arg1, Bundle arg2) {
// TODO Auto-generated method stub
}
}
}
In new code you should use LocationClient rather then LocationManager. It's more efficient in getting the location with minimal energy(battery drain) with greater accuracy. Look here LocationClient vs LocationManager. With LocationClient established you can call getLastLocation() which provide you last location and doesn't start cyclic location updates.
If you want to stick with LocationManager use requestSingleUpdate (String provider, LocationListener listener, Looper looper) method to get only one newest location from it.
I am listening to 2 location providers
locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER,
500,
5,this); locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER,
500, 5, this);
it is possible somehow remove one listener? For example for one task I just want to use GPS update, and while doing this task I want that NETWORK_PROVIDER will be disabled. It is possible somehow? I tried to do like this :
locationManager.removeUpdates(this);
locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 500, 5,this);
But this is not really good, because if GPS had fix, this method is removing it and GPS starts to search satellites again.
You can create two different LocationListener:
private LocationListener gpsListener = 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) {
if(location != null){
// do your work for gps location
}
}
};
private LocationListener networkListener = .... // same init as gpsListener
And use like:
locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 500, 5, gpsListener);
locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 500, 5, networkListener);
Then you can use the approach you are doing, without losing GPS fix.
Instead of:
locationManager.removeUpdates(this);
locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 500, 5,this);
You will use:
locationManager.removeUpdates(networkListener);
I am testing the option to send coordinates to the Android Emulator using the Built in Eclipse tool.But it doesn't seem to receive them.I have this simple code:
public class Main extends MapActivity {
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
MapView view = (MapView) findViewById(R.id.themap);
view.setBuiltInZoomControls(true);
final MapController mp = view.getController();
LocationManager manager = (LocationManager) this.getSystemService(Context.LOCATION_SERVICE);
LocationListener listener = new LocationListener() {
public void onStatusChanged(String provider, int status, Bundle extras) {
// TODO Auto-generated method stub
}
public void onProviderEnabled(String provider) {
// TODO Auto-generated method stub
}
public void onProviderDisabled(String provider) {
// TODO Auto-generated method stub
}
public void onLocationChanged(final Location location) {
// TODO Auto-generated method stub
mp.setCenter(new GeoPoint((int)location.getLatitude(), (int)location.getLongitude()));
}
};
manager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, listener);
}
#Override
protected boolean isRouteDisplayed() {
// TODO Auto-generated method stub
return false;
}
}
I have the permissions for ACCESS_FINE_LOCATION and INTERNET in the Manifest.
If someone has any explanation I would be grateful.
Did you add
<uses-library android:name="com.google.android.maps" />
to the application tag in the manifest?
You also need a MD5 Fingerprint of the SDK Debug Certificate from Google to receive Google Maps data. You can get it here.
Try to put a breakpoint inside the onLocationChanged method and see if it stops when sending the location command to the emulator. this should also work when you don't have a certificate yet.
This works for me.
Listener implementation...
public class MyLocationListener implements LocationListener {
public static final String TAG = "MyLocationListener";
private Context context;
public MyLocationListener(Context c) {
this.context = c;
}
public void onLocationChanged(android.location.Location location) {
Log.d(TAG,"LocationChanged: Lat: "+location.getLatitude()+" Lng: "+location.getLongitude());
}
}
Usage...
MyLocationListener locationListener = new MyLocationListener(this);
// Acquire a reference to the system Location Manager
LocationManager locationManager = (LocationManager) this.getSystemService(Context.LOCATION_SERVICE);
// Register the listener with the Location Manager to receive location updates
locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0,locationListener);
I'm trying to have GPS coordinates sent to a text message. This code works, but every time the GPS updates location, it tries to send a new text message. I can't figure out how to stop the location updates. This is what I have currently...I realize it may not be the most efficient way to do it.
Any help would be appreciated!
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
LocationManager mlocManager = (LocationManager)getSystemService(Context.LOCATION_SERVICE);
LocationListener mlocListener = new MyLocationListener();
mlocManager.requestLocationUpdates( LocationManager.GPS_PROVIDER, 0, 0, mlocListener);
}
public void GPSDisable() {
LocationManager mlocManager = (LocationManager)getSystemService(Context.LOCATION_SERVICE);
LocationListener mlocListener = new MyLocationListener();
mlocManager.removeUpdates(mlocListener);
}
public class MyLocationListener implements LocationListener {
#Override
public void onLocationChanged(Location loc) {
loc.getLatitude();
loc.getLongitude();
double latitude = loc.getLatitude();
double longitude = loc.getLongitude();
Intent smsIntent = new Intent(Intent.ACTION_VIEW);
smsIntent.setType("vnd.android-dir/mms-sms");
smsIntent.putExtra("address", "5555555555");
smsIntent.putExtra("sms_body", "Location:"+latitude+","+longitude);
GPSDisable();
startActivity(smsIntent);
}
#Override
public void onStatusChanged(String provider, int status, Bundle extras)
{
}
#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 onLocationChanged(Location location) {
// TODO Auto-generated method stub
}
#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
}
}
I would set two global variables latitude and longitude.
This variables would be updated every onLocationChanged. You cannot change this comportament, but you can get out from there the sending of sms.
I would send the sms on a timer after 5 seconds let's say.
new java.util.Timer().schedule(
new java.util.TimerTask() {
#Override
public void run() {
Intent smsIntent = new Intent(Intent.ACTION_VIEW);
smsIntent.setType("vnd.android-dir/mms-sms");
smsIntent.putExtra("address", "5555555555");
smsIntent.putExtra("sms_body", "Location:"+latitude+","+longitude);
startActivity(smsIntent);
}
},
5000 );
And your onlocation changed could look like this
#Override
public void onLocationChanged(Location loc) {
loc.getLatitude();
loc.getLongitude();
latitude = loc.getLatitude();
longitude = loc.getLongitude();
}
First I would advise you to have a look at this article.
Having said this, generally you should "unsubscribe" from the location manager when you do not need any more updates. Typically, you subscribe for location updates in "onCreate" and unsubscribe in "onDestroy" when you need updates for as long as your Activity is 'alive'.
Even better is to subscribe/unsubscribe when your activity is getting visible or hidden respectively (via "onResume"/"onPause" respectively). Have a look here for details on the Activity's lifecycle.
Now, about your specific problem, it is not clear what is your desired behavior. Do you want to send an SMS message every time the location changes? Or only when some time passes?
Assuming what you need is to send SMS whenever your location changes but not too often, I would suggest the following:
1. Register for location updates in "onResume" and unregister in "onPause".
2. Maintain some local variables that tell you which was the last time you sent an SMS message and what were the coordinates in it. These variables should probably persist Activity lifecycle events (e.g. when the Activity is destroyed, you should "store" these values, and restore them when you recreate it).
3. Whenever there is a new location update, check if it is too soon or too close (compared to the previous SMS) and if not send another message, updating the variables.
Having said these, please note that this will work for as long as your Activity is visible. If you need a similar functionality that does not require you to keep the Activity visible, I would suggest you use a BroadcastReceiver.
Hello I've been using this guide to determine the locationof the user: http://developer.android.com/guide/topics/location/obtaining-user-location.html
and my current code looks like this:
LocationManager locationManager = (LocationManager) this.getSystemService(Context.LOCATION_SERVICE);
LocationListener locationListener = new LocationListener() {
public void onLocationChanged(Location location) {
test = new GeoPoint((int)location.getLatitude()*1000000, (int)location.getAltitude()*1000000);
mapController.animateTo(test);
}
#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
}
};
locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 0, 0, locationListener);
}
I only get error and the app shuts down though when I'm using this activity.
Thankful for help
PLease confirm that you have alloted the following permission to your manifest file
ACCESS_COARSE_LOCATION
ACCESS_FINE_LOCATION
I guess you are executing this code in the device
try this on device
Setting -> Location -> Use GPS
AND
Setting -> Application Settings -> Development -> Allow Mock Location
I solved it, I didn't instantiate mapContoller :>. But I've another problem now. which I will post in another question.