Android 永远不会调用OnLocationChanged回调

Android 永远不会调用OnLocationChanged回调,android,geolocation,locationmanager,Android,Geolocation,Locationmanager,我正在尝试使用LocationManager获取用户的当前位置。我做了很多研究,似乎找不到有同样问题的人。OnLocationChanged回调似乎从未被调用。下面是我的各种代码和日志 protected LocationListener locationListener; protected LocationManager locationManager; protected Context context; 我的OnCreate()方法 @Override public void onCr

我正在尝试使用
LocationManager
获取用户的当前位置。我做了很多研究,似乎找不到有同样问题的人。
OnLocationChanged
回调似乎从未被调用。下面是我的各种代码和日志

protected LocationListener locationListener;
protected LocationManager locationManager;
protected Context context;
我的
OnCreate()
方法

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    Log.v(TAG, "IN ON CREATE");

    this.context = getActivity();

    registerLocationUpdates();
}
void registerLocationUpdates() {
    Criteria criteria = new Criteria();
    criteria.setAccuracy(Criteria.ACCURACY_LOW);
    criteria.setPowerRequirement(Criteria.POWER_LOW);
    criteria.setAltitudeRequired(false);
    criteria.setBearingRequired(false);

    locationManager = (LocationManager)getActivity().getSystemService(LOCATION_SERVICE);

    provider = locationManager.getBestProvider(criteria, true);

    // Cant get a hold of provider
    if (provider == null) {
        Log.v(TAG, "Provider is null");
        showNoProvider();
        return;
    } else {
        Log.v(TAG, "Provider: " + provider);
    }

    locationListener = new MyLocationListener();

    locationManager.requestLocationUpdates(provider, 1L, 1f, locationListener);

    // connect to the GPS location service
    Location oldLocation = locationManager.getLastKnownLocation(provider);

    if (oldLocation != null)  {
        Log.v(TAG, "Got Old location");
        latitude = Double.toString(oldLocation.getLatitude());
        longitude = Double.toString(oldLocation.getLongitude());
        waitingForLocationUpdate = false;
        getNearbyStores();
    } else {
        Log.v(TAG, "NO Last Location found");
    }
}
我的
注册表位置更新
方法

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    Log.v(TAG, "IN ON CREATE");

    this.context = getActivity();

    registerLocationUpdates();
}
void registerLocationUpdates() {
    Criteria criteria = new Criteria();
    criteria.setAccuracy(Criteria.ACCURACY_LOW);
    criteria.setPowerRequirement(Criteria.POWER_LOW);
    criteria.setAltitudeRequired(false);
    criteria.setBearingRequired(false);

    locationManager = (LocationManager)getActivity().getSystemService(LOCATION_SERVICE);

    provider = locationManager.getBestProvider(criteria, true);

    // Cant get a hold of provider
    if (provider == null) {
        Log.v(TAG, "Provider is null");
        showNoProvider();
        return;
    } else {
        Log.v(TAG, "Provider: " + provider);
    }

    locationListener = new MyLocationListener();

    locationManager.requestLocationUpdates(provider, 1L, 1f, locationListener);

    // connect to the GPS location service
    Location oldLocation = locationManager.getLastKnownLocation(provider);

    if (oldLocation != null)  {
        Log.v(TAG, "Got Old location");
        latitude = Double.toString(oldLocation.getLatitude());
        longitude = Double.toString(oldLocation.getLongitude());
        waitingForLocationUpdate = false;
        getNearbyStores();
    } else {
        Log.v(TAG, "NO Last Location found");
    }
}
我的
LocationListener

private class MyLocationListener implements LocationListener {

    public void onLocationChanged(Location location) {
        latitude = Double.toString(location.getLatitude());
        longitude = Double.toString(location.getLongitude());

        Log.v(TAG, "IN ON LOCATION CHANGE");

        if (waitingForLocationUpdate) {
            getNearbyStores();
            waitingForLocationUpdate = false;
        }

        locationManager.removeUpdates(this);
    }

    public void onStatusChanged(String s, int i, Bundle bundle) {
        Log.v(TAG, "Status changed: " + s);
    }

    public void onProviderEnabled(String s) {
        Log.e(TAG, "PROVIDER DISABLED: " + s);
    }

    public void onProviderDisabled(String s) {
        Log.e(TAG, "PROVIDER DISABLED: " + s);
    }
}
我在AndroidManifest中的权限

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

而logcat中的android SDK位置部分也在不断重复。我已经尝试了我能想到的一切,在谷歌和stackoverflow上看到的一切。Als作为旁注,我已经能够使用API 9中提供的
requestSingleUpdate
并按照指南在2.3设备上运行,但我需要它使用旧SDK在2.1或2.2及更高版本上运行。因此,如果你有任何提示或想知道更多,请让我知道。提前感谢。

看起来您的设置应该可以正常工作,因为它不能正常工作,为了解决问题,我会尽量简化您的示例。我会让你的要求看起来像

requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, locationListener);
requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 0, 0, locationListener);
这样您就可以获得所有可能的更新。并注释掉关于获取最后已知位置的部分。现在还不需要

然后在
onLocationChanged()
中,只需

Log.v(TAG, "IN ON LOCATION CHANGE, lat=" + latitude + ", lon=" + longitude);

把剩下的注释掉,这样你就能让你的听众保持活跃。这将为您提供真实设备上的更新流。在emulator上,您需要使用DDMS,并且每次按send时都会得到一次GPS更新。

正如Steve Blackwell所写,您的设置很好。你可以尝试的是了解你是否100%拥有GPS固定信号!我已经安装了一个nice,它将显示您是否有修复程序,您连接到了哪些卫星,以及连接强度如何。 这就是我的OnLocationChanged()从未调用的原因。。我试着在大楼里运行它:\


祝你好运

我也面临同样的问题。我将getLastKnownLocation设置为null。当我在设备中重新启动设备和位置服务时,问题已得到解决。

更换

LocationManager.GPS\u提供程序

LocationManager.NETWORK\u提供程序

        locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER,
                MIN_TIME_BW_UPDATES,
                MIN_DISTANCE_CHANGE_FOR_UPDATES, MapFragment.this);
解决了我的问题

下面是我的位置管理器的代码片段

 LocationManager locationManager = (LocationManager) getActivity().getSystemService(LOCATION_SERVICE);
//检查位置权限,棉花糖及以上

        if (ActivityCompat.checkSelfPermission(getActivity(), Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED
                && ActivityCompat.checkSelfPermission(getActivity(), 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.

            Toast.makeText(getActivity(), "Not Enough Permission", Toast.LENGTH_SHORT).show();
            return;
        }
//获取要开始的当前位置

        Location myLocation = locationManager.getLastKnownLocation(LocationManager.PASSIVE_PROVIDER);

        currentLatitude = myLocation.getLatitude();
        currentLongitude = myLocation.getLongitude();
//使用LocationManager.NETWORK\u提供程序请求位置更新

        locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER,
                MIN_TIME_BW_UPDATES,
                MIN_DISTANCE_CHANGE_FOR_UPDATES, MapFragment.this);

我也经历过类似的问题。我有权限,正确请求服务,但没有更新。事实证明,我所要做的只是等待。当我在互联网上搜索这个问题时,我让应用程序运行,几分钟后它才开始接收更新。然后,即使当我关闭应用程序并再次运行它时,更新也会立即出现——我猜这是一个系统问题,一些优化,可能是因为设备根本没有移动(顺便说一句,它不是什么糟糕的设备,它是像素).

当设备处于低功耗或使用省电模式时,GPS提供商将禁用,在这种情况下,我们无法接收
onLocationChanged

GPS提供商如果您呆在房子或建筑物内,几乎不会返回该位置(仅在室外工作良好)

因此,在我的应用程序中,我将同时使用
GPS\u提供商
NETWORK\u提供商
来接收
onLocationChanged()
更好

要向GPS提供商请求位置更新,请使用GPS\U提供商 而不是网络供应商。您还可以请求位置更新 通过呼叫GPS和网络位置提供商 requestLocationUpdates()两次,一次用于网络\u提供程序,一次用于 全球定位系统供应商


如果您正在尝试使用NETWORK_PROVIDER,则很难测试:

  • 在Emulator上:从不工作
  • 在真实设备上:只有getLastKnownLocation()起作用,要接收onLocationChanged(),您必须使用移动数据并外出,否则可能会丢失手机
我想原因是它只是网络提供商的位置,而不是您的设备本身,而且网络提供商从不移动,因此onLocationChanged()从不调用。只有在移动数据和wifi之间切换时才会发生这种情况,反之亦然。如果我错了,请纠正我

因此,我建议在考虑性能和电池使用之前,使用GPS_提供商进行试验。它在模拟器和真实设备上都能很好地工作。关于最佳做法:


我花了好几个小时才使用网络提供商进行测试,没有任何结果,所以希望我的建议能有所帮助。

在我的真实设备(M,应用程序的targetSDK 23)上,我也遇到了同样的问题(onLocationChanged()从未使用网络提供商调用),直到我重新启动它

正如潘文林回答的那样,这可能是因为你在一幢大楼里。 有关于如何为模拟器模拟GPS的说明。 此外,还有一款模拟GPS数据的应用程序

LocationManager=(LocationManager)getSystemService(Context.LOCATION\u服务);
LocationManager manager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
if (manager != null) {
        List<String> providers = manager.getAllProviders();
        for (String provider : providers) {
           manager.requestLocationUpdates(provider, TIME_BW_UP, DISTANCE_BW_UP, locationListener);
        }
}
if(manager!=null){ List providers=manager.getAllProviders(); for(字符串提供程序:提供程序){ manager.requestLocationUpdate(提供程序、时间、距离、位置侦听器); } }
很抱歉打断了这么一个老话题,但这对其他一些人来说可能很方便,因为这个问题在谷歌搜索中排名相对较高

我有一个类似的问题,onlocationchanged没有被解雇,但是我没有发现我的代码有任何错误。在尝试了各种组合之后,我意识到问题的根本原因是我在服务中注册了侦听器

该服务是一个前台服务,所以基于谷歌的,应该工作,它没有

将初始化包装到方法中,并调用me
protected void onCreate(Bundle savedInstanceState) {
    //...
    final LocationManager manager = (LocationManager) getSystemService( Context.LOCATION_SERVICE );

    if ( !manager.isProviderEnabled( LocationManager.GPS_PROVIDER ) ) {
        buildAlertMessageNoGps();
    }
}

private void buildAlertMessageNoGps() {
    final AlertDialog.Builder builder = new AlertDialog.Builder(this);
    builder.setMessage("Your GPS seems to be disabled, do you want to enable it?")
            .setCancelable(false)
            .setPositiveButton("Yes", new DialogInterface.OnClickListener() {
                public void onClick(@SuppressWarnings("unused") final DialogInterface dialog, @SuppressWarnings("unused") final int id) {
                    startActivity(new Intent(android.provider.Settings.ACTION_LOCATION_SOURCE_SETTINGS));
                }
            })
            .setNegativeButton("No", new DialogInterface.OnClickListener() {
                public void onClick(final DialogInterface dialog, @SuppressWarnings("unused") final int id) {
                    dialog.cancel();
                }
            });
    final AlertDialog alert = builder.create();
    alert.show();
}
val intent = Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS)
startActivity(intent)