如何查看GPS接收器的当前状态?

nr1*_*nr1 88 gps android

如何查看GPS接收器的当前状态?我已经检查了这个LocationListener onStatusChanged方法,但不知怎的,这似乎不起作用,或者只是错误的可能性.

基本上我只需要知道屏幕顶部的GPS图标是否闪烁(没有实际修复)或固体(修复可用).

sou*_*ven 148

作为SpeedView的开发者:Android的GPS速度计,我必须尝试解决这个问题的所有可能的解决方案,所有这些都有相同的负面结果.让我们重申一下不起作用:

  1. onStatusChanged()没有被Eclair和Froyo调用.
  2. 当然,简单地计算所有可用的卫星是没用的.
  3. 检查usedInFix()中是否有任何卫星返回true也不是很有帮助.该系统明显失去了修复程序,但仍然报告仍然有几个sats在其中使用.

所以这是我找到的唯一可行的解​​决方案,也是我在我的应用中实际使用的解决方案.假设我们有这个实现GpsStatus.Listener的简单类:

private class MyGPSListener implements GpsStatus.Listener {
    public void onGpsStatusChanged(int event) {
        switch (event) {
            case GpsStatus.GPS_EVENT_SATELLITE_STATUS:
                if (mLastLocation != null)
                    isGPSFix = (SystemClock.elapsedRealtime() - mLastLocationMillis) < 3000;

                if (isGPSFix) { // A fix has been acquired.
                    // Do something.
                } else { // The fix has been lost.
                    // Do something.
                }

                break;
            case GpsStatus.GPS_EVENT_FIRST_FIX:
                // Do something.
                isGPSFix = true;

                break;
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

好的,现在在onLocationChanged()中我们添加以下内容:

@Override
public void onLocationChanged(Location location) {
    if (location == null) return;

    mLastLocationMillis = SystemClock.elapsedRealtime();

    // Do something.

    mLastLocation = location;
}
Run Code Online (Sandbox Code Playgroud)

就是这样.基本上,这就是完成所有工作的路线:

isGPSFix = (SystemClock.elapsedRealtime() - mLastLocationMillis) < 3000;
Run Code Online (Sandbox Code Playgroud)

您当然可以调整毫秒值,但我建议将其设置为3-5秒左右.

这实际上有效,虽然我没有看过绘制原生GPS图标的源代码,但这接近于复制其行为.希望这有助于某人.

  • 嗨,斯蒂芬,你能解释一下*为什么*isGPSFix有效.谢谢,尼克 (3认同)

小智 25

GPS图标似乎根据收到的广播意图改变其状态.您可以使用以下代码示例自行更改其状态:

通知已启用GPS:

Intent intent = new Intent("android.location.GPS_ENABLED_CHANGE");
intent.putExtra("enabled", true);
sendBroadcast(intent);
Run Code Online (Sandbox Code Playgroud)

通知GPS正在接收修复程序:

Intent intent = new Intent("android.location.GPS_FIX_CHANGE");
intent.putExtra("enabled", true);
sendBroadcast(intent);
Run Code Online (Sandbox Code Playgroud)

通知GPS不再接收修复程序:

Intent intent = new Intent("android.location.GPS_FIX_CHANGE");
intent.putExtra("enabled", false);
sendBroadcast(intent);
Run Code Online (Sandbox Code Playgroud)

通知GPS已被禁用:

Intent intent = new Intent("android.location.GPS_ENABLED_CHANGE");
intent.putExtra("enabled", false);
sendBroadcast(intent);
Run Code Online (Sandbox Code Playgroud)

将接收器注册到意图的示例代码:

// MyReceiver must extend BroadcastReceiver
MyReceiver receiver = new MyReceiver();
IntentFilter filter = new IntentFilter("android.location.GPS_ENABLED_CHANGE");
filter.addAction("android.location.GPS_FIX_CHANGE");
registerReceiver(receiver, filter);
Run Code Online (Sandbox Code Playgroud)

通过接收这些广播意图,您可以注意到GPS状态的变化.但是,只有在状态发生变化时才会通知您.因此,不可能使用这些意图来确定当前状态.


chi*_*ich 19

新成员很遗憾我无法发表评论或投票,但上面的Stephen Daye的帖子是我一直在寻求帮助的完全相同问题的完美解决方案.

对以下行的一个小改动:

isGPSFix = (SystemClock.elapsedRealtime() - mLastLocationMillis) < 3000;
Run Code Online (Sandbox Code Playgroud)

至:

isGPSFix = (SystemClock.elapsedRealtime() - mLastLocationMillis) < (GPS_UPDATE_INTERVAL * 2);
Run Code Online (Sandbox Code Playgroud)

基本上我正在建立一个慢节奏的游戏,我的更新间隔已经设置为5秒,一旦gps信号超出10秒,这是触发某些东西的正确时间.

欢呼队友,在找到你的帖子之前花了大约10个小时试图解决这个问题:)


Chr*_*Orr 14

好的,所以让我们尝试到目前为止所有答案和更新的组合,并执行以下操作:

GPS聆听者可能是这样的:

GpsStatus.Listener listener = new GpsStatus.Listener() {
    void onGpsStatusChanged(int event) {
        if (event == GPS_EVENT_SATELLITE_STATUS) {
            GpsStatus status = mLocManager.getGpsStatus(null);
            Iterable<GpsSatellite> sats = status.getSatellites();
            // Check number of satellites in list to determine fix state
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

关于何时以及提供GPS和卫星信息的API有点不清楚,但我认为一个想法是看看有多少卫星可用.如果它低于三,那么你就无法修复.如果它更多,那么你应该有一个修复.

尝试和错误可能是确定Android报告卫星信息的频率以及每个GpsSatellite对象包含的信息的方式.


Jus*_*ler 8

在Windows Mobile上使用GPS几年后,我意识到"丢失"GPS定位的概念可能是主观的.要简单地听GPS告诉你的内容,添加NMEAListener并解析句子将告诉你修复是否"有效".见http://www.gpsinformation.org/dale/nmea.htm#GGA.不幸的是,对于一些GPS,即使在"良好修复"区域的正常操作过程中,该值也会来回波动.

因此,另一种解决方案是将GPS位置的UTC时间与手机的时间(转换为UTC)进行比较.如果它们相隔一定的时差,则可以假设您丢失了GPS位置.


小智 7

在我的MSc项目上工作时遇到类似的问题,似乎Daye的答案在设备停留在静态位置时错误地报告了"无法修复".我已经修改了一点点解决方案,这似乎在静态位置对我来说很好.我不知道它会如何影响电池,因为它不是我主要关注的问题,但是这是我通过在修复超时时重新请求位置更新来实现的.

private class MyGPSListener implements GpsStatus.Listener {
    public void onGpsStatusChanged(int event) {
        switch (event) {
        case GpsStatus.GPS_EVENT_SATELLITE_STATUS:
            if (Global.getInstance().currentGPSLocation != null)
            {
                if((SystemClock.elapsedRealtime() - mLastLocationMillis) < 20000)
                {
                    if (!hasGPSFix) 
                        Log.i("GPS","Fix Acquired");
                    hasGPSFix = true;
                } 
                else
                {
                    if (hasGPSFix) 
                    {
                        Log.i("GPS","Fix Lost (expired)");
                        lm.requestLocationUpdates(LocationManager.GPS_PROVIDER, 2000, 10, locationListener);
                    }
                    hasGPSFix = false;
                }
            }
            break;
        case GpsStatus.GPS_EVENT_FIRST_FIX:
            Log.i("GPS", "First Fix/ Refix");
            hasGPSFix = true;
            break;
        case GpsStatus.GPS_EVENT_STARTED:
            Log.i("GPS", "Started!");
            break;
        case GpsStatus.GPS_EVENT_STOPPED:
            Log.i("GPS", "Stopped");
            break;
        }
    }
}
Run Code Online (Sandbox Code Playgroud)


Gre*_*ein 5

好吧,将所有工作方法放在一起会导致这个(也处理 deprecated GpsStatus.Listener):

private GnssStatus.Callback mGnssStatusCallback;
@Deprecated private GpsStatus.Listener mStatusListener;
private LocationManager mLocationManager;

@Override
public void onCreate() {
    mLocationManager = (LocationManager) getSystemService(LOCATION_SERVICE);

    mLocationManager = (LocationManager) this.getSystemService(Context.LOCATION_SERVICE);
    if (checkPermission()) {
       mLocationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, GPS_UPDATE_INTERVAL, MIN_DISTANCE, this);
    }

    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
        mGnssStatusCallback = new GnssStatus.Callback() {
            @Override
            public void onSatelliteStatusChanged(GnssStatus status) {
                satelliteStatusChanged();
            }

            @Override
            public void onFirstFix(int ttffMillis) {
                gpsFixAcquired();

            }
        };
        mLocationManager.registerGnssStatusCallback(mGnssStatusCallback);
    } else {
        mStatusListener = new GpsStatus.Listener() {
            @Override
            public void onGpsStatusChanged(int event) {
                switch (event) {
                    case GpsStatus.GPS_EVENT_SATELLITE_STATUS:
                        satelliteStatusChanged();
                        break;
                    case GpsStatus.GPS_EVENT_FIRST_FIX:
                        // Do something.
                        gpsFixAcquired();
                        break;
                }
            }
        };
        mLocationManager.addGpsStatusListener(mStatusListener);
    }
}

private void gpsFixAcquired() {
    // Do something.
    isGPSFix = true;
}

private void satelliteStatusChanged() {
    if (mLastLocation != null)
        isGPSFix = (SystemClock.elapsedRealtime() - mLastLocationMillis) < (GPS_UPDATE_INTERVAL * 2);

    if (isGPSFix) { // A fix has been acquired.
        // Do something.
    } else { // The fix has been lost.
        // Do something.
    }
}

@Override
public void onLocationChanged(Location location) {
    if (location == null) return;

    mLastLocationMillis = SystemClock.elapsedRealtime();

    mLastLocation = location;
}

@Override
public void onStatusChanged(String s, int i, Bundle bundle) {

}

@Override
public void onProviderEnabled(String s) {

}

@Override
public void onProviderDisabled(String s) {

}
Run Code Online (Sandbox Code Playgroud)

注意:此答案是上述答案的组合。


Eri*_*ass 2

您可以尝试使用LocationManager.addGpsStatusListener在 GPS 状态更改时获取更新。看起来GPS_EVENT_STARTEDGPS_EVENT_STOPPED可能就是您要查找的内容。

  • 状态监听器与“GPS_EVENT_FIRST_FIX”相结合听起来更合适。 (3认同)