FusedLocationApi.getLastLocation始终为null

Mar*_*tti 48 android location geolocation google-play-services

我想在我的Android项目中简单地检索设备位置,为了做到这一点,我使用了play-services方法:

            protected synchronized void buildGoogleApiClient() {

    mGoogleApiClient = new GoogleApiClient.Builder( MainSearchActivity.this )
        .addConnectionCallbacks(new GoogleApiClient.ConnectionCallbacks() {
            @Override
            public void onConnected( Bundle bundle ){
                Location location = LocationServices.FusedLocationApi.getLastLocation(mGoogleApiClient);
                if( location == null ){
                    LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient, mLocationRequest, new LocationListener() {
                        @Override
                        public void onLocationChanged(Location location) {
                            lastLocation = location;
                        }
                    });
                }
            }
            @Override
            public void onConnectionSuspended( int i ){

            }

        })
        .addOnConnectionFailedListener(new GoogleApiClient.OnConnectionFailedListener() {
            @Override
            public void onConnectionFailed( ConnectionResult connectionResult ){
                if( connectionResult.hasResolution() ){
                    try {
                        // Start an Activity that tries to resolve the error
                        connectionResult.startResolutionForResult(MainSearchActivity.this, CONNECTION_FAILURE_RESOLUTION_REQUEST);
                    }catch( IntentSender.SendIntentException e ){
                        e.printStackTrace();
                    }
                }else{
                    Utils.logger("Location services connection failed with code " + connectionResult.getErrorCode(), Utils.LOG_DEBUG );
                }
            }
        })
        .addApi(LocationServices.API)
        .build();

    mGoogleApiClient.connect();
}

public Location retrieveLastLocation(){
    Location loc = LocationServices.FusedLocationApi.getLastLocation(mGoogleApiClient);
    if( loc == null)
    {

    }
    return loc; //TODO: What if loc is null?
}
Run Code Online (Sandbox Code Playgroud)

但是loc变量总是为空.每次都是在不同的手机上.我尝试在onLocationChanged中分配的lastLocation也永远不会改变.始终为空.

这些是我为应用设置的权限

    <uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="com.vogella.android.locationapi.maps.permission.MAPS_RECEIVE" />
<uses-permission android:name="com.google.android.providers.gsf.permission.READ_GSERVICES" />
Run Code Online (Sandbox Code Playgroud)

我只是不明白:为什么LocationServices不能检索一个位置?我在测试的所有三个设备上启用了所有地理定位设置: - /

感谢您的任何帮助

Ami*_*aha 42

Location Provider如果至少有一个客户端连接到融合,则仅保留背景位置.现在只需打开位置服务,就无法保证存储最后一个已知位置.

一旦第一个客户端连接,它将立即尝试获取位置.如果您的活动是第一个连接的客户端并且立即getLastLocation()被调用onConnected(),那么第一个位置可能没有足够的时间到达..

我建议您先启动Google地图应用,以便至少有一些确认位置,然后测试您的应用.

  • 所以你说的是,当用户在我们的应用程序中,并且我们需要他们的位置时,我们需要打开谷歌地图应用程序,然后希望用户将回到我们的应用程序? (41认同)
  • 那么如何在我自己的应用程序中强制执行一些位置获取事件 (13认同)
  • 我认为这个博客实际上解决了这个问题:http://blog.teamtreehouse.com/beginners-guide-location-android (7认同)
  • 在这种情况下,您需要经历常规的位置检索过程.毕竟,融合位置提供商是"权力安全且不那么重要"的任务. (6认同)

Nic*_*cks 13

我想在我看到的代码中有一个小小的遗漏.

mGoogleApiClient建,但似乎没有connected.You可以通过调用验证这一点mGoogleApiClient.isConnected().

您可以覆盖onStart方法并在那里调用connect.或者onResume(),如果您希望在活动可见时访问该位置,则可以覆盖.

  @Override
protected void onStart() {
    super.onStart();
    if (mGoogleApiClient != null) {
        mGoogleApiClient.connect();
    }
}
Run Code Online (Sandbox Code Playgroud)


小智 11

首先,创建一个LocationRequest对象:

 // Create the LocationRequest object
 mLocationRequest = LocationRequest.create()
    .setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY)
    .setInterval(10 * 1000)        // 10 seconds, in milliseconds
    .setFastestInterval(1 * 1000); // 1 second, in milliseconds
Run Code Online (Sandbox Code Playgroud)

然后,确保用户已授予使用位置的权限.如果是这样,请从requestLocationUpdates以下位置获取位置:

void getLocation() {
    Location location = null;
    if (ContextCompat.checkSelfPermission(activity, android.Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
        ActivityCompat.requestPermissions(activity, new String[]{Manifest.permission.ACCESS_COARSE_LOCATION}, 1);

        /*TODO!! INSERT CODE TO PROMPT USER TO GIVE PERMISSION*/

    } else {
        LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient, mLocationRequest, this);
    }

    mLastLocation = location;
    LocationServices.FusedLocationApi.removeLocationUpdates(mGoogleApiClient,this);
}
Run Code Online (Sandbox Code Playgroud)

如果您只需要一个位置而没有持续监控,请务必删除更新.这样,你永远不会得到null Location.

有关更多信息,请访问http://blog.teamtreehouse.com/beginners-guide-location-android.

  • `requestLocationUpdates` 回调仍然可以返回一个 `null` `Location`。 (2认同)

Gun*_*lan 10

正如在这篇文章中所说,融合的位置提供者只有在至少有一个客户端连接到它时才会保留后台位置.

但我们不想启动地图应用以获取最后位置,而且我们也不能说我们的用户启动地图应用以获取最后位置.

我们需要做的是

  1. 我们必须从FusedLocationProviderClient请求位置更新
  2. 然后我们可以从FusedLocationProviderClient获取最后一个位置,它不会为null.

请求位置

LocationRequest mLocationRequest = LocationRequest.create();
mLocationRequest.setInterval(60000);
mLocationRequest.setFastestInterval(5000);
mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
LocationCallback mLocationCallback = new LocationCallback() {
    @Override
    public void onLocationResult(LocationResult locationResult) {
        if (locationResult == null) {
            return;
        }
        for (Location location : locationResult.getLocations()) {
            if (location != null) {
                //TODO: UI updates.
            }
        }
    }
};
LocationServices.getFusedLocationProviderClient(context).requestLocationUpdates(mLocationRequest, mLocationCallback, null);
Run Code Online (Sandbox Code Playgroud)

获取最后位置

LocationServices.getFusedLocationProviderClient(context).getLastLocation().addOnSuccessListener(new OnSuccessListener<Location>() {
        @Override
        public void onSuccess(Location location) {
            //TODO: UI updates.
        }
    });
Run Code Online (Sandbox Code Playgroud)

为了获得有关位置更新的活动请求的最佳结果onStart,您可以获取最后一个位置.

  • 这是唯一对我有用的解决方案。我必须严格按照步骤进行操作,包括`PRIORITY_HIGH_ACCURACY`和设置时间间隔。任何间隔似乎都能解决问题。我还添加了`setNumUpdates(1)`。如果有人想知道,为了重现最后一个已知位置为null的问题,只需冷启动模拟器并立即调用`getLastKnownLocation()`。 (3认同)