如何更好地处理 GPS 位置和 android
Posted
技术标签:
【中文标题】如何更好地处理 GPS 位置和 android【英文标题】:How to better handle GPS location and android 【发布时间】:2014-04-15 15:41:48 【问题描述】:我有一个带有列表视图的片段,它检索用户位置,然后根据用户位置更新列表视图。
我的代码的问题是它似乎抓住了位置更新列表,然后继续更新。并重新加载列表,几乎到了烦恼的地步。这是我的代码:
public class FindBrewery extends Fragment implements LocationListener
private TextView latituteField;
private TextView longitudeField;
LocationManager locationManager;
private String provider;
@Override
public void onAttach(Activity activity)
super.onAttach(activity);
Context c = getActivity().getApplicationContext();
locationManager =(LocationManager)activity.getSystemService(Context.LOCATION_SERVICE);
public void onCreate(Bundle savedInstanceState)
super.onCreate(savedInstanceState);
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState)
//todo change view
View rootView = inflater.inflate(R.layout.beer_location_list,container, false);
// Get the location manager
// Define the criteria how to select the locatioin provider -> use
// default
Criteria criteria = new Criteria();
provider = locationManager.getBestProvider(criteria, false);
Location location = locationManager.getLastKnownLocation(provider);
// Initialize the location fields
if (location != null)
System.out.println("Provider " + provider + " has been selected.");
onLocationChanged(location);
else
return rootView;
/* Request updates at startup */
@Override
public void onResume()
super.onResume();
locationManager.requestLocationUpdates(provider, 400, 1, this);
/* Remove the locationlistener updates when Activity is paused */
@Override
public void onPause()
super.onPause();
locationManager.removeUpdates(this);
@Override
public void onLocationChanged(Location location)
int lat = (int) (location.getLatitude());
int lng = (int) (location.getLongitude());
//latituteField.setText(String.valueOf(lat));
//longitudeField.setText(String.valueOf(lng));
//Toast.makeText(this, "Finding your loaction",Toast.LENGTH_SHORT).show();
//call asycn task for location
String url = "myURL";
Log.d("urlTest", url);
//async task goes here
new GetNearbyBreweries(this.getActivity()).execute(url);
@Override
public void onStatusChanged(String provider, int status, Bundle extras)
// TODO Auto-generated method stub
@Override
public void onProviderEnabled(String provider)
//Toast.makeText(this, "Enabled new provider " + provider,Toast.LENGTH_SHORT).show();
@Override
public void onProviderDisabled(String provider)
//Toast.makeText(this, "Disabled provider " + provider,Toast.LENGTH_SHORT).show();
【问题讨论】:
【参考方案1】:也许你想试试这个方法:
LocationClient mLocationClient;
LocationRequest mLocationRequest;
@Override
public void onAttach(Activity activity)
if (GooglePlayServicesUtil.isGooglePlayServicesAvailable(activity))
mLocationClient = new LocationClient(activity, activity, activity);
mLocationRequest = LocationRequest.create();
mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
mLocationRequest.setInterval(5000);
mLocationRequest.setNumUpdates(1);
mLocationRequest.setFastestInterval(1000);
@Override
public void onActivityCreated(Bundle savedInstanceState)
if (mLocationClient != null)
mLocationClient.connect();
@Override
protected void onStop()
if (mLocationClient != null)
if (mLocationClient.isConnected())
mLocationClient.removeLocationUpdates(this);
mLocationClient.disconnect();
super.onStop();
@Override
public void onConnected(Bundle dataBundle)
LocationManager lm = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
mLocationClient.requestLocationUpdates(mLocationRequest, this);
@Override
public void onLocationChanged(Location location)
int lat = (int) (location.getLatitude());
int lng = (int) (location.getLongitude());
// post to a handler to update the list items
诀窍如下:
您不要使用getLastKnownLocation
,因为它使用缓存并且经常返回错误数据,
你设置了setNumUpdates(1)
,所以你不需要打电话给removeLocationUpdates()
不要忘记 androidManifest 权限:
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
【讨论】:
我在上面的代码中哪里调用了我的异步任务,一旦它有了位置? 如您所见:滚动代码框以查看 :) 让我知道这是否适合您。【参考方案2】:Here 是一篇关于 GPS 位置以及如何经常检查它的巨大帖子。 (在该示例中为 30 分钟)
您可能还想查看Timer
以设置对方法的重复调用,该方法以您想要的时间间隔获取位置。
【讨论】:
【参考方案3】:虽然它可能有点满足您的需求,但请查看 Fused Location Provider。就 Android 中的位置管理器而言,它是相当具有革命性的。它允许您执行某些操作,例如设置最大和最小间隔时间以及非常直接的关闭实现。我从这个示例进行了第一次运行,效果非常好(我试图做相反的事情,我需要每 5 秒更新一次,而 Android 每 30-45 秒进行一次更新):
http://www.kpbird.com/2013/06/fused-location-provider-example.html
【讨论】:
【参考方案4】:您应该从代码中某处的 gps 中删除更新(假设在您的情况下,当您从用户那里获得当前位置时您可能会这样做),因此调用 locationManager.removeUpdates(this);一旦你有一个适合你需要的位置,就在 onLocationChanged() 方法中。
【讨论】:
【参考方案5】:为此,我使用了一项单独的服务,并在其中实现了 GPS 相关功能。该服务发出位置请求并将其广播回来。所以你可以只注册接收器来获取接收到的坐标。
LocationService.java
package com.my.package.services;
import android.app.Service;
import android.content.Intent;
import android.location.Location;
import android.os.Bundle;
import android.os.IBinder;
import android.util.Log;
import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.GooglePlayServicesClient.ConnectionCallbacks;
import com.google.android.gms.common.GooglePlayServicesClient.OnConnectionFailedListener;
import com.google.android.gms.location.LocationClient;
import com.google.android.gms.location.LocationListener;
import com.google.android.gms.location.LocationRequest;
public class LocationService extends Service implements LocationListener, ConnectionCallbacks, OnConnectionFailedListener
private static final String TAG = LocationService.class.getSimpleName();
public static final String BROADCAST_ACTION = "com.my.package.LOCATION_UPDATE";
// Milliseconds per second
private static final int MILLISECONDS_PER_SECOND = 1000;
// Update frequency in seconds
public static final int UPDATE_INTERVAL_IN_SECONDS = 60;
// Update frequency in milliseconds
private static final long UPDATE_INTERVAL = MILLISECONDS_PER_SECOND * UPDATE_INTERVAL_IN_SECONDS;
// The fastest update frequency, in seconds
private static final int FASTEST_INTERVAL_IN_SECONDS = 40;
// A fast frequency ceiling in milliseconds
private static final long FASTEST_INTERVAL = MILLISECONDS_PER_SECOND * FASTEST_INTERVAL_IN_SECONDS;
private LocationClient locationClient;
@Override
public void onCreate()
super.onCreate();
Log.d(TAG, "Location service created…");
locationClient = new LocationClient(this, this, this);
locationClient.connect();
// Unregister location listeners
private void clearLocationData()
locationClient.disconnect();
if (locationClient.isConnected())
locationClient.removeLocationUpdates(this);
@Override
public IBinder onBind(Intent intent)
return null;
// When service destroyed we need to unbind location listeners
@Override
public void onDestroy()
super.onDestroy();
Log.d(TAG, "Location service destroyed…");
clearLocationData();
@Override
public int onStartCommand(Intent intent, int flags, int startId)
Log.d(TAG, "Calling command…");
return START_STICKY;
@Override
public void onConnected(Bundle bundle)
Log.d(TAG, "Location Callback. onConnected");
Location currentLocation = locationClient.getLastLocation();
// Create the LocationRequest object
LocationRequest locationRequest = LocationRequest.create();
// Use power balanced mode
locationRequest.setPriority(LocationRequest.PRIORITY_BALANCED_POWER_ACCURACY);
// Set the update interval to 5 seconds
locationRequest.setInterval(UPDATE_INTERVAL);
// Set the fastest update interval to 1 second
locationRequest.setFastestInterval(FASTEST_INTERVAL);
locationClient.requestLocationUpdates(locationRequest, this);
onLocationChanged(currentLocation);
@Override
public void onLocationChanged(Location location)
Log.d(TAG, "onLocationChanged");
Log.d(TAG, "LOCATION: " + location.getLatitude() + ":" + location.getLongitude());
// Since location information updated, broadcast it
Intent broadcast = new Intent();
// Set action so other parts of application can distinguish and use this information if needed
broadcast.setAction(BROADCAST_ACTION);
broadcast.putExtra("latitude", location.getLatitude());
broadcast.putExtra("longitude", location.getLongitude());
sendBroadcast(broadcast);
@Override
public void onDisconnected()
Log.d(TAG, "Location Callback. onDisconnected");
@Override
public void onConnectionFailed(ConnectionResult connectionResult)
Log.d(TAG, "Location Callback. onConnectionFailed");
【讨论】:
以上是关于如何更好地处理 GPS 位置和 android的主要内容,如果未能解决你的问题,请参考以下文章