android - Google Play 服务或 Android 定位服务

标签 android gps google-play-services location-services

我想在我的应用中实现基于位置的功能。我读了一些书,发现自己有点困惑。

在谷歌搜索教程时,几乎每个结果都会返回一个使用 Android Location API 的示例。

然而,在阅读 android 开发人员指南时,他们声明如下:

The Google Play services location APIs are preferred over the Android framework location APIs (android.location) as a way of adding location awareness to your app. If you are currently using the Android framework location APIs, you are strongly encouraged to switch to the Google Play services location APIs as soon as possible.

Android Docs

所以这告诉我不要选择只实现位置监听器这样更简单的方法。

所以我的问题是,两者之间有什么区别?为什么我要使用一个而不是另一个?

我在哪里可以找到关于如何安全准确地正确访问 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();
}
}

然后我从我的 Activity 调用我的 LocationManager:

LocationManager locationManager = new LocationManager(this);
Location location = locationManager.getCoarseLocation();
//Use Location

我想制作一个助手类,我可以从任何 Activity 或 fragment 中简单地调用它。 但是,当我运行以下命令时,构造函数成功执行。然而,我在回调中的断点都没有被击中。即使在 1 或 2 分钟后。

最佳答案

Google Play Services 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 中创建公共(public) 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 Services Location Api。只需在构造函数中的 buildGoogleApiClient(); 方法调用之后添加方法调用 mGoogleApiClient.connect()。您无需检查 Google Play 服务是否可用。

您还可以在 public void onConnectionSuspended(int i) 的实现中添加方法调用 googleApiClient.connect();

关于android - Google Play 服务或 Android 定位服务,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27844512/

相关文章:

python - urls.py 正则表达式帮助坐标

Android 浏览器 Intent - 使用 GPS 坐标打开导航应用程序

android - 无法下载 "gms:play:services-appindexing:10.0.1"

java - 如果 firebase 数据库没有子值,则开始下一个 Activity

java - FusedLocationApi.getLastLocation 始终返回 null(android 6.0,api 23)

android - google map api v2 和旧版本的 google play services lib

android - 以编程方式启用定位模式高精度或省电,无需用户访问设置

Android 隐藏自己的应用程序图标在某些 android 10 设备中不起作用

iOS 检测模拟位置

android - 用户通过 Google+ 登录的电子邮件或持久性内容(Google 游戏服务)