Androidの実現の位置づけ

5814 ワード

Androidベースの位置決めはnetwork、gpsの2つにほかならない.両者にはそれぞれ優劣がある.
Network:位置決めが速く、精度が低く、環境の影響が少ない.
GPS:位置決めが遅く、精度が高く、環境の影響が大きい.
ここで解決する問題:
1.      locationManager.getLastKnownLocationメソッドはnullを返します.
2.迅速かつ正確な位置付けを実現する方法.
 
E文がよければ、公式サイトを直接見ればいいです.http://developer.android.com/guide/topics/location/strategies.html
 
あなたのプログラムにこのようなコードがあれば注意してください(今から見れば余計です)
[java] view plaincopy
<span style="font-size:14px;">    Criteria criteria = new Criteria();  
            criteria.setAccuracy(Criteria.ACCURACY_FINE);//     
            criteria.setAltitudeRequired(false);//       
            criteria.setBearingRequired(false);//       
            criteria.setCostAllowed(true);//        
            criteria.setPowerRequirement(Criteria.POWER_LOW);//     
            
            //           
            String provider = locationManager.getBestProvider(criteria,true);  
    locationManager.getLastKnownLocation(provider);  </span>

locationManager.getBestProvider(criteria,true);方法は完璧に見えますが、実は戻り値はnetwork、gpsの2つに1つ選択されています.また、高精度を要求する場合はGPSを優先的にチェックし、携帯電話がGPSをオンにするとGPSに戻り、そうでない場合はnetworkに戻ります.いずれも開いていない場合はnullを返します.
Network、GPSの2つの測位方式の優劣を組み合わせると、getLastKnownLocationメソッドがnullを返す理由がわかります(これは最初の測位のみです).
 
GPSをオンにすると、providerの値はGPSです.このときの測位方式はGPSで、GPSの測位が遅い(私がテストした時間は約50秒)ため、すぐにLocationオブジェクトに戻ることはできないのでnullに戻ります.次の方法でこの問題を解決する人もいます.
[java] view plaincopy
<span style="font-size:14px;">    while (location ==null) {  
           location = locationManager.getLastKnownLocation(provider);  
       }  </span>

これは絶対に愚かなやり方だ.例えば、室内にいるとgpsが位置決めできず、プログラムはデッドサイクルに陥ります.もちろんrequestLocationUpdatesを使用すると、プログラムがデッドサイクルに陥らないように位置決めできますが、位置決めに時間がかかり、位置決めも得られません.
ネット測位を使うなら、これもいい選択だとは言えません.locationManager.requestLocationUpdates(
              LocationManager.NETWORK_PROVIDER, 0, 0,networkListener);
ネットワークの位置決めには一般的に2秒程度かかります(ネットワークが悪く、時間が長くなります).ネットワークにアクセスすれば、基本的に位置決めが得られます.唯一の欠点は精度が高くないことです.
 
それは両者を結びつけることができるかどうか、これも本文の重点です.両者を結合する以上、同時に傍受を追加しなければならない.
[java] view plaincopy
<span style="font-size:14px;">    locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER,1000 * 2,50,gpsListener);  
    locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 0, 0,networkListener);  </span>

これにより、約2秒でネットワークからの位置決めが得られ、1分後にGPSからの位置決めが得られます.このときGPS測位でネットワーク測位を置き換えるとよい.もちろんこれは理想的な状況で、現実は複雑です.
例:
ネットワークの問題でnullが2回目に戻ったため、locationに最初の位置決めに成功しました.この場合、更新されたlocationは前回の正確さ、nullさえなく、使用できないことがわかります.この場合、現在のlocationと新しく取得したlocationのほうが良いと判断します.GPS測位を取得した後、天気やトンネルに入るなどの理由でGPSサーバーが失われ、locationを更新できない可能性があります(この場合、network測位に切り替えるのが良い方法です).また、GPSとnetworkをオンにしていないと、位置決めとは言えない可能性もあります(実際には、位置決めが成功するたびに位置決めキャッシュがあり、getLastKnownLocationを使用して入手できます).
 
最後に述べたように、私たちがしなければならないのは:
1.getLastKnownLocationで最終位置決め情報を取得してみる
2.networkとgpsの傍受をオンにする
3.network測位情報locationを取得する
4.現在のlocationと新しく取得したlocationのどちらが良いかを比較する(networkから)
5.gps測位情報locationを取得する
6.networkの傍受を止める
7.現在のlocationと新しく取得したlocationのどちらが良いかを比較する(gpsから)
8.gpsサーバが失われた場合、networkリスニングを再開
GPS傍受を例に
[java] view plaincopy
<span style="font-size:14px;">    // GPS         
     private class GPSLocationListener implements LocationListener {  
      
        private boolean isRemove = false;//            
      
        @Override  
        public void onLocationChanged(Location location) {  
            // TODO Auto-generatedmethod stub  
            boolean flag =betterLocation.isBetterLocation(location,  
                   currentBestLocation);  
      
            if (flag) {  
               currentBestLocation = location;  
               updateLocation(currentBestLocation);  
            }  
            //   GPS   ,  network    
            if (location !=null && !isRemove) {  
               locationManager.removeUpdates(networkListener);  
               isRemove = true;  
            }  
        }  
      
        @Override  
        public void onProviderDisabled(String provider) {  
            // TODO Auto-generatedmethod stub  
        }  
      
        @Override  
        public void onProviderEnabled(String provider) {  
            // TODO Auto-generatedmethod stub  
        }  
      
        @Override  
        public void onStatusChanged(String provider, int status, Bundleextras) {  
            // TODO Auto-generatedmethod stub  
            if (LocationProvider.OUT_OF_SERVICE == status) {  
               Toast.makeText(MainActivity.this,"GPS    ,       ",  
                      Toast.LENGTH_SHORT).show();  
               locationManager  
                      .requestLocationUpdates(  
                             LocationManager.NETWORK_PROVIDER, 0, 0,  
                             networkListener);  
            }  
        }  
     }  </span>

その中でisBetterLocationはどのlocationが良いかを判断するために使われています.この方法はandroid公式サイトから,locationで取得した時間,精度などの情報から判断する.
前にアップロードしたdemoは、あまり意味がないと思っていたので、提供しませんでした.
次の図の「マイクロ秒」の単位が間違っています.ミリ秒です.
Android之实现定位_第1张图片
その後、私が接触したプロジェクトでは、位置決めに対する要求はそれほど高くないことがわかりました.ただ、現在の位置を簡単に取得するだけで十分で、起動するたびに取得するだけです.
Androidのシンプルな位置決めの実装については、http://blog.csdn.net/limb99/article/details/18819925
from:http://blog.csdn.net/limb99/article/details/8765584#comments