为啥 FusedLocationApi.getLastLocation 为空

Posted

技术标签:

【中文标题】为啥 FusedLocationApi.getLastLocation 为空【英文标题】:Why is FusedLocationApi.getLastLocation null为什么 FusedLocationApi.getLastLocation 为空 【发布时间】:2015-06-30 01:03:51 【问题描述】:

我正在尝试使用 FusedLocationApi.getLastLocation 获取位置,并且我在清单文件中获得了位置权限:

<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />

但是,当我从系统请求位置时,我收到了null。我只是在测试关闭和打开位置服务,所以它可能与此有关(当然,当我尝试这个时它是打开的)。但即使在返回 null 之后,我也在等待 onLocationChanged 被调用并且它从未被调用过。我在这里也看到了类似的问题:FusedLocationApi.getLastLocation always null

这是我的代码:

 protected LocationRequest createLocationRequest() 
    LocationRequest mLocationRequest = new LocationRequest();
    mLocationRequest.setInterval(120000);
    mLocationRequest.setFastestInterval(30000);
    mLocationRequest.setPriority(LocationRequest.PRIORITY_BALANCED_POWER_ACCURACY);
    return mLocationRequest;


protected GoogleApiClient getLocationApiClient()
    return new GoogleApiClient.Builder(this)
            .addConnectionCallbacks(this)
            .addOnConnectionFailedListener(this)
            .addApi(LocationServices.API)
            .build();


LocationRequest locationRequest = createLocationRequest(); 

@Override
public void onLocationChanged(Location location) 
    App.setLocation(location); // NEVER CALLED


@Override
public void onConnected(Bundle bundle) 
    App.setLocation(LocationServices.FusedLocationApi.getLastLocation(locationApiClient)); //RETURNS NULL
    LocationRequest locationRequest = createLocationRequest();
    LocationServices.FusedLocationApi.requestLocationUpdates(locationApiClient, locationRequest, this);

在我的应用程序的onCreate 上:

locationApiClient = getLocationApiClient();
locationApiClient.connect();

this 是我的应用程序对象。 为什么我会得到空值(是的,我确实知道在文档中所述的某些极少数情况下它可能是空值,但我总是得到这个,不是很少) 此后仍未获得位置更新?如果有帮助,它是一个没有 SIM 卡的真实设备(三星 Galaxy S3)。

【问题讨论】:

Android 中没有ACCESS_GPSACCESS_LOCATION 权限。除此之外,没有代码很难帮助你。 @CommonsWare 我不知道我是怎么做到的,反正应该不会影响行为。 你是在真机上测试吗?除了文档说,如果客户端未连接,将返回 null。确保您的客户端已完全连接。 你能把代码粘贴到你初始化api客户端的地方和你得到null的地方吗? 这个答案与这篇文章中的废话完全一样。问题不在于位置回调,问题在于 FusedLocationProvider 为 getLastLocation 返回 null。我看到它说 null,然后正确报告,然后几秒钟后再次报告 null,仅在某些设备上。 【参考方案1】:

如果至少有一个客户端连接到融合位置提供程序,它将只维护后台位置。现在仅打开位置服务并不能保证存储最后一个已知位置。

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

然后你设置mLocationRequest.setFastestInterval(30000); 这基本上意味着 30 秒。所以至少 30 秒后,通常根据您的设置,首选时间是 120 秒,如果根本没有存储的最后一个已知位置,这不是很长的时间吗?加上你正在设置电池平衡优先级,这会让你等待更长的时间。

mLocationRequest.setPriority(LocationRequest.PRIORITY_BALANCED_POWER_ACCURACY);

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

【讨论】:

我遇到了与 OP 相同的问题,但在使用模拟器时,我手动设置了设备的位置。在模拟器中打开地图为我解决了这个问题。【参考方案2】:

我在我的应用程序中使用 FusedLocationProvider api, 这是我在设备和模拟器上都可以使用的代码 -

  @Override
  protected void onCreate(Bundle savedInstanceState)
     //put your code here
     ....
     getLocation();

  

 private void getLocation()
    locationRequest = LocationRequest.create();
    locationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
    locationRequest.setInterval(LOCATION_INTERVAL);
    locationRequest.setFastestInterval(LOCATION_INTERVAL);
    fusedLocationProviderApi = LocationServices.FusedLocationApi;
    googleApiClient = new GoogleApiClient.Builder(this)
    .addApi(LocationServices.API)
    .addConnectionCallbacks(this)
    .addOnConnectionFailedListener(this)
    .build();
    if (googleApiClient != null) 
        googleApiClient.connect();
    



   @Override
   public void onConnected(Bundle arg0) 
        fusedLocationProviderApi.requestLocationUpdates(googleApiClient,  locationRequest, this);
   

   @Override
   public void onLocationChanged(Location location) 
        Toast.makeText(mContext, "location :"+location.getLatitude()+" , "+location.getLongitude(), Toast.LENGTH_SHORT).show();
    

这是我的工作代码。

希望我的代码对你有所帮助。

干杯..

【讨论】:

注意需要实现 GoogleApiClient.ConnectionCallbacks 和 com.google.android.gms.location.LocationListener 那么与作者代码的主要区别是什么?命令序列? @AlexeyStrakh 是的。当应用启动时,googleApiClient 的 lastLocation 对象为空。因此,在 null 对象上调用最后一个位置将返回 null,因此应该通过首先更新位置来改进算法,然后当 googleApiClient 获取当前位置时,您继续询问它。请注意,如果位置没有改变,onLocationChanged 将不会被触发。 你甚至不使用 fusedLocationProviderApi ...问题是“为什么 FusedLocationApi.getLastLocation null”而不是“我如何在没有 FusedLocationApil 的情况下进行位置更新”【参考方案3】:

如果它返回 null,这意味着您需要在检索位置之前使用 LocationServices.FusedLocationApi.requestLocationUpdates 开始接收位置更新。

对我来说,解决问题的方法是调用:

LocationServices.FusedLocationApi.requestLocationUpdates(locationApiClient,locationRequest, this);

之前:

App.setLocation(LocationServices.FusedLocationApi.getLastLocation(locationApiClient));

问题是最后一个位置不存在所以它是空的。

如果问题仍然存在,试试这个:

检查必要的权限。

确保您已在设备上启用定位,然后重新启动。

【讨论】:

这是正确的,不久前我遇到了类似的问题***.com/q/35830987/4243687 lastKnownLoction 只是一个缓存位置。事实上,当其他应用请求一个位置时,这个位置就会被缓存【参考方案4】:

我使用了 FusedAPI,下面的代码对我有用...在真实设备中测试

import android.Manifest;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.content.IntentSender;
import android.content.pm.PackageManager;
import android.location.Location;
import android.location.LocationManager;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Looper;
import android.provider.Settings;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v4.app.ActivityCompat;
import android.support.v4.app.FragmentActivity;
import android.support.v4.content.PermissionChecker;
import android.widget.ProgressBar;

import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.GoogleApiAvailability;
import com.google.android.gms.common.api.ApiException;
import com.google.android.gms.common.api.GoogleApiClient;
import com.google.android.gms.common.api.ResolvableApiException;
import com.google.android.gms.common.api.ResultCallback;
import com.google.android.gms.location.FusedLocationProviderClient;
import com.google.android.gms.location.LocationCallback;
import com.google.android.gms.location.LocationListener;
import com.google.android.gms.location.LocationRequest;
import com.google.android.gms.location.LocationResult;
import com.google.android.gms.location.LocationServices;
import com.google.android.gms.location.LocationSettingsRequest;
import com.google.android.gms.location.LocationSettingsResponse;
import com.google.android.gms.location.LocationSettingsResult;
import com.google.android.gms.location.LocationSettingsStatusCodes;
import com.google.android.gms.location.SettingsClient;
import com.google.android.gms.maps.CameraUpdate;
import com.google.android.gms.maps.CameraUpdateFactory;
import com.google.android.gms.maps.GoogleMap;
import com.google.android.gms.maps.OnMapReadyCallback;
import com.google.android.gms.maps.SupportMapFragment;
import com.google.android.gms.maps.model.LatLng;
import com.google.android.gms.maps.model.LatLngBounds;
import com.google.android.gms.maps.model.Marker;
import com.google.android.gms.maps.model.MarkerOptions;
import com.google.android.gms.tasks.OnCanceledListener;
import com.google.android.gms.tasks.OnFailureListener;
import com.google.android.gms.tasks.OnSuccessListener;

import java.util.ArrayList;
import java.util.LinkedHashMap;

public class MapsActivity extends FragmentActivity implements OnMapReadyCallback, GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener, LocationListener, ResultCallback<LocationSettingsResult> 

    private static final int REQUEST_CHECK_SETTINGS = 214;
    private static final int REQUEST_ENABLE_GPS = 516;
    private final int REQUEST_LOCATION_PERMISSION = 214;
    protected GoogleApiClient mGoogleApiClient;
    protected LocationSettingsRequest mLocationSettingsRequest;
    /* For Google Fused API */
    private FusedLocationProviderClient mFusedLocationClient;
    private SettingsClient mSettingsClient;
    private LocationCallback mLocationCallback;
    private LocationRequest mLocationRequest;
    private Location mCurrentLocation;
    /* For Google Fused API */
    private Context context;
    private ProgressBar progressBar;
    private AsyncTask task;
    private GoogleMap mMap;

    @Override
    protected void onCreate(Bundle savedInstanceState) 
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_maps);

        SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager()
                .findFragmentById(R.id.map);
        mapFragment.getMapAsync(this);

        try 
            int permissionCheck = PermissionChecker.checkCallingOrSelfPermission(context, Manifest.permission.ACCESS_FINE_LOCATION);
            if (permissionCheck == PackageManager.PERMISSION_GRANTED) 
                Helper.showLog("Permission is already allowed. Build Client");
                buildGoogleApiClient();
             else 
                Helper.showLog("Permission is requested");
                ActivityCompat.requestPermissions(MapsActivity.this, new String[]Manifest.permission.ACCESS_FINE_LOCATION, REQUEST_LOCATION_PERMISSION);
            
         catch (Exception e) 
            e.printStackTrace();
        
    

    @Override
    public void onMapReady(GoogleMap googleMap) 
        mMap = googleMap;

        // Add a marker in Sydney and move the camera
        LatLng sydney = new LatLng(-34, 151);
        mMap.addMarker(new MarkerOptions().position(sydney).title("Marker in Sydney"));
        mMap.moveCamera(CameraUpdateFactory.newLatLng(sydney));
    

    protected synchronized void buildGoogleApiClient() 
        mFusedLocationClient = LocationServices.getFusedLocationProviderClient(this);
        mSettingsClient = LocationServices.getSettingsClient(this);

        mGoogleApiClient = new GoogleApiClient.Builder(this)
                .addConnectionCallbacks(this)
                .addOnConnectionFailedListener(this)
                .addApi(LocationServices.API)
                .build();

        connectGoogleClient();

        mLocationCallback = new LocationCallback() 
            @Override
            public void onLocationResult(LocationResult locationResult) 
                super.onLocationResult(locationResult);
                Helper.showLog("Location Received");
                mCurrentLocation = locationResult.getLastLocation();
                onLocationChanged(mCurrentLocation);
            
        ;
    

    private void connectGoogleClient() 
        GoogleApiAvailability googleAPI = GoogleApiAvailability.getInstance();
        int resultCode = googleAPI.isGooglePlayServicesAvailable(this);
        if (resultCode == ConnectionResult.SUCCESS) 
            mGoogleApiClient.connect();
         else 
            int REQUEST_GOOGLE_PLAY_SERVICE = 988;
            googleAPI.getErrorDialog(this, resultCode, REQUEST_GOOGLE_PLAY_SERVICE);
        
    

    @Override
    public void onConnected(@Nullable Bundle bundle) 
        mLocationRequest = new LocationRequest();
        mLocationRequest.setInterval(30 * 1000);
        mLocationRequest.setFastestInterval(5 * 1000);
        mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);

        LocationSettingsRequest.Builder builder = new LocationSettingsRequest.Builder();
        builder.addLocationRequest(mLocationRequest);
        builder.setAlwaysShow(true);
        mLocationSettingsRequest = builder.build();

        mSettingsClient
                .checkLocationSettings(mLocationSettingsRequest)
                .addOnSuccessListener(new OnSuccessListener<LocationSettingsResponse>() 
                    @Override
                    public void onSuccess(LocationSettingsResponse locationSettingsResponse) 
                        Helper.showLog("GPS Success");
                        requestLocationUpdate();
                    
                ).addOnFailureListener(new OnFailureListener() 
            @Override
            public void onFailure(@NonNull Exception e) 
                int statusCode = ((ApiException) e).getStatusCode();
                switch (statusCode) 
                    case LocationSettingsStatusCodes.RESOLUTION_REQUIRED:
                        try 
                            ResolvableApiException rae = (ResolvableApiException) e;
                            rae.startResolutionForResult(MapsActivity.this, REQUEST_CHECK_SETTINGS);
                         catch (IntentSender.SendIntentException sie) 
                            Helper.showLog("PendingIntent unable to execute request.");
                        
                        break;
                    case LocationSettingsStatusCodes.SETTINGS_CHANGE_UNAVAILABLE:
                        Helper.showLog("Location settings are inadequate, and cannot be fixed here. Fix in Settings.");
                
            
        ).addOnCanceledListener(new OnCanceledListener() 
            @Override
            public void onCanceled() 
                Helper.showLog("checkLocationSettings -> onCanceled");
            
        );
    

    @Override
    public void onConnectionSuspended(int i) 
        connectGoogleClient();
    

    @Override
    public void onConnectionFailed(@NonNull ConnectionResult connectionResult) 
        buildGoogleApiClient();
    

    @Override
    public void onResult(@NonNull LocationSettingsResult locationSettingsResult) 

    

    @Override
    public void onLocationChanged(Location location) 
        String latitude = String.valueOf(location.getLatitude());
        String longitude = String.valueOf(location.getLongitude());

        if (latitude.equalsIgnoreCase("0.0") && longitude.equalsIgnoreCase("0.0")) 
            requestLocationUpdate();
         else 
            //Perform Your Task with LatLong
        
    

    @SuppressLint("MissingPermission")
    private void requestLocationUpdate() 
        mFusedLocationClient.requestLocationUpdates(mLocationRequest, mLocationCallback, Looper.myLooper());
    

    @Override
    protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) 
        super.onActivityResult(requestCode, resultCode, data);

        if (requestCode == REQUEST_CHECK_SETTINGS) 
            switch (resultCode) 
                case Activity.RESULT_OK:
                    Helper.showLog("User allow to access location. Request Location Update");
                    requestLocationUpdate();
                    break;
                case Activity.RESULT_CANCELED:
                    Helper.showLog("User denied to access location.");
                    openGpsEnableSetting();
                    break;
            
         else if (requestCode == REQUEST_ENABLE_GPS) 
            LocationManager locationManager = (LocationManager) context.getSystemService(Context.LOCATION_SERVICE);
            boolean isGpsEnabled = locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER);

            if (!isGpsEnabled) 
                openGpsEnableSetting();
             else 
                requestLocationUpdate();
            
        
    

    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) 
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);

        if (requestCode == REQUEST_LOCATION_PERMISSION) 
            int permissionCheck = PermissionChecker.checkCallingOrSelfPermission(context, Manifest.permission.ACCESS_FINE_LOCATION);
            if (permissionCheck == PackageManager.PERMISSION_GRANTED) 
                Helper.showLog("User Allowed Permission Build Google Client");
                buildGoogleApiClient();
             else 
                Helper.showLog("User Denied Permission");
            
        

    

    private void openGpsEnableSetting() 
        Intent intent = new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS);
        startActivityForResult(intent, REQUEST_ENABLE_GPS);
    

    @Override
    protected void onDestroy() 
        //Remove location update callback here
        mFusedLocationClient.removeLocationUpdates(mLocationCallback);
        super.onDestroy();
    

助手类

public class Helper 
    public static void showLog(String message) 
        Log.e("Ketan", "" + message);
    

    public static void showToast(Context context, String message) 
        Toast.makeText(context, "" + message, Toast.LENGTH_SHORT).show();
    

May Help

【讨论】:

【参考方案5】:

可能,您的问题是您连接客户端的位置,我现在无法测试,但正如示例中的 google 文档所示,您应该在活动中的 onStart() 方法中连接客户端。

    @Override
    protected void onStart() 
        super.onStart();
        mGoogleApiClient.connect();
    

    @Override
    protected void onStop() 
        super.onStop();
        if (mGoogleApiClient.isConnected()) 
            mGoogleApiClient.disconnect();
        
    

对我来说,这使 getLocation 工作

【讨论】:

在调用Activity类的OnStop()中的super方法之前,你应该断开google api客户端。【参考方案6】:

对于 23 以上的 android APILEVEL,您需要一些运行时权限。定位服务ACCESS_COARSE_LOCATIONACCESS_FINE_LOCATION 也需要权限。

查看此文档https://developer.android.com/training/permissions/requesting.html

【讨论】:

【参考方案7】:

我遇到了同样的问题。就我而言,问题在于允许应用程序的权限。 我拒绝了第一次启动应用时询问的 FINE LOCATION 权限。

尝试从您的设备上卸载该应用程序,然后重新部署它。它将再次请求许可。允许精确位置访问。

在我的情况下工作!

【讨论】:

【参考方案8】:

我找到了解决方案。

我正在使用 API 22 的手机上测试我的应用程序,它运行良好,但是,在 API 17 位置上不断返回 null

事实证明,您必须允许您的手机使用谷歌定位服务。您可以通过转到Settings-&gt;Location Access-&gt;Check the "WLAN &amp; mobile network location" 来做到这一点(在另一个 API 中可能会被称为不同的名称)。它的描述是这样的:

让应用使用 Google 的位置服务来估计您的位置 快点。系统会收集匿名位置数据并将其发送给 Google。

通过启用它,我突然开始获得急需的融合位置数据。

希望这会有所帮助!

【讨论】:

【参考方案9】:

我认为这不是编码问题。

似乎设备位置提供者难以在建议的时间确定位置,并且从未调用 locationChanged() 方法。

检查是否未使用更硬的定位模式(如仅 GPS)选择定位服务的设备配置。

如果是这样,如果您在室内(我猜您是这样),您的代码将无法通过 GPS 确定您的位置。选择高精度选项,您的问题将得到解决。

【讨论】:

【参考方案10】:

这是确切的解决方案。但我想添加一些小的解释步骤,以便任何人都能获得确切的概念。为什么它返回 null,我同意遵循 Amit K 的答案。但是,为了保证避免位置 NullPointerException,您在 onLocationChanged() 回调中启动与位置相关的处理。

1) Android 组件的 onCreate()(例如,ActivityFragmentService注意:不是 IntentService em>),build 然后连接 GoogleApiClient,如下所示。

buildGoogleApiClient();
mGoogleApiClient.connect();

buildGoogleApiClient() 实现在哪里,

protected synchronized void buildGoogleApiClient() 
        Log.i(TAG, "Building GoogleApiClient");

        mGoogleApiClient = new GoogleApiClient.Builder(this)
                .addApi(LocationServices.API)
                .addConnectionCallbacks(this)
                .addOnConnectionFailedListener(this)
                .build();

    

稍后在 onDestroy() 上,您可以断开 GoogleApiClient 为,

@Override
    public void onDestroy() 
        Log.i(TAG, "Service destroyed!");
        mGoogleApiClient.disconnect();
        super.onDestroy();
    

第 1 步确保您构建并连接 GoogleApiClient。

1) GoogleApiClient 实例第一次通过 onConnected() 方法连接。现在,您的下一步应该查看 onConnected() 方法。

@Override
    public void onConnected(@Nullable Bundle bundle) 
        Log.i(TAG, "GoogleApiClient connected!");
        buildLocationSettingsRequest();
        createLocationRequest();
        location = LocationServices.FusedLocationApi.getLastLocation(mGoogleApiClient);
        Log.i(TAG, " Location: " + location); //may return **null** because, I can't guarantee location has been changed immmediately 
    

在上面,您调用了方法 createLocationRequest() 来创建位置请求。 createLocationRequest() 方法如下所示。

protected void createLocationRequest() 
        //remove location updates so that it resets
        LocationServices.FusedLocationApi.removeLocationUpdates(mGoogleApiClient, this); //Import should not be **android.Location.LocationListener**
    //import should be **import com.google.android.gms.location.LocationListener**;

        mLocationRequest = new LocationRequest();
        mLocationRequest.setInterval(10000);
        mLocationRequest.setFastestInterval(5000);
        mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
        //restart location updates with the new interval
        LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient, mLocationRequest, this);

    

3) 现在,在 LocationListener 接口的 onLocationChange() 回调中,您将获得新的位置。

@Override
    public void onLocationChanged(Location location) 
        Log.i(TAG, "Location Changed!");
        Log.i(TAG, " Location: " + location); //I guarantee of change of location here.


    

你在 Logcat 中得到这样的结果: 03-22 18:34:17.336 817-817/com.LiveEarthquakesAlerts I/LocationTracker: Location: Location[fused 37.421998,-122.084000 acc=20 et=+15m35s840ms alt=0.0]

注意:虽然我在阿肯色州,但上面得到的位置是 Google 总部的位置。当您使用模拟器时会发生这种情况。在真机上显示正确的地址。

为了能够完成这三个步骤,您应该如下配置您的 build.gradle:

 compile 'com.google.android.gms:play-services-location:10.2.1'

【讨论】:

每个人都知道在哪里可以找到样板代码。问题是为什么提供者会在最后一个位置返回 null 1) 如果 GoogleApiClient 没有找到 Location 对象,则返回 null。这是很明显的事情。 这不是一个有用的回应。显然 OP 不会问这是否是一个明显的问题 看我的语言? :S 你仍然没有回答这个问题......补充说,除了样板代码之外,这还有什么?仅仅因为你在你的应用程序中使用它或将它用于研究论文并不意味着它是你的,或者它不是很容易找到(咳咳:developer.android.com/training/location/… .. 你的代码几乎是相同的)。除非一切正常,否则您不能绝对保证会有最后一个位置,不是这种情况的情况就是这个问题中探讨的情况 “在 Null 位置调用 onLocationChange() 绝对是零变化” - 这实际上与问题无关(getLastLocation)。 “这里是我的代码”和“这里是如何避免空指针”没有回答“为什么 FusedLocationApi.getLastLocation 为空”的问题。 “它取决于系统”是一个更好的答案,尽管对于遇到问题的人来说,它与“这是我的代码”一样有用【参考方案11】:

试试这个,

    private static int UPDATE_INTERVAL = 10000; // 10 sec
    private static int FATEST_INTERVAL = 5000; // 5 sec
    private static int DISPLACEMENT = 10; // 10 meters


   private void createLocationRequest() 
    mLocationRequest = new LocationRequest();
    mLocationRequest.setInterval(UPDATE_INTERVAL);
    mLocationRequest.setFastestInterval(FATEST_INTERVAL);
    mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
    mLocationRequest.setSmallestDisplacement(DISPLACEMENT);
  

 @Override
    public void onConnected(@Nullable Bundle bundle) 
        mLastLocation = LocationServices.FusedLocationApi
            .getLastLocation(mGoogleApiClient);
       if(mLastLocation == null)
           LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient, mLocationRequest, this);
        
    

【讨论】:

这并不能解释为什么它是空的【参考方案12】:

检查您的设备是否启用了位置

您可以从 通知面板设置 启用它:

设置 -> 个人 -> 位置

我只使用了以下权限:

ACCESS_FINE_LOCATION

我的工作代码是:

package com.go.findlocation;

import android.content.pm.PackageManager;
import android.location.Location;
import android.location.LocationManager;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v4.app.ActivityCompat;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.widget.TextView;
import android.widget.Toast;

import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.api.GoogleApiClient;
import com.google.android.gms.location.LocationListener;
import com.google.android.gms.location.LocationRequest;
import com.google.android.gms.location.LocationServices;

public class MainActivity extends AppCompatActivity implements     GoogleApiClient.ConnectionCallbacks,
    GoogleApiClient.OnConnectionFailedListener, LocationListener 

private GoogleApiClient mGoogleApiClient = null;
//private Location mLocation = null;
private LocationManager mLocationManager = null;
private LocationRequest mLocationRequest = null;

private TextView tv1 = null;
private TextView tv2 = null;

@Override
protected void onCreate(Bundle savedInstanceState) 
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    mLocationRequest = new LocationRequest();
    mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
    mLocationRequest.setInterval(10000);
    mLocationRequest.setFastestInterval(7000);
    mLocationRequest.setSmallestDisplacement(1);

    mGoogleApiClient = new GoogleApiClient.Builder(this)
            .addConnectionCallbacks(this)
            .addOnConnectionFailedListener(this)
            .addApi(LocationServices.API)
            .build();

    mLocationManager = (LocationManager) getSystemService(LOCATION_SERVICE);
    tv1 = (TextView) findViewById(R.id.tv1);
    tv2 = (TextView) findViewById(R.id.tv2);


@Override
public void onConnected(@Nullable Bundle bundle) 

    Log.d("abc", "def");

    if (ActivityCompat.checkSelfPermission(this, android.Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED
            && ActivityCompat.checkSelfPermission(this, android.Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) 
        // TODO: Consider calling
        //    ActivityCompat#requestPermissions
        // here to request the missing permissions, and then overriding
        //   public void onRequestPermissionsResult(int requestCode, String[] permissions,
        //                                          int[] grantResults)
        // to handle the case where the user grants the permission. See the documentation
        // for ActivityCompat#requestPermissions for more details.
        return;
    
    Log.d("ghi", "jkl");

    LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient, mLocationRequest, this);

    Log.d("connected", String.valueOf(mGoogleApiClient.isConnected()));

   /* if (mLocation != null) 
        tv1.setText(String.valueOf(mLocation.getLatitude()));
        tv2.setText(String.valueOf(mLocation.getLongitude()));
     else
        Toast.makeText(this, "mLocation is null", Toast.LENGTH_SHORT).show();*/


@Override
public void onConnectionSuspended(int i) 



@Override
public void onConnectionFailed(@NonNull ConnectionResult connectionResult) 



@Override
protected void onStart() 

    mGoogleApiClient.connect();
    super.onStart();


@Override
protected void onStop() 

    if (mGoogleApiClient.isConnected())
        mGoogleApiClient.disconnect();
    super.onStop();


@Override
public void onLocationChanged(Location location) 

    if (ActivityCompat.checkSelfPermission(this, android.Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, android.Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) 
        // TODO: Consider calling
        //    ActivityCompat#requestPermissions
        // here to request the missing permissions, and then overriding
        //   public void onRequestPermissionsResult(int requestCode, String[] permissions,
        //                                          int[] grantResults)
        // to handle the case where the user grants the permission. See the documentation
        // for ActivityCompat#requestPermissions for more details.
        return;
    

    Log.d("mno",String.valueOf(mGoogleApiClient.isConnected()));

if (location != null)
    
        tv1.setText(String.valueOf(location.getLatitude()));
        tv2.setText(String.valueOf(location.getLongitude()));
        Toast.makeText(this, location.getLatitude()+" "+location.getLongitude(), Toast.LENGTH_SHORT).show();
    
    else
        Toast.makeText(this, "location is null", Toast.LENGTH_SHORT).show();


【讨论】:

你不认为我已经尝试了所有可能的位置设置组合吗?【参考方案13】:

30 分钟前遇到类似问题,代码在新模拟器之前运行。 更改模拟器的 lat lng 后,它又开始工作了

【讨论】:

【参考方案14】:

我刚刚发现,也许它会对你们中的一些人有所帮助。我从 getLastLocation() 得到空值,事实证明这是因为我试图在仅打开 GPS 的情况下获取位置,但 显然你还必须打开 Wi-Fi(即使未连接到任何网络)。 我想知道这是否是我的设备故障(三星平板电脑)......我正在深入研究这个话题,但目前还没有发现。我将感谢任何人分享有关此问题的更多知识。

【讨论】:

以上是关于为啥 FusedLocationApi.getLastLocation 为空的主要内容,如果未能解决你的问题,请参考以下文章

为啥 DataGridView 上的 DoubleBuffered 属性默认为 false,为啥它受到保护?

为啥需要softmax函数?为啥不简单归一化?

为啥 g++ 需要 libstdc++.a?为啥不是默认值?

为啥或为啥不在 C++ 中使用 memset? [关闭]

为啥临时变量需要更改数组元素以及为啥需要在最后取消设置?

为啥 CAP 定理中的 RDBMS 分区不能容忍,为啥它可用?