[android] 我如何檢查GPS接收器的當前狀態?


Answers

GPS圖標似乎根據收到的廣播意圖改變其狀態。 您可以使用以下代碼示例自行更改其狀態:

通知GPS已啟用:

Intent intent = new Intent("android.location.GPS_ENABLED_CHANGE");
intent.putExtra("enabled", true);
sendBroadcast(intent);

通知GPS正在接受修復:

Intent intent = new Intent("android.location.GPS_FIX_CHANGE");
intent.putExtra("enabled", true);
sendBroadcast(intent);

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

Intent intent = new Intent("android.location.GPS_FIX_CHANGE");
intent.putExtra("enabled", false);
sendBroadcast(intent);

通知GPS已被禁用:

Intent intent = new Intent("android.location.GPS_ENABLED_CHANGE");
intent.putExtra("enabled", false);
sendBroadcast(intent);

將接收者註冊到意圖的示例代碼:

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

通過接收這些廣播意圖,您可以注意到GPS狀態的變化。 但是,只有在狀態發生變化時才會通知您。 因此,使用這些意圖來確定當前狀態是不可能的。

Question

我如何檢查GPS接收器的當前狀態? 我已經檢查了LocationListener onStatusChanged方法,但不知何故,它似​​乎不工作,或者只是錯誤的可能性。

基本上,我只需要知道屏幕頂部的GPS圖標是否閃爍(沒有實際的修正)或實體(修復可用)。




好的,我們現在嘗試所有答案和更新的組合,並執行如下操作:

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

這些API對何時以及給出什麼GPS和衛星信息有點不清楚,但我認為一個想法是查看有多少衛星可用。 如果它低於三,那麼你不能有一個修復。 如果更多,那麼你應該有一個修復。

試驗和錯誤可能是確定Android報告衛星信息的頻率以及每個GpsSatellite對象包含哪些信息的方式。




我知道這有點晚了。 但是,如果你想知道你是否有修復,為什麼不使用NMEAListener? 從我讀過的內容來看,NMEAListener會給你NMEA的句子,並從那裡選擇正確的句子。

RMC語句包含固定狀態,可以是A代表OK或V代表警告。 GGA語句包含固定質量(0無效,1 GPS或2 DGPS)

我不能為您提供任何Java代碼,因為我只是剛剛開始使用Android,但我已經在C#中為Windows應用程序完成了一個GPS庫,我正在使用Xamarin。 我只是遇到了這個線程,因為我在尋找提供者信息。

從迄今為止關於Location對象所讀到的內容來看,我對getAccuracy()和hasAccuracy()等方法並不滿意。 我習慣從NMEA語句中提取HDOP和VDOP值,以確定我的修復程序有多準確。 它有一個修復相當普遍,但有一個糟糕的HDOP,這意味著你的水平精度不是很好。 例如,坐在桌面上用外部藍牙GPS設備進行調試時,你很可能會得到一個修復,但非常糟糕的HDOP和VDOP。 將您的GPS設備放置在室外的花盆或類似的地方,或者將外部天線添加到GPS,並立即獲得良好的HDOP和VDOP值。




這麼多帖子...

GpsStatus.Listener gpsListener = new GpsStatus.Listener() {
                        public void onGpsStatusChanged(int event) {
                            if( event == GpsStatus.GPS_EVENT_FIRST_FIX){
                                showMessageDialog("GPS fixed");
                            }
                        }
                 };

添加此代碼,與addGpsListener ... showMessageDialog ...只顯示一個標準的對話框窗口與字符串

完成了我的工作:) :)非常感謝:=)(對於這篇文章,還沒有投票)




那麼,把每一種工作方法放在一起會導致這種情況(也涉及不推薦使用的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) {

}

注意:這個答案是上述答案的組合。




你說你已經試過onStatusChanged(),但是這對我有用。

這裡是我使用的方法(我讓類本身處理onStatusChanged):

private void startLocationTracking() {
    final int updateTime = 2000; // ms
    final int updateDistance = 10; // meter
    final Criteria criteria = new Criteria();
    criteria.setCostAllowed(false);
    criteria.setAccuracy(Criteria.ACCURACY_FINE);
    final String p = locationManager.getBestProvider(criteria, true);
    locationManager.requestLocationUpdates(p, updateTime, updateDistance,
            this);
}

我按如下方式處理onStatusChanged:

void onStatusChanged(final String provider, final int status,
        final Bundle extras) {
    switch (status) {
    case LocationProvider.OUT_OF_SERVICE:
        if (location == null || location.getProvider().equals(provider)) {
            statusString = "No Service";
            location = null;
        }
        break;
    case LocationProvider.TEMPORARILY_UNAVAILABLE:
        if (location == null || location.getProvider().equals(provider)) {
            statusString = "no fix";
        }
        break;
    case LocationProvider.AVAILABLE:
        statusString = "fix";
        break;
    }
}

請注意,onProvider {Dis,En} abled()方法是關於啟用和禁用用戶的GPS跟踪; 不是你要找的東西。







在處理我的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;
        }
    }
}



Links



Tags

android android   gps