【问题标题】:Android requestLocationUpdates with GPS nullAndroid requestLocationUpdates GPS null
【发布时间】:2017-10-15 19:09:24
【问题描述】:
private void getLocation(){
    locationManager = (LocationManager) getContext().getSystemService(Context.LOCATION_SERVICE);
    List<String> providers = locationManager.getAllProviders();
    for (String provider : providers) {
        Log.e("GPS_provider: ", provider);
    }
    Criteria criteria = new Criteria();
    bestProvider = locationManager.getBestProvider(criteria, false);
    Log.e("Best_provider: ", bestProvider);
    locationListener = new LocationListener() {
        public void onLocationChanged(Location location) {
            // Called when a new location is found by the network location provider.
            Log.e("Loc_changed", ""+ location.getLatitude() + location.getLongitude());
            mLocation = location;
        }

        public void onStatusChanged(String provider, int status, Bundle extras) {}

        public void onProviderEnabled(String provider) {
            Log.e("Provider_enabled:", provider);
        }

        public void onProviderDisabled(String provider) {
            Log.e("Provider_disabled:", provider);

        }
    };
    // Register the listener with the Location Manager to receive location updates
    try {
        locationManager.requestLocationUpdates(bestProvider, 0, 0, locationListener);
        mLocation = locationManager.getLastKnownLocation(bestProvider);
        if (mLocation == null){
            mLocation = locationManager.getLastKnownLocation(LocationManager.NETWORK_PROVIDER);
            Log.e("GPS network", "true");
        }
    } catch (SecurityException e){
        Log.e("GPS problem", "GPS problem "+e.getMessage());
    }
}

我正在尝试在执行 HTTP GET 检索我的记录之前读取位置:

private void loadBusinesses(){
    gpsMsg.setVisibility(View.INVISIBLE);
    getLocation();
    currentView = GEOVIEW;
    businessesList.nextUrl = "null";
    if (!businessesList.isEmpty()){
        Log.e("businessList ","not empty");
        businessesList.clear();
        notifyAdapter();
    }

    Double latitude;
    Double longitude;
    try{
        latitude = mLocation.getLatitude();
        longitude = mLocation.getLongitude();
    } catch (NullPointerException e){
        Log.e("GPS", "Location unavailable");
        gpsMsg.setVisibility(View.VISIBLE);
        swipeContainer.setRefreshing(false);
        return;
    }

}

即使我检查 GPS 是否打开,当我尝试使用 GPS 位置时,我总是会得到空值,然后它会从 NETWORK 获取位置。 出于这个原因,我尝试将 GPS 设置设置为“仅 GPS”,但我得到 NULL,所以没有位置。 我阅读了所有其他帖子,但我一直在 GPS 上取零。我正在使用 USB Debug 在真实设备上进行仿真。

有什么想法吗?

【问题讨论】:

    标签: java android android-asynctask android-location android-gps


    【解决方案1】:

    我相信您对 LocationManager 的工作方式的解释是错误的。

    当您致电locationManager.requestLocationUpdates(bestProvider, 0, 0, locationListener) 时,您只是在注册以接收位置更新,这通常需要一些时间才能发生(并且可能永远不会发生,正如 CommonsWare 指出的那样)。此调用不会立即为您提供更新的位置,因此,在下一行代码中,当您调用getLastKnownLocation() 时,接收null 是正常行为。

    也就是说,我认为处理您的情况的最佳方法是:

    1 - 首先:检查 getLastKnownLocation() 是否返回 null (如果所选的 LocationProvider 已经从您的应用程序甚至另一个应用程序中获得了最近的位置,它会在这里为您返回它。但请注意:这个位置可能是非常过时!)。

    2 - 如果 getLastKnownLocation() 返回 null,那么您将别无选择,只能请求一个全新的位置并等待它到达,这将在方法 onLocationChanged 中发生位置监听器。因此,要做到这一点,您有两个选择:(a) 调用 requestSingleUpdate(),它会只为您返回一个更新的位置,或者 (b) 调用 requestLocationUpdates(),它将注册locationManager 接收定期位置更新(并且会消耗更多电池)。

    3 - 在这两个选项中,当您收到位置更新时,LocationListener 中的方法 onLocationChanged 将被调用,然后您可以从此方法调用您的 loadBusinesses,并收到全新的位置。

    希望这很清楚;)

    ----- 编辑-----

    在调用requestSingleUpdaterequestLocationUpdates 之前,您还应该在运行时请求位置权限。为此,请使用此 sn-p:

    if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
        // If permission is not granted, request it from user. When user responds, your activity will call method "onRequestPermissionResult", which you should override
        ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.ACCESS_FINE_LOCATION, Manifest.permission.ACCESS_COARSE_LOCATION}, 1);
    } else {
        locationManager.requestSingleUpdate(bestProvider, locationListener, null)
    }
    

    如果之前没有授予权限,系统会提示用户授予(或不授予)权限。因此,您还应该在您的活动中@Override 方法onRequestPermissionResult,以检查用户是否授予权限,然后正确响应。这是您应该覆盖的方法:

    @Override
    public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) {
        switch (requestCode) {
            case 1:
                if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                    // PERMISSION WAS GRANTED
                } else {
                    // USER DID NOT GRANT PERMISSION
                }
                break;
        }
    }
    

    【讨论】:

    • 我这样使用你的建议:locationManager.requestSingleUpdate(bestProvider, locListen, null); 我的 locListen 有:@Override public void onLocationChanged(Location location) { Log.e("Single_loc", location.getLongitude()+" "+location.getLatitude()); } 问题是,如果我使用模拟器,我必须从菜单中发送位置,然后读取位置,但是如果我使用真实的设备,它什么都不做,它不会投射 onLocationChanged、onStatusChanged、onProviderEnabled 和 onProviderDisabled。
    • 我也尝试使用谷歌地图,即使我在室内也能完美运行。
    • 您是否请求访问设备位置的权限?您应该在 AndroidManifest 中通过添加权限 ACCESS_COARSE_LOCATIONACCESS_FINE_LOCATION 来执行此操作。此外,从 Android 6.0 开始,您必须在运行时请求此权限,就在调用 requestSingleUpdate 之前。在这里阅读:developer.android.com/training/permissions/requesting.html
    • 我编辑了我的答案,包括 sn-ps 用于在运行时请求位置权限,如果是这样的话。
    【解决方案2】:

    getLastKnownLocation() 的问题在于,如果您更改设置中的位置提供程序、重新启动设备或在您的设备上打开和关闭位置服务,最后一个已知位置将被清除并返回 null。最重要的是,如果返回一个位置点,它可能太旧以至于它可能无关紧要。 getLastKnownLocation() 函数应该用作提示。

    关于您的评论说您在室内使用 GPS 时一无所获,但 Google 地图仍然有效... Google 地图使用 FusedLocationProviderApi,它同时使用 GPS 和网络为您提供当时的最佳位置。如果您只在您的设备上使用 GPS,并打开 Google 地图,您会看到它给您一个坏点(灰点),或者根本没有点。

    我建议您使用Google's Fused Location 提供程序来满足您的位置需求,因为它可以节省电池电量,在您丢失 GPS 时提供可靠的回退,并且它有自己的最后一个已知位置功能,似乎与LocationManager

    【讨论】:

      【解决方案3】:

      getLastKnownLocation() 经常返回null。这是完全正常的。你只用getLastKnownLocation():

      • 作为一种优化,以避免必须等待位置修复,或
      • 如果您可以在没有位置数据的情况下生活

      否则,您需要推迟您的 HTTP GET 请求,直到您在onLocationChanged() 中获得给您的位置。请记住,您可能永远不会获得位置修复。

      LocationManager 的正确使用在the documentation 中有介绍。

      【讨论】:

        猜你喜欢
        • 2013-06-14
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-06-29
        • 2021-04-18
        • 1970-01-01
        • 1970-01-01
        • 2011-07-30
        相关资源
        最近更新 更多