问题
I am developing a proximity alert related project. For that whenever I opened my app, I need to get exact readings of where I am. Even though I am following the right coding practices prescribed by android documentation, I am not getting the expected result.
Why there is no alternative command in entire android Geolocation coding for getLastKnownLocation which will give us where we are earlier not now.
I have did one javascript coding in the same lines. There My code is working properly. The Descriptive address and coordinates where my device is working nice there. Those commands getCurrentPosition and watchPosition are givinga beautiful response via their event handler callbacks. Why there is no getCurrentLocation in android geolocation parlance?
Even though I have followed relevant coding practices, MyLocationListener myLocationUpdate which implements LocationListener is not updating my new location when I am moving from one place to another place. I gave MINIMUM_DISTANCE_CHANGE_FOR_UPDATES as 1(in meters) and MINIMUM_TIME_BETWEEN_UPDATES as 1000 (in milliseconds).
I am giving important code snippets below to understand the problem
in onCreate handler of the activity
locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
boolean enabled = locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER);
if (!enabled) {
Intent intent = new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS);
startActivity(intent);
}
Criteria criteria = new Criteria();
provider = locationManager.getBestProvider(criteria, false);
myLocationUpdate = new MyLocationListener();
locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER,MINIMUM_TIME_BETWEEN_UPDATES,MINIMUM_DISTANCE_CHANGE_FOR_UPDATES, myLocationUpdate);
retrieveLocationButton.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
Toast.makeText(MainActivity.this,"Finding Location",Toast.LENGTH_LONG).show();
showCurrentLocation();
}
});
latituteField = (TextView) findViewById(R.id.display_Location);
showCurrentLocation();
in showCurrentLocation function I am using locationManager.getLastKnownLocation(provider) to retrieving that location. By using GeoCoder Object and the command geocoder.getFromLocation(latitude, longitude, 1) to get First Address match for the coordinates. // internal class to handle location cahnge event private class MyLocationListener implements LocationListener contains all the Overridden functions including public void onLocationChanged(Location location) But Practically I am getting nothing out of all the application. I have already recorded Time via location.getTime(). It is showing a fixed earlier time, but not the interval i specified.
回答1:
There is the way i did it in my application and it works grate.
Create AsyncTask thread which will get the location in background.
public class GPSmanager extends AsyncTask implements LocationListener {
private Context mContext; private final long MIN_TIME_BW_UPDATES = 100000; private final float MIN_DISTANCE_CHANGE_FOR_UPDATES = 10; public GPSmanager(Context mContext) { super(); this.mContext = mContext; } public String getCurrentCity() { String adress = null; try { Location location = getLocation(); Geocoder gcd = new Geocoder(mContext, Locale.getDefault()); List<Address> addresses = gcd.getFromLocation( location.getLatitude(), location.getLongitude(), 1); if (addresses.size() > 0) { for (int i = 0; i < addresses.size() && adress == null; i++) adress = addresses.get(i).getLocality(); for (int i = 0; i < addresses.size() && adress == null; i++) adress = addresses.get(i).getCountryName(); Intent intent = new Intent(MainActivity.BRODCAST_ACTION); intent.putExtra("city", adress); mContext.sendBroadcast(intent); return adress; } } catch (Exception e) { e.printStackTrace(); } return adress; } private Location getLocation() { Location location = null; try { LocationManager locationManager = (LocationManager) mContext .getSystemService(Context.LOCATION_SERVICE); // getting GPS status boolean isGPSEnabled = locationManager .isProviderEnabled(LocationManager.GPS_PROVIDER); // getting network status boolean isNetworkEnabled = locationManager .isProviderEnabled(LocationManager.NETWORK_PROVIDER); if (!isGPSEnabled && !isNetworkEnabled) { // no network provider is enabled } else { try { Looper.prepare(); } catch (Exception e) { } if (isNetworkEnabled) { locationManager.requestLocationUpdates( LocationManager.NETWORK_PROVIDER, MIN_TIME_BW_UPDATES, MIN_DISTANCE_CHANGE_FOR_UPDATES, this); Log.d("Network", "Network"); if (locationManager != null) { location = locationManager .getLastKnownLocation(LocationManager.NETWORK_PROVIDER); } } // if GPS Enabled get lat/long using GPS Services if (isGPSEnabled) { if (location == null) { locationManager.requestLocationUpdates( LocationManager.GPS_PROVIDER, MIN_TIME_BW_UPDATES, MIN_DISTANCE_CHANGE_FOR_UPDATES, this); Log.d("GPS Enabled", "GPS Enabled"); if (locationManager != null) { location = locationManager .getLastKnownLocation(LocationManager.GPS_PROVIDER); } } } } } catch (Exception e) { e.printStackTrace(); } return location; } @Override public void onLocationChanged(Location arg0) { // TODO Auto-generated method stub } @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 } @Override protected Void doInBackground(Void... params) { getCurrentCity(); return null; }Create Service and run this Thread inside Service
public class UpdatesService extends Service { private GPSmanager gpsManager; @Override public IBinder onBind(Intent intent) { // TODO Auto-generated method stub return null; } @Override public void onCreate() { // TODO Auto-generated method stub super.onCreate(); } @Override public int onStartCommand(Intent intent, int flags, int startId) { gpsManager = new GPSmanager(this); Utiles.taskLauncher(gpsManager); return super.onStartCommand(intent, flags, startId); }}
Register BrodcastReciver in Activity where you need the location.
private BroadcastReceiver receiver = new BroadcastReceiver() {
@Override public void onReceive(Context context, Intent intent) { if (intent.getAction().equals(BRODCAST_ACTION)) { String city = intent.getExtras().getString("city"); if (city != null) if (!city.isEmpty()) etSearchCity.setText(intent.getExtras().getString( "city")); } } };Register it inside onCreate.
registerReceiver(receiver, new IntentFilter(BRODCAST_ACTION));There is the best way, I found to do it. The only way to do it quickly and in background - use Service. P.S Don't forget to add service in your Manifest.
回答2:
the problem with getting GPS location is that it isnt available immediately. From my understanding of GPS location provider is that when you request location update, the gpr provider will try to connect to the gps satellites which runs in a separate thread (not entirely sure about it). In the meantime your program is executed normally and there maybe a chance that you wont get any location.
What you can do is use Fused Location Provide which was introduced in this year's IO Event. You can find the tutorial here
回答3:
Use this to find you current location
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Bundle;
import android.os.IBinder;
import android.provider.Settings;
import android.app.AlertDialog;
import android.app.Service;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.util.Log;
public class GetMyLocation extends Service implements LocationListener {
Context mContext;
// flag for GPS status
boolean isGPSEnabled = false;
// flag for network status
boolean isNetworkEnabled = false;
// flag for GPS status
boolean canGetLocation = false;
Location location; // location
double latitude; // latitude
double longitude; // longitude
// The minimum distance to change Updates in meters
private static final long MIN_DISTANCE_CHANGE_FOR_UPDATES = 1; // 1 meter
// The minimum time between updates in milliseconds
private static final long MIN_TIME_BW_UPDATES = 500; // 0.5 second
// Declaring a Location Manager
protected LocationManager locationManager;
public GetMyLocation(Context context) {
this.mContext = context;
getLocation();
}
public Location getLocation() {
try {
locationManager = (LocationManager) mContext.getSystemService(LOCATION_SERVICE);
// getting GPS status
isGPSEnabled = locationManager
.isProviderEnabled(LocationManager.GPS_PROVIDER);
// getting network status
isNetworkEnabled = locationManager
.isProviderEnabled(LocationManager.NETWORK_PROVIDER);
if (!isGPSEnabled && !isNetworkEnabled) {
// no network provider is enabled
} else {
this.canGetLocation = true;
if (isNetworkEnabled) {
locationManager.requestLocationUpdates(
LocationManager.NETWORK_PROVIDER,
MIN_TIME_BW_UPDATES,
MIN_DISTANCE_CHANGE_FOR_UPDATES, this);
Log.d("Network", "Network");
if (locationManager != null) {
location = locationManager.getLastKnownLocation(LocationManager.NETWORK_PROVIDER);
if (location != null) {
latitude = location.getLatitude();
longitude = location.getLongitude();
}
}
}
// if GPS Enabled get lat/long using GPS Services
if (isGPSEnabled) {
if (location == null) {
locationManager.requestLocationUpdates(
LocationManager.GPS_PROVIDER,
MIN_TIME_BW_UPDATES,
MIN_DISTANCE_CHANGE_FOR_UPDATES, this);
Log.d("GPS Enabled", "GPS Enabled");
if (locationManager != null) {
location = locationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER);
if (location != null) {
latitude = location.getLatitude();
longitude = location.getLongitude();
}
}
}
}
}
} catch (Exception e) {
e.printStackTrace();
}
return location;
}
public void stopUsingGPS(){
if(locationManager != null){
locationManager.removeUpdates(GetMyLocation.this);
}
}
/**
* Function to get latitude
* */
public double getLatitude(){
if(location != null){
latitude = location.getLatitude();
}
// return latitude
return latitude;
}
/**
* Function to get longitude
* */
public double getLongitude(){
if(location != null){
longitude = location.getLongitude();
}
// return longitude
return longitude;
}
/**
* Function to check GPS/wifi enabled
* @return boolean
* */
public boolean canGetLocation() {
return this.canGetLocation;
}
/**
* Function to show settings alert dialog
* On pressing Settings button will launch Settings Options
* */
public void showSettingsAlert(){
AlertDialog.Builder alertDialog = new AlertDialog.Builder(mContext);
// Setting Dialog Title
alertDialog.setTitle("GPS is settings");
// Setting Dialog Message
alertDialog.setMessage("GPS is not enabled. Do you want to go to settings menu?");
// On pressing Settings button
alertDialog.setPositiveButton("Settings", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog,int which) {
Intent intent = new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS);
mContext.startActivity(intent);
}
});
// on pressing cancel button
alertDialog.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
dialog.cancel();
}
});
// Showing Alert Message
alertDialog.show();
}
@Override
public void onLocationChanged(Location location) {
this.location = location;
}
@Override
public void onProviderDisabled(String provider) {
}
@Override
public void onProviderEnabled(String provider) {
}
@Override
public void onStatusChanged(String provider, int status, Bundle extras) {
}
@Override
public IBinder onBind(Intent arg0) {
return null;
}
}
To use it in your Activity
gps = new GetMyLocation(YourActivity.this);
// check if GPS enabled
if(gps.canGetLocation()){
latitude = gps.getLatitude();
longitude = gps.getLongitude();
}
else{
// can't get location
// GPS or Network is not enabled
// Ask user to enable GPS/network in settings
gps.showSettingsAlert();
}
来源:https://stackoverflow.com/questions/19559712/android-requestlocationupdates-failing