GPSレシーバーの現在のステータスを確認するにはどうすればよいですか?私はすでにLocationListener
onStatusChanged
方法をチェックしましたが、どういうわけかそれは機能していないか、単に間違った可能性があるようです。
基本的に、画面の上部にあるGPSアイコンが点滅している(実際の修正はない)か、点灯している(修正が利用可能)かを知る必要があります。
GPSレシーバーの現在のステータスを確認するにはどうすればよいですか?私はすでにLocationListener
onStatusChanged
方法をチェックしましたが、どういうわけかそれは機能していないか、単に間違った可能性があるようです。
基本的に、画面の上部にあるGPSアイコンが点滅している(実際の修正はない)か、点灯している(修正が利用可能)かを知る必要があります。
回答:
SpeedView:Android向けGPSスピードメーターの開発者として、私はこの問題に対するすべての可能な解決策を試したに違いありません。うまくいかないことを繰り返しましょう:
だから、ここで私が見つけた唯一の実用的なソリューションと、私が実際に自分のアプリで使用しているものを紹介します。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;
}
}
}
では、onLocationChanged()に次のコードを追加します。
@Override
public void onLocationChanged(Location location) {
if (location == null) return;
mLastLocationMillis = SystemClock.elapsedRealtime();
// Do something.
mLastLocation = location;
}
以上です。基本的に、これはすべてを行う行です:
isGPSFix = (SystemClock.elapsedRealtime() - mLastLocationMillis) < 3000;
もちろんミリ値を微調整することもできますが、約3〜5秒に設定することをお勧めします。
これは実際に機能しますが、ネイティブGPSアイコンを描画するソースコードを見たことはありませんが、これは動作を再現するところです。これが誰かを助けることを願っています。
mLastLocationMillis
、GPS以外のソースによって設定された場合、これは壊れませんか?システムだろう主張よりもisGPSFix
真実であるが、現実にはそれだけで任意の修正(電話ネットワークから多分1)
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ステータスの変化に気付くことができます。ただし、状態が変化したときにのみ通知されます。したがって、これらのインテントを使用して現在の状態を判断することはできません。
新しいメンバーなので、残念ながらコメントや投票はできませんが、上記のStephen Dayeの投稿は、私が助けを求めているまったく同じ問題に対する完璧な解決策でした。
次の行の小さな変更:
isGPSFix = (SystemClock.elapsedRealtime() - mLastLocationMillis) < 3000;
に:
isGPSFix = (SystemClock.elapsedRealtime() - mLastLocationMillis) < (GPS_UPDATE_INTERVAL * 2);
基本的に、ペースの遅いゲームを構築していて、gps信号が10秒以上出力されると、更新間隔が既に5秒に設定されているため、何かをトリガーするのに適切なタイミングです。
乾杯の仲間、私があなたの投稿を見つける前にこの解決策を解決するために約10時間を費やしました:)
では、これまでのすべての回答と更新を組み合わせて、次のようなことをしてみましょう。
ACCESS_FINE_LOCATION
マニフェストに権限を追加しますLocationManager
GpsStatus.Listener
反応するを作成しますGPS_EVENT_SATELLITE_STATUS
LocationManager
してaddGpsStatusListener
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と衛星の情報がいつ、どのように提供されるかについては少し不明確ですが、利用可能な衛星の数を調べることが考えられると思います。3未満の場合、修正はできません。それ以上の場合は、修正する必要があります。
試行錯誤は、Androidが衛星情報を報告する頻度、および各GpsSatellite
オブジェクトに含まれる情報を特定するための方法です。
GpsSatellite
オブジェクトからどのように/どのようにしてこれを取得できるかについては、もうわかりません。
LocationManager.requestLocationUpdates
が、時間と距離の設定を0に設定して使用したことはありますか?GPSの修正が行われるとすぐに送信されます。何も受け取っていない場合は、おそらく修正されていません。必要に応じて、これを上記のステータスリスナーと組み合わせることができます。
Windows MobileでGPSを数年使用した後、GPSフィックスを「失う」という概念は主観的である可能性があることに気付きました。GPSからの通知を単純に聞くには、NMEAListenerを追加して文を解析すると、修正が「有効」であったかどうかがわかります。http://www.gpsinformation.org/dale/nmea.htm#GGAを参照してください。残念ながら、一部のGPSでは、この値は、「良好な修正」領域での通常の動作コースの間でも前後に変動します。
したがって、他の解決策は、GPS位置のUTC時間と電話の時間(UTCに変換)を比較することです。一定の時間差がある場合は、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;
}
}
}
まあ、すべての実用的なアプローチをまとめると、次のようになります(非推奨のも扱います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) {
}
注:この回答は上記の回答を組み合わせたものです。
修正があるかどうかを知る必要があるだけの場合は、GPSレシーバーによって提供された最後の既知の場所を確認し、.getTime()値を確認して、その古さを確認します。それが十分に新しい場合(たとえば...数秒)に修正があります。
LocationManager lm = (LocationManager)context.getSystemService(LOCATION_SERVICE);
Location loc = lm.getLastKnownLocation(LocationManager.GPS_PROVIDER);
// Get the time of the last fix
long lastFixTimeMillis = loc.getTime();
...そして最後にそれを現在の日付時刻と比較します(UTC!)。それが十分に新しい場合、修正があります。
私はそれを自分のアプリで行い、これまでのところとても良いです。
GPSステータスが変更されたときにLocationManager.addGpsStatusListenerを使用して更新を試みることができます。GPS_EVENT_STARTEDとGPS_EVENT_STOPPEDのように見えるかもしれません。
GPS_EVENT_FIRST_FIX
サウンドを組み合わせると、より密接にフィットします。
私は間違っているかもしれませんが、人々は話題から外れているようです
画面上部のgpsアイコンが点滅しているかどうかを確認するだけです(実際の修正はありません)。
それは簡単に行われます
LocationManager lm = (LocationManager) getSystemService(LOCATION_SERVICE);
boolean gps_on = lm.isProviderEnabled(LocationManager.GPS_PROVIDER);
確実な修正があるかどうかを確認するには、少し注意が必要です。
public class whatever extends Activity {
LocationManager lm;
Location loc;
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
lm = (LocationManager) getSystemService(LOCATION_SERVICE);
loc = null;
request_updates();
}
private void request_updates() {
if (lm.isProviderEnabled(LocationManager.GPS_PROVIDER)) {
// GPS is enabled on device so lets add a loopback for this locationmanager
lm.requestLocationUpdates(LocationManager.GPS_PROVIDER,0, 0, locationListener);
}
}
LocationListener locationListener = new LocationListener() {
public void onLocationChanged(Location location) {
// Each time the location is changed we assign loc
loc = location;
}
// Need these even if they do nothing. Can't remember why.
public void onProviderDisabled(String arg0) {}
public void onProviderEnabled(String provider) {}
public void onStatusChanged(String provider, int status, Bundle extras) {}
};
修正があるかどうかを確認したいときはいつでも?
if (loc != null){
// Our location has changed at least once
blah.....
}
ファンシーになりたい場合は、常にSystem.currentTimeMillis()とloc.getTime()を使用してタイムアウトにすることができます
少なくとも2.1以降のN1で確実に動作します。
LocationManagerを使用すると、getBestProvider()の後でgetLastKnownLocation()を取得できます。これにより、Locationオブジェクトが提供されます。これには、メートル単位のgetAccuracy()メソッドとUTCミリ秒単位のgetTime()メソッドがあります。
これで十分な情報が得られますか?
または、LocationProvidersを反復処理して、それぞれがmeetsCriteria(ACCURACY_COARSE)かどうかを確認することもできます
非常に多くの投稿...
GpsStatus.Listener gpsListener = new GpsStatus.Listener() {
public void onGpsStatusChanged(int event) {
if( event == GpsStatus.GPS_EVENT_FIRST_FIX){
showMessageDialog("GPS fixed");
}
}
};
このコードをaddGpsListenerで追加します... showMessageDialog ...は、標準のダイアログウィンドウに文字列を表示します
私のために完全に仕事をしました:)どうもありがとう:=)(この投稿のために申し訳ありませんが、まだ投票できません)
修正が失われた瞬間に更新が必要ない場合、Stephen Dayeのソリューションをそのように変更して、修正がまだ存在するかどうかを確認するメソッドを作成できます。
したがって、GPSデータが必要なときにいつでも確認でき、GpsStatus.Listenerは必要ありません。
「グローバル」変数は次のとおりです。
private Location lastKnownLocation;
private long lastKnownLocationTimeMillis = 0;
private boolean isGpsFix = false;
これは、更新時刻と現在の場所を記憶するために「onLocationChanged()」内で呼び出されるメソッドです。「isGpsFix」を更新することに加えて:
private void handlePositionResults(Location location) {
if(location == null) return;
lastKnownLocation = location;
lastKnownLocationTimeMillis = SystemClock.elapsedRealtime();
checkGpsFix(); // optional
}
そのメソッドは、GPS修正があるかどうかを知る必要があるときに呼び出されます。
private boolean checkGpsFix(){
if (SystemClock.elapsedRealtime() - lastKnownLocationTimeMillis < 3000) {
isGpsFix = true;
} else {
isGpsFix = false;
lastKnownLocation = null;
}
return isGpsFix;
}
私の実装では、最初にcheckGpsFix()を実行し、結果がtrueの場合、変数 "lastKnownLocation"を現在の位置として使用します。
私はこれが少し遅れていることを知っています。ただし、修正があるかどうかを知りたい場合は、NMEAListenerを使用しないでください。私が読んだ内容から、NMEAListenerはNMEA文を提供し、そこから正しい文を選択します。
RMC文には修正ステータスが含まれており、OKの場合はA、警告の場合はVのいずれかです。GGA文には修正品質が含まれています(0無効、1 GPSまたは2 DGPS)
Androidから始めたばかりなので、Javaコードは提供できませんが、Xamarinで使用する予定のWindowsアプリ用のC#でGPSライブラリを作成しました。プロバイダー情報を探していたため、このスレッドに出くわしました。
これまでにLocationオブジェクトについて読んだことから、getAccuracy()やhasAccuracy()などのメソッドについては、それほど快適ではありません。NMEAセンテンスからHDOPとVDOPの値を抽出して、修正の精度を判断することに慣れています。修正することは非常に一般的ですが、HDOPが粗末なので、水平方向の精度はまったく良くありません。たとえば、外付けのBluetooth GPSデバイスを窓に密着させてデバッグしている机に座っていると、修正が行われる可能性が非常に高くなりますが、HDOPとVDOPは非常に貧弱です。GPSデバイスをフラワーポットの外などに配置するか、外部アンテナをGPSに追加すると、すぐに良好なHDOP値とVDOP値が得られます。
あなたはすでに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追跡の有効化と無効化に関するものであることに注意してください。あなたが探しているものではありません。
修正をチェックする時間間隔を設定することは良い選択ではありません。移動していない場合、onLocationChangedが呼び出されないことに気付きました。ました..場所は変更されていないので、何が理解できますか:)
より良い方法は、例えば: