OnLocationChanged 回调永远不会被调用

发布于 2024-12-29 03:12:27 字数 7442 浏览 2 评论 0 原文

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

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();
}

我的 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

01-25 09:43:10.963: VERBOSE/NearbyListFragment(3060): IN ON CREATE
01-25 09:43:10.963: VERBOSE/LocationManagerService(1329): getProviders
01-25 09:43:10.963: VERBOSE/LocationManagerService(1329): getProviders
01-25 09:43:10.973: VERBOSE/LocationManagerService(1329): getProviders
01-25 09:43:10.983: VERBOSE/NearbyListFragment(3060): Provider: gps
01-25 09:43:10.983: DEBUG/LocationManager(3060): requestLocationUpdates: provider = gps, listener = co.fusionweb.dealsplus.app.NearbyItems$NearbyListFragment$MyLocationListener@46ef4680
01-25 09:43:10.983: DEBUG/GpsLocationProvider(1329): setMinTime 1
01-25 09:43:10.983: VERBOSE/NearbyListFragment(3060): NO Last Location found
01-25 09:43:10.983: VERBOSE/LocationManagerService(1329): _requestLocationUpdates: listener = Receiver{47421e68 Listener android.os.BinderProxy@47421a68}
01-25 09:43:11.003: VERBOSE/countingFragment(3060): IN ON CREATE VIEW
01-25 09:43:11.003: WARN/GpsLocationProvider(1329): Duplicate add listener for co.fusionweb.dealsplus
01-25 09:43:11.013: VERBOSE/ScrollListener(3060): In Constructor
01-25 09:43:11.013: VERBOSE/ScrollListener(3060): Scrolling
01-25 09:43:11.033: DEBUG/GpsLocationProvider(1329): startNavigating
01-25 09:43:11.043: DEBUG/lib_locapi(1329): loc_eng_set_qos_time_out(standalone = 60, agps = 89)
01-25 09:43:11.043: DEBUG/lib_locapi(1329): loc_eng_set_qos_accuracy(accuracy = 50)
01-25 09:43:11.043: VERBOSE/lib_locapi(1329): persist.radio.agps.mode: []
01-25 09:43:11.043: DEBUG/lib_locapi(1329): loc_eng_set_position mode, client = 1, interval = 1, mode = 1
01-25 09:43:11.043: VERBOSE/lib_locapi(1329): loc_eng_ioctl called: client = 1, ioctl_type = 2
01-25 09:43:11.043: VERBOSE/locapi_rpc_glue(1329): loc_ioctl
01-25 09:43:11.043: DEBUG/RPC(1329): written RPC packet size: [96]
01-25 09:43:11.043: DEBUG/RPC(1329): read RPC packet
01-25 09:43:11.043: DEBUG/RPC(1329): read RPC packet size: [28]
01-25 09:43:11.043: VERBOSE/locapi_rpc_glue(1329): loc_api_sync_ioctl: select_id = 0, loc_ioctl returned 0
01-25 09:43:11.043: DEBUG/RPC(1329): read RPC packet
01-25 09:43:11.043: DEBUG/RPC(1329): read RPC packet size: [80]
01-25 09:43:11.043: VERBOSE/locapi_rpc_glue(1329): Callback received: 80 (cb_id=0x5310000 handle=1)
01-25 09:43:11.043: DEBUG/RPC(1329): written RPC packet size: [28]
01-25 09:43:11.043: VERBOSE/lib_locapi(1329): loc_eng_ioctl result: client = 1, ioctl_type = 2, SUCCESS
01-25 09:43:11.043: DEBUG/lib_locapi(1329): loc_eng_start
01-25 09:43:11.043: DEBUG/locapi_rpc_glue(1329): loc_start_fix
01-25 09:43:11.043: DEBUG/RPC(1329): written RPC packet size: [44]
01-25 09:43:11.043: DEBUG/RPC(1329): read RPC packet
01-25 09:43:11.053: DEBUG/RPC(1329): read RPC packet size: [28]
01-25 09:43:11.103: DEBUG/RPC(1329): read RPC packet
01-25 09:43:11.103: DEBUG/RPC(1329): read RPC packet size: [80]
01-25 09:43:11.113: VERBOSE/locapi_rpc_glue(1329): Callback received: 100 (cb_id=0x5310000 handle=1)
01-25 09:43:11.113: VERBOSE/lib_locapi(1329): process_deferred_action: pthread_cond_wait returned
01-25 09:43:11.113: DEBUG/lib_locapi(1329): loc_eng_report_status: GPS_STATUS_SESSION_BEGIN
01-25 09:43:11.113: DEBUG/lib_locapi(1329): loc_eng_report_status: update status
01-25 09:43:11.113: VERBOSE/GpsLocationProvider(1329): reportStatus status: 1
01-25 09:43:11.113: DEBUG/GpsLocationProvider(1329): Acquiring wakelock
01-25 09:43:11.123: DEBUG/RPC(1329): written RPC packet size: [28]
01-25 09:43:11.183: DEBUG/PowerManagerService(1329): New lightsensor value:40, lcdValue:77
01-25 09:43:11.273: DEBUG/RPC(1329): read RPC packet
01-25 09:43:11.273: DEBUG/RPC(1329): read RPC packet size: [80]
01-25 09:43:11.273: VERBOSE/locapi_rpc_glue(1329): Callback received: 100 (cb_id=0x5310000 handle=1)
01-25 09:43:11.273: VERBOSE/lib_locapi(1329): process_deferred_action: pthread_cond_wait returned
01-25 09:43:11.273: DEBUG/lib_locapi(1329): loc_eng_report_status: GPS_STATUS_ENGINE_ON
01-25 09:43:11.273: DEBUG/lib_locapi(1329): loc_eng_report_status: update status
01-25 09:43:11.273: VERBOSE/GpsLocationProvider(1329): reportStatus status: 3

以及 android SDK 位置logcat 的某些部分不断重复。我已经尝试了所有我能想到的以及在 google 和 stackoverflow 上看到的东西。另外,作为旁注,我已经能够使用 API 9 中提供的 requestSingleUpdate 并按照指南 深入了解位置,但我需要它来工作使用旧 SDK 的 2.1 或 2.2 及更高版本。因此,如果您有任何提示或想了解更多信息,请告诉我。

I am trying to get the users current location using the LocationManager. I have done a lot of research and can't seem to find anyone with the same problem. The OnLocationChanged callback never seems to be called. Below is my various code and the logcat.

protected LocationListener locationListener;
protected LocationManager locationManager;
protected Context context;

My OnCreate() method

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

    this.context = getActivity();

    registerLocationUpdates();
}

My registerLocationUpdates method

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");
    }
}

My 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);
    }
}

My permissions in the 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" />

And finally the logcat after I run my app

01-25 09:43:10.963: VERBOSE/NearbyListFragment(3060): IN ON CREATE
01-25 09:43:10.963: VERBOSE/LocationManagerService(1329): getProviders
01-25 09:43:10.963: VERBOSE/LocationManagerService(1329): getProviders
01-25 09:43:10.973: VERBOSE/LocationManagerService(1329): getProviders
01-25 09:43:10.983: VERBOSE/NearbyListFragment(3060): Provider: gps
01-25 09:43:10.983: DEBUG/LocationManager(3060): requestLocationUpdates: provider = gps, listener = co.fusionweb.dealsplus.app.NearbyItems$NearbyListFragment$MyLocationListener@46ef4680
01-25 09:43:10.983: DEBUG/GpsLocationProvider(1329): setMinTime 1
01-25 09:43:10.983: VERBOSE/NearbyListFragment(3060): NO Last Location found
01-25 09:43:10.983: VERBOSE/LocationManagerService(1329): _requestLocationUpdates: listener = Receiver{47421e68 Listener android.os.BinderProxy@47421a68}
01-25 09:43:11.003: VERBOSE/countingFragment(3060): IN ON CREATE VIEW
01-25 09:43:11.003: WARN/GpsLocationProvider(1329): Duplicate add listener for co.fusionweb.dealsplus
01-25 09:43:11.013: VERBOSE/ScrollListener(3060): In Constructor
01-25 09:43:11.013: VERBOSE/ScrollListener(3060): Scrolling
01-25 09:43:11.033: DEBUG/GpsLocationProvider(1329): startNavigating
01-25 09:43:11.043: DEBUG/lib_locapi(1329): loc_eng_set_qos_time_out(standalone = 60, agps = 89)
01-25 09:43:11.043: DEBUG/lib_locapi(1329): loc_eng_set_qos_accuracy(accuracy = 50)
01-25 09:43:11.043: VERBOSE/lib_locapi(1329): persist.radio.agps.mode: []
01-25 09:43:11.043: DEBUG/lib_locapi(1329): loc_eng_set_position mode, client = 1, interval = 1, mode = 1
01-25 09:43:11.043: VERBOSE/lib_locapi(1329): loc_eng_ioctl called: client = 1, ioctl_type = 2
01-25 09:43:11.043: VERBOSE/locapi_rpc_glue(1329): loc_ioctl
01-25 09:43:11.043: DEBUG/RPC(1329): written RPC packet size: [96]
01-25 09:43:11.043: DEBUG/RPC(1329): read RPC packet
01-25 09:43:11.043: DEBUG/RPC(1329): read RPC packet size: [28]
01-25 09:43:11.043: VERBOSE/locapi_rpc_glue(1329): loc_api_sync_ioctl: select_id = 0, loc_ioctl returned 0
01-25 09:43:11.043: DEBUG/RPC(1329): read RPC packet
01-25 09:43:11.043: DEBUG/RPC(1329): read RPC packet size: [80]
01-25 09:43:11.043: VERBOSE/locapi_rpc_glue(1329): Callback received: 80 (cb_id=0x5310000 handle=1)
01-25 09:43:11.043: DEBUG/RPC(1329): written RPC packet size: [28]
01-25 09:43:11.043: VERBOSE/lib_locapi(1329): loc_eng_ioctl result: client = 1, ioctl_type = 2, SUCCESS
01-25 09:43:11.043: DEBUG/lib_locapi(1329): loc_eng_start
01-25 09:43:11.043: DEBUG/locapi_rpc_glue(1329): loc_start_fix
01-25 09:43:11.043: DEBUG/RPC(1329): written RPC packet size: [44]
01-25 09:43:11.043: DEBUG/RPC(1329): read RPC packet
01-25 09:43:11.053: DEBUG/RPC(1329): read RPC packet size: [28]
01-25 09:43:11.103: DEBUG/RPC(1329): read RPC packet
01-25 09:43:11.103: DEBUG/RPC(1329): read RPC packet size: [80]
01-25 09:43:11.113: VERBOSE/locapi_rpc_glue(1329): Callback received: 100 (cb_id=0x5310000 handle=1)
01-25 09:43:11.113: VERBOSE/lib_locapi(1329): process_deferred_action: pthread_cond_wait returned
01-25 09:43:11.113: DEBUG/lib_locapi(1329): loc_eng_report_status: GPS_STATUS_SESSION_BEGIN
01-25 09:43:11.113: DEBUG/lib_locapi(1329): loc_eng_report_status: update status
01-25 09:43:11.113: VERBOSE/GpsLocationProvider(1329): reportStatus status: 1
01-25 09:43:11.113: DEBUG/GpsLocationProvider(1329): Acquiring wakelock
01-25 09:43:11.123: DEBUG/RPC(1329): written RPC packet size: [28]
01-25 09:43:11.183: DEBUG/PowerManagerService(1329): New lightsensor value:40, lcdValue:77
01-25 09:43:11.273: DEBUG/RPC(1329): read RPC packet
01-25 09:43:11.273: DEBUG/RPC(1329): read RPC packet size: [80]
01-25 09:43:11.273: VERBOSE/locapi_rpc_glue(1329): Callback received: 100 (cb_id=0x5310000 handle=1)
01-25 09:43:11.273: VERBOSE/lib_locapi(1329): process_deferred_action: pthread_cond_wait returned
01-25 09:43:11.273: DEBUG/lib_locapi(1329): loc_eng_report_status: GPS_STATUS_ENGINE_ON
01-25 09:43:11.273: DEBUG/lib_locapi(1329): loc_eng_report_status: update status
01-25 09:43:11.273: VERBOSE/GpsLocationProvider(1329): reportStatus status: 3

And the android SDK location parts of the logcat keep repeating them selves. I have tried everything that i can think of and have seen on google and stackoverflow. Als just as a side note i have been able to get it to work on a 2.3 device using the requestSingleUpdate which is available in API 9 and by following the guide A Deep Dive into Location but i need it to work on 2.1 or 2.2 and higher using the old SDK. SO if you have any hints or would like to know more please let me know.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(16

心不设防 2025-01-05 03:12:27

看来您的设置应该有效,因为它不起作用,我会让您的示例尽可能简单以便进行故障排除。我会让你的请求看起来像

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);

注释掉其余部分,以便让侦听器保持活动状态。这应该会为您提供真实设备上的更新流。在模拟器上,您需要使用 DDMS,并且每次按发送键时您都会收到一次 GPS 更新。

It looks like you setup should work, since it doesn't, I would make your example as simple as possible in order to troubleshoot. I would make your request look like

requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, locationListener);
requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 0, 0, locationListener);

This way you get ALL the updates possible. And comment out the part about getting the last known location. It's not needed yet.

Then in onLocationChanged(), just have

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

Comment out the rest so that you keep your listener active. This should give you a stream of updates on a real device. On the emulator, you'll need to use DDMS, and you'll get one GPS update each time you press send.

花间憩 2025-01-05 03:12:27

更换

LocationManager.GPS_PROVIDER

LocationManager.NETWORK_PROVIDER

解决了我的问题。

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

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

//检查位置权限、Marshmallow 及以上

        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_PROVIDER 请求位置更新

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

Replacing

LocationManager.GPS_PROVIDER

with

LocationManager.NETWORK_PROVIDER

solved my problem.

Here is code snippet of my location manager

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

//Check for Location permissions, Marshmallow and above

        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;
        }

//Get current location to start with

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

        currentLatitude = myLocation.getLatitude();
        currentLongitude = myLocation.getLongitude();

// Request location update using LocationManager.NETWORK_PROVIDER

        locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER,
                MIN_TIME_BW_UPDATES,
                MIN_DISTANCE_CHANGE_FOR_UPDATES, MapFragment.this);
青衫负雪 2025-01-05 03:12:27

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

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

因此,在我的应用程序中,我将使用 GPS_PROVIDERNETWORK_PROVIDER 来接收 onLocationChanged()< /代码>更好

https://developer.android.com/guide/topics/location/策略.html#更新

要向 GPS 提供商请求位置更新,请使用 GPS_PROVIDER
而不是 NETWORK_PROVIDER。您还可以请求位置更新
通过拨打 GPS 和网络位置提供商的电话
requestLocationUpdates() 两次 - 一次用于 NETWORK_PROVIDER,一次用于
GPS_PROVIDER。

GPS Provider will disable when device in low power or use power save mode then in that case we can not receive onLocationChanged

GPS Provider hardly ever return the location if you stay inside house or building (only work well in outdoor)

Therefore, in my app I will use both GPS_PROVIDER and NETWORK_PROVIDER to receive onLocationChanged() better

https://developer.android.com/guide/topics/location/strategies.html#Updates

To request location updates from the GPS provider, use GPS_PROVIDER
instead of NETWORK_PROVIDER. You can also request location updates
from both the GPS and the Network Location Provider by calling
requestLocationUpdates() twice—once for NETWORK_PROVIDER and once for
GPS_PROVIDER.

む无字情书 2025-01-05 03:12:27

正如史蒂夫·布莱克威尔(Steve Blackwell)所写,你的设置很好。您可以尝试了解自己是否 100% 有 GPS 固定信号!我已经安装了一个不错的 GPS 测试器应用程序(来自 Play 商店)< /a> 它将显示您是否已修复、您连接到哪些卫星以及连接强度是多少。
这就是我的 OnLocationChanged() 从未调用的原因。我尝试从建筑物内运行它:\

祝你好运!

As Steve Blackwell wrote, your setup is good. What you can try is to understand if you 100% have a GPS fixed signal! I have installed a nice GPS Tester application (from the play store) and it will show you if you have a fix or not and to which satellites you are connected and what is the connection strength.
This was the reason my OnLocationChanged() never called.. I tried running it from within a building :\

good luck!

东风软 2025-01-05 03:12:27

很抱歉撞到这么旧的线程,但这可能对其他人来说很方便,因为这个问题在谷歌搜索上排名相对较高。

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

该服务是前台服务,因此基于 Google 文档这应该有效,但没有!

将初始化包装在一个方法中,然后从创建或绑定到服务的活动中调用该方法解决了我的问题。

这是我在服务中的方法:

void start_gps_track(int i) {
        if (myCarLocationListener!=null) {
            if (i==1) //if start night
                myCarLocationListener.setNightstart(true);
            else if (i==2) //if start GPS
                myCarLocationListener.setLocationStart(true);
            return;
        }
        locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
        if ( locationManager.isProviderEnabled( LocationManager.GPS_PROVIDER ) ) {
            myCarLocationListener=new CarLocationListener(this,adjust_audio);
            if (i==1) //if start night
                myCarLocationListener.setNightstart(true);
            else if (i==2) //if start GPS
                myCarLocationListener.setLocationStart(true);
            try {
                locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 100, 0, myCarLocationListener);
                Log.d("HU","Registered location listener");
                Location lastlocation = locationManager.getLastKnownLocation(LocationManager.NETWORK_PROVIDER);
                if (lastlocation == null)
                    lastlocation = locationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER);
                if (lastlocation != null)
                    myCarLocationListener.onLocationChanged(lastlocation);
            }
            catch (SecurityException e){
                Log.e("HU-GPS","No permission to access Location");
            }
        }
        else
        {
            Log.e("HU-GPS","No GPS provider or no permission");
        }
    }

如果我从服务本身内部调用它,我将不会收到任何位置更新(再次注意服务是前台服务,它实际上绑定到当前正在运行的活动)。

但是,如果我从创建/绑定到服务的活动中调用此方法,如下所示,它可以正常工作:

@Override
public void onServiceConnected(ComponentName className,
                               IBinder service) {
    // We've bound to LocalService, cast the IBinder and get LocalService instance
    TransporterService.LocalBinder binder = (TransporterService.LocalBinder) service;
    mService = binder.getService();
    mService.updatePlayer(player.this);
    try {
        mService.start_gps_track(0);
    }
    catch (Exception e) {            //This should only happen if there is no GPS provider available, but it might happen quickly after boot when the device is not yet ready.
        mService.recheck_gps(0);
    }

    mBound = true;
  }

@Override
public void onServiceDisconnected(ComponentName arg0) {
    mBound = false;

}
};

希望这可以帮助其他遇到此问题的人。

Sorry for bumping such an old thread, but this might come handy to some others, since this question is ranking relatively high on google search.

I had a similar problem, the onlocationchanged wasn't getting fired, but I could not find anything wrong with my code. After trying all sorts of combination, I realised that the root cause of the problem was the fact that I was registering the listener in a service.

The service WAS a foreground service, so based on Google documentation that should work, it DID NOT!

Wrapping the initialisation in a method, and calling the method from the activity which created or bind to the service solved my problem.

This is my method in my service:

void start_gps_track(int i) {
        if (myCarLocationListener!=null) {
            if (i==1) //if start night
                myCarLocationListener.setNightstart(true);
            else if (i==2) //if start GPS
                myCarLocationListener.setLocationStart(true);
            return;
        }
        locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
        if ( locationManager.isProviderEnabled( LocationManager.GPS_PROVIDER ) ) {
            myCarLocationListener=new CarLocationListener(this,adjust_audio);
            if (i==1) //if start night
                myCarLocationListener.setNightstart(true);
            else if (i==2) //if start GPS
                myCarLocationListener.setLocationStart(true);
            try {
                locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 100, 0, myCarLocationListener);
                Log.d("HU","Registered location listener");
                Location lastlocation = locationManager.getLastKnownLocation(LocationManager.NETWORK_PROVIDER);
                if (lastlocation == null)
                    lastlocation = locationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER);
                if (lastlocation != null)
                    myCarLocationListener.onLocationChanged(lastlocation);
            }
            catch (SecurityException e){
                Log.e("HU-GPS","No permission to access Location");
            }
        }
        else
        {
            Log.e("HU-GPS","No GPS provider or no permission");
        }
    }

If I call this from within the Service itself I won't receive any Location Updates (again note service is a FOREGROUND service and it's actually binded to an activity which is currently running).

However if I call this method from the activity which created/bound to the service like below it works fine:

@Override
public void onServiceConnected(ComponentName className,
                               IBinder service) {
    // We've bound to LocalService, cast the IBinder and get LocalService instance
    TransporterService.LocalBinder binder = (TransporterService.LocalBinder) service;
    mService = binder.getService();
    mService.updatePlayer(player.this);
    try {
        mService.start_gps_track(0);
    }
    catch (Exception e) {            //This should only happen if there is no GPS provider available, but it might happen quickly after boot when the device is not yet ready.
        mService.recheck_gps(0);
    }

    mBound = true;
  }

@Override
public void onServiceDisconnected(ComponentName arg0) {
    mBound = false;

}
};

Hope this helps some others who come across this problem.

大姐,你呐 2025-01-05 03:12:27

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

I experienced similar issue. I had the permissions, requested for service correctly, but no update came. It turned out that all I had to do was simply wait. While I was searching for the issue on the internet, I had the application running and after few minutes it just started to receiving updates. Then even when I killed the app and run it again, the updates came instantaneously - I guess it is a system thing, some optimization, maybe due to the fact that device wasn't moving at all (btw. it is not some shitty device, it is Pixel).

蝶…霜飞 2025-01-05 03:12:27
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);
        }
}
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);
        }
}
我的黑色迷你裙 2025-01-05 03:12:27

我遇到了同样的问题。我得到的 getLastKnownLocation 为空。当我重新启动设备和设备中的位置服务时,问题得到解决。

I faced same issue. I was getting getLastKnownLocation as null. Issue is resolved when I restarted both the device and Location service in device.

困倦 2025-01-05 03:12:27

如果您尝试使用 NETWORK_PROVIDER,那么测试确实很困难:

  • 在模拟器上:永远不会
  • 在真实设备上工作:只有 getLastKnownLocation() 有效,要接收 onLocationChanged(),您必须使用移动数据并冒着丢失手机的风险外出来自强盗:P

我想原因是它只是网络提供商的位置而不是您的设备本身,并且网络提供商永远不会移动,因此 onLocationChanged() 永远不会调用。仅当在移动数据和 WiFi 之间切换时才可能发生这种情况,反之亦然。如果我错了,请纠正我。

所以我建议先使用GPS_PROVIDER进行实验,然后再考虑性能和电池使用情况。它在模拟器和真实设备上都能很好地工作。最佳实践:https://developer.android.com/guide/topics /location/strategies.html

我花了几个小时使用 NETWORK_PROVIDER 进行测试,但没有任何结果,所以希望我的建议有所帮助。

If you are trying with NETWORK_PROVIDER, it is really difficult to test:

  • on Emulator: never work
  • on Real Device: only getLastKnownLocation() works, to receive onLocationChanged(), you have to use mobile data and go outside with the risk of losing phone from robber :P

I guess the reason is that it just the location of network provider only not your device itself, and the network provider never move, so the onLocationChanged() never call. It might happen only when switching between mobile data and wifi and vice versa. Please correct me if I am wrong.

So I suggest to use GPS_PROVIDER to experiment before considering performance and battery usage. It works nicely on both emulators and real devices. For the best practice: https://developer.android.com/guide/topics/location/strategies.html

It took me several hours to test with NETWORK_PROVIDER without any results, so hopefully my suggestion helpful.

江挽川 2025-01-05 03:12:27

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

I had the same problem (onLocationChanged() never called with NETWORK_PROVIDER) on my real device (M, app's targetSDK 23) until I restarted it.

梦醒时光 2025-01-05 03:12:27

正如 Phan Van Linh 回答的那样,这可能是因为您在建筑物内。
此处有关于如何为模拟器模拟 GPS 的说明。
此外,还有应用模拟 GPS 数据。

As Phan Van Linh answered , it's probably because you are inside a building.
There are explanation here on how to mock GPS for the emulator.
Also, there is this app that mocks GPS data.

飘然心甜 2025-01-05 03:12:27

我有 2 台设备:Samsung Galaxy S4 (Android 5.0.1) 和 Vertex Win (Android 8.1)。

在三星上,一切正常且快速,找到 GPS 坐标,并调用 onLocationChanged

在优先级 PRIORITY_BALANCED_POWER_ACCURACY 的 Vertex 上,它可能首先与网络提供商交互,因此它通过 Wi-Fi 查找坐标。但它无法正确检测位置服务是否打开(一段时间后设备认为它已打开,而实际上它已关闭,并调用 LocationServices.getSettingsClient< 的 addOnSuccessListener 方法/code> 因此,我切换到了 PRIORITY_HIGH_ACCURACY 并得到了另一个惊喜,网络提供商已关闭,但没有调用 onLocationChanged,所以我 在建筑物内也无法接收到信号。

无法获取坐标。我从 Play Market 下载了 GPS 测试仪(按照 @Li3ro 的建议),发现卫星是可见的,但即使 独立地图无法接收坐标,但户外可以。因此,在我离开后,我可以在应用程序中找到我的坐标

。 href="https://stackoverflow.com/a/27828929/2914140">https://stackoverflow.com/a/27828929/2914140,其中提到了优先级和错误识别(经过一段时间后禁用 GPS)如果没有找到坐标,则为时间)。

I have 2 devices: Samsung Galaxy S4 (Android 5.0.1) and Vertex Win (Android 8.1).

On Samsung everything works right and fast, GPS coordinates are found, and onLocationChanged is called.

On Vertex in prioity PRIORITY_BALANCED_POWER_ACCURACY it probably interacts with network provider first, so it finds coordinates via Wi-Fi. But it can't detect right, whether location service is turned on (after some time the device thinks it is turned on, while it is off, and calls addOnSuccessListener method of LocationServices.getSettingsClient. So I switched to PRIORITY_HIGH_ACCURACY and got another surprise. Network provider turned off, but onLocationChanged wasn't called, so I couldn't get coordinates. I downloaded GPS tester (as @Li3ro advised) from Play Market and saw that sattelites are visible, but without fixed signal. I couldn't receive a signal inside a building.

Even standalone maps couldn't receive coordinates, but outdoor could. So, after I walked away, I could find my coordindinates in an application.

See also https://stackoverflow.com/a/27828929/2914140, where it is said about priorities and error recognition (disabling GPS after some time if no coordinsates found).

千寻… 2025-01-05 03:12:27

这应该是由于您的手机设置而发生的。在手机位置设置中,如果位置服务模式设置为仅 GPS,则 OnLocationChanged 回调会在有 GPS Fix 时调用。通过选择“使用 GPS、WI-FI 和移动网络”选项,将使用这三个提供商来确定位置。这将花费更少的时间来定位您的设备位置。
***访问位置服务的路径可以更改设备。
谢谢

This should be happen due to your phone settings. In phones Location settings, If the Location service Mode set to GPS only, then OnLocationChanged callback calls when there is GPS Fix. By selecting Use GPS, WI-FI And mobile networks options, location will be determine by using those three providers. This will take less time to locate your device location.
***Path to access to location services could be change device to device.
Thanks

心奴独伤 2025-01-05 03:12:27

当位置关闭时,这发生在我身上。不是应用程序的位置权限,而是 Android 设备本身的位置。请求用户激活 GPS 为我解决了这个问题:

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();
}

来自 此处

您可能还需要关闭 GPS,然后再次打开以触发对话框以提高位置准确性:

提高定位精度的对话框提示

This happened to me when the location was turned off. Not the location permission for the app, but the location for the android device itself. Requesting that the user activate the GPS fixed it for 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();
}

Solution from here.

You may also need to turn the GPS off and then on again to trigger a dialog to improve location accuracy:

Dialog prompting to improve location accuracy

老旧海报 2025-01-05 03:12:27

就我而言,即使编写了正确的代码,我也没有使用 client.requestLocationUpdates(locationRequest, this, it) 获取位置。
在手机中也启用了 GPS,

val intent = Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS)
startActivity(intent)

在花费时间切换模拟器、构建等之后,最终发现位置模式是“仅设备”,并且它没有在模拟器上提供结果。将其切换到“高精度”并开始工作。

In my case even after writing correct code, I did not get location using client.requestLocationUpdates(locationRequest, this, it).
In phone gps was enabled as well using

val intent = Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS)
startActivity(intent)

After spending time in switching emulators, builds, etc, finally figured out that Location mode was "Device Only" and it wasn't providing the result on emulator. Switched to it to "High accuracy" and it started working.

星光不落少年眉 2025-01-05 03:12:27

就我而言,GPS 被禁用。

所以我从设置中打开位置,效果很好

In my case the gps was disabled.

So I turned On Location from setting and it worked fine

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文