我想在我的应用中实现基于位置的功能。我一直在阅读,我发现自己有点困惑。
当谷歌搜索教程时,几乎每个结果都会返回一个使用Android Location API的示例。
但是,在阅读Android开发人员指南时,他们会说明以下内容:
Google Play服务位置API优先于Android框架位置API(android.location),作为向您的应用添加位置感知的一种方式。如果您当前正在使用Android框架位置API,强烈建议您尽快切换到Google Play服务位置API。
所以这告诉我不要采用更简单的方法来实现位置监听器。
所以我的问题是,两者有什么区别?为什么我会使用一个而不是另一个?
我在哪里可以找到关于如何安全准确地正确访问Google Play服务位置API的正确教程。
到目前为止,我已尝试过此操作(如Android网站上所示),但我的回拨都没有被调用。
public class LocationManager implements GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener {
private Context mContext;
private GoogleApiClient mGoogleApiClient;
private Location mLastLocation;
public LocationManager(Context context) {
mContext = context;
//
if (checkIfGooglePlayServicesAreAvailable()) {
//Get Access to the google service api
buildGoogleApiClient();
} else {
//Use Android Location Services
//TODO:
}
}
public Location getCoarseLocation() {
if (mLastLocation != null) {
return mLastLocation;
} else return null;
}
private synchronized void buildGoogleApiClient() {
mGoogleApiClient = new GoogleApiClient.Builder(mContext)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.addApi(LocationServices.API)
.build();
}
private boolean checkIfGooglePlayServicesAreAvailable() {
int errorCode = GooglePlayServicesUtil.isGooglePlayServicesAvailable(mContext);
if (errorCode != ConnectionResult.SUCCESS) {
GooglePlayServicesUtil.getErrorDialog(errorCode, (MainActivity) mContext, 0).show();
return false;
}
return true;
}
@Override
public void onConnected(Bundle bundle) {
Location location = LocationServices.FusedLocationApi.getLastLocation(mGoogleApiClient);
if (location != null) {
mLastLocation = location;
Toast.makeText(mContext, location.getLongitude() + " , " + location.getLatitude() + " : " + location.getAccuracy(), Toast.LENGTH_LONG).show();
}
}
@Override
public void onConnectionSuspended(int i) {
Toast.makeText(mContext, "suspended", Toast.LENGTH_LONG).show();
}
@Override
public void onConnectionFailed(ConnectionResult connectionResult) {
Toast.makeText(mContext, connectionResult.toString(), Toast.LENGTH_LONG).show();
}
}
然后我从我的活动中调用我的LocationManager:
LocationManager locationManager = new LocationManager(this);
Location location = locationManager.getCoarseLocation();
//Use Location
我想创建一个帮助类,我可以从任何活动或片段调用它。 但是,当我运行以下命令时,构造函数执行成功。但是我的回调中没有一个断点被击中。即使在1或2分钟后。
答案 0 :(得分:5)
Google Play服务Api使用仅在建立连接时调用的回调方法public void onConnected(Bundle bundle)
。只有这样,LocationServices.FusedLocationApi.getLastLocation(googleApiClient)
方法调用才能返回正确的Location
。
您已构建了一个帮助程序类来获取此位置,但您应该了解该连接未立即建立。因此,只是对辅助类或其方法的异步调用可能会返回一个空对象,因为可能没有建立连接。
您可以通过以下方式获取Location
。
1)广播位置并通过BroadcastReceiver
接收,以便在public void onConnected(Bundle bundle)
内执行后续操作。这对我有用。
private boolean flag = false;
@Override
public void onConnected(Bundle connectionHint) {
location = LocationServices.FusedLocationApi.getLastLocation(googleApiClient);
if (location != null && !flag) {
flag = true;
Intent intent = new Intent(LOCATION_BROADCAST_ACTION);
intent.putExtra(INTENT_EXTRA_LOCATION, location);
LocalBroadcastManager.getInstance(context).sendBroadcast(intent);
Log.i(TAG, "Sending Location Broadcast");
Log.i(TAG, location.toString());
} else if (location == null){
Toast.makeText(mContext, R.string.no_location_detected, Toast.LENGTH_LONG).show();
Log.e(TAG, "No Location Detected");
}
}
2)在调用Activity或Fragment中创建一个公共Location
对象,并从public void onConnected(Bundle bundle)
方法中更新其值。
@Override
public void onConnected(Bundle connectionHint) {
location = LocationServices.FusedLocationApi.getLastLocation(googleApiClient);
if (location != null) {
MyActivity.location = location; // update the Location object of you caller activity or fragment
Log.i(TAG, "location updated");
}
}
此外,您应该在构建GoogleApiClient后连接到Google Play服务位置Api。只需在构造函数中的mGoogleApiClient.connect()
方法调用之后添加方法调用buildGoogleApiClient();
即可。您无需检查Google Play服务是否可用。
您还可以在googleApiClient.connect();
。
public void onConnectionSuspended(int i)
答案 1 :(得分:2)
您需要致电:
mGoogleApiClient.connect()
除了您对差异的疑问外,Google Play服务框架还为您提供了“融合”的位置。使用Android框架,您应该使用GPS或Wif。您可以指定条件,但如果您需要位置用户位置,则Google Play服务是最佳选择。如果您需要一个非常精确的位置,例如GPS,例如您的应用程序是导航器应用程序,那么最好直接使用GPS。