位置決め

429548 ワード

まずModelを定義します.

  
  
  
  
  1. public class LocationData {  
  2.         String lat;  
  3.         String lon;  
  4.         String address;  
  5. }  

 
そしてLBSのすべての機能はツールクラスにカプセル化されます.
まず、コンストラクション関数でシステムサービスのLocationManagerを取得します.

  
  
  
  
  1. public class LBSTool {  
  2.     private Context mContext;  
  3.     private LocationManager mLocationManager;   
  4.     private LocationData mLocation;  
  5.     private LBSThread mLBSThread;  
  6.     private MyLocationListner mNetworkListner;  
  7.     private MyLocationListner mGPSListener;  
  8.     private Looper mLooper;  
  9.       
  10.     public LBSTool(Context context) {  
  11.         mContext = context;  
  12.         // Location manager  
  13.         mLocationManager = (LocationManager)mContext.getSystemService(Context.LOCATION_SERVICE);  
  14.     }  
  15.   
  16. ......  
  17. }  

 
次にエントリメソッドです.ここではサブスレッドを起動して地理的位置情報を取得し、メインスレッドを待機させます.時間長はtimeout設定を通過します.

  
  
  
  
  1. /**  
  2.  *     
  3.  * @param timeout    
  4.  * @return LocationData , null  
  5.  */  
  6. public LocationData getLocation(long timeout) {  
  7.     mLocation = null;  
  8.     mLBSThread = new LBSThread();  
  9.     mLBSThread.start();// LBSThread  
  10.     timeout = timeout > 0 ? timeout : 0;  
  11.       
  12.     synchronized (mLBSThread) {  
  13.         try {  
  14.             Log.i(Thread.currentThread().getName(), "Waiting for LocationThread to complete...");  
  15.             mLBSThread.wait(timeout);// , timeout ms  
  16.             Log.i(Thread.currentThread().getName(), "Completed.Now back to main thread");  
  17.         }  
  18.         catch (InterruptedException e) {  
  19.             e.printStackTrace();  
  20.         }  
  21.     }  
  22.     mLBSThread = null;  
  23.     return mLocation;  

サブスレッドはregisterLocationListenerを呼び出して位置サービスのリスニングを開始し、指定したlooperにリスナーを割り当てます.

  
  
  
  
  1. private class LBSThread extends Thread {  
  2.     @Override  
  3.     public void run() {  
  4.         setName("location thread");   
  5.         Log.i(Thread.currentThread().getName(), "--start--");   
  6.         Looper.prepare();// LBSThread Looper  
  7.         mLooper = Looper.myLooper();  
  8.         registerLocationListener();  
  9.         Looper.loop();  
  10.         Log.e(Thread.currentThread().getName(),  "--end--");  
  11.           
  12.     }  
  13. }  
  14.   
  15. private void registerLocationListener () {  
  16.     Log.i(Thread.currentThread().getName(), "registerLocationListener");          
  17.     if (isGPSEnabled()) {  
  18.         mGPSListener=new MyLocationListner();    
  19.   
  20.         // , , ,listener,listener looper  
  21.         mLocationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 50000, mGPSListener, mLooper);    
  22.     }  
  23.     if (isNetworkEnabled()) {  
  24.         mNetworkListner=new MyLocationListner();    
  25.  
  26.         mLocationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 30000, mNetworkListner, mLooper);    
  27.     }  

isGPSEnabledとisNetworkEnabledは、それぞれ、現在の携帯電話がGPSをオンにしているかどうかおよびネットワークの状況(wifiとモバイルネットワークをオンにしているかどうかを含む)を判断するために、どのサービスプロバイダを使用するかを決定する:GPS_PROVIDERまたはNETWORK_PROVIDER.

  
  
  
  
  1. /**  
  2.  *  GPS   
  3.  * @return  
  4.  */  
  5. public boolean isGPSEnabled() {  
  6.     if(mLocationManager.isProviderEnabled(LocationManager.GPS_PROVIDER)) {  
  7.         Log.i(Thread.currentThread().getName(), "isGPSEnabled");  
  8.         return true;  
  9.     }   
  10.     else {  
  11.         return false;  
  12.     }  
  13. }  
  14.   
  15. /**  
  16.  *  Network ( wifi)  
  17.  * @return  
  18.  */  
  19. public boolean isNetworkEnabled() {  
  20.     return (isWIFIEnabled() || isTelephonyEnabled());   
  21. }  
  22.   
  23. /**  
  24.  *    
  25.  * @return  
  26.  */  
  27. public boolean isTelephonyEnabled() {  
  28.     boolean enable = false;  
  29.     TelephonyManager telephonyManager = (TelephonyManager) mContext.getSystemService(Context.TELEPHONY_SERVICE);  
  30.     if (telephonyManager != null) {  
  31.         if (telephonyManager.getNetworkType() != TelephonyManager.NETWORK_TYPE_UNKNOWN) {  
  32.             enable = true;  
  33.             Log.i(Thread.currentThread().getName(), "isTelephonyEnabled");  
  34.         }  
  35.     }  
  36.       
  37.     return enable;  
  38. }  
  39.   
  40. /**  
  41.  *  wifi   
  42.  */  
  43. public boolean isWIFIEnabled() {  
  44.     boolean enable = false;  
  45.     WifiManager wifiManager = (WifiManager)mContext.getSystemService(Context.WIFI_SERVICE);  
  46.     if(wifiManager.isWifiEnabled()) {  
  47.         enable = true;  
  48.         Log.i(Thread.currentThread().getName(), "isWIFIEnabled");   
  49.     }   
  50.     return enable;  

LocationManagerが最短時間以上で最小位置変化を検出した場合、リスナーに通知され、戻った経緯情報でgoogleサーバに行って対応するアドレスを検索し、LocationMangerの作業を停止し、LBSthreadのLooperを解除し、LBSthreadを終了させ、最後にメインスレッドが継続できることを通知し、プロセス全体が終了する.

  
  
  
  
  1. private class MyLocationListner implements LocationListener{    
  2.   
  3.     @Override  
  4.     public void onLocationChanged(Location location) {    
  5.         //  LocationManager ,   
  6.         Log.i(Thread.currentThread().getName(), "Got New Location of provider:"+location.getProvider());  
  7.         unRegisterLocationListener();// LocationManager   
  8.         try {  
  9.             synchronized (mLBSThread) {   
  10.                 parseLatLon(location.getLatitude()+"", location.getLongitude()+"");//   
  11.                 mLooper.quit();// LBSThread Looper,LBSThread   
  12.                 mLBSThread.notify();//   
  13.             }  
  14.         }  
  15.         catch (Exception e) {  
  16.             e.printStackTrace();  
  17.         }  
  18.     }    
  19.  
  20.     // 3  
  21.     @Override  
  22.     public void onStatusChanged(String provider, int status, Bundle extras) {}    
  23.  
  24.     @Override  
  25.     public void onProviderEnabled(String provider) {}    
  26.  
  27.     @Override  
  28.     public void onProviderDisabled(String provider) {}  
  29.   
  30. };  
  31.   
  32. /**  
  33.  *  goole    
  34.  * @param    
  35.  */  
  36. private void parseLatLon(String lat, String lon) throws Exception {  
  37.     Log.e(Thread.currentThread().getName(),  "---parseLatLon---");  
  38.     Log.e(Thread.currentThread().getName(),  "---"+lat+"---");  
  39.     try {  
  40.         HttpClient httpClient = new DefaultHttpClient();  
  41.         HttpGet get = new HttpGet("http://ditu.google.cn/maps/geo?output=json&q="+lat+","+lon);  
  42.         HttpResponse response = httpClient.execute(get);  
  43.         String resultString = EntityUtils.toString(response.getEntity());  
  44.           
  45.         JSONObject jsonresult = new JSONObject(resultString);  
  46.         if(jsonresult.optJSONArray("Placemark") != null) {  
  47.             mLocation = new LocationData();  
  48.             mLocation.lat = lat;  
  49.             mLocation.lon = lon;  
  50.             mLocation.address = jsonresult.optJSONArray("Placemark").optJSONObject(0).optString("address");  
  51.         }  
  52.     }  
  53.     catch (Exception e) {  
  54.         e.printStackTrace();  
  55.     }  
  56. }  
  57.   
  58. /**  
  59.  *     
  60.  */  
  61. private void unRegisterLocationListener () {  
  62.     if(mGPSListener!=null){    
  63.         mLocationManager.removeUpdates(mGPSListener);    
  64.         mGPSListener=null;    
  65.     }   
  66.     if(mNetworkListner!=null){    
  67.         mLocationManager.removeUpdates(mNetworkListner);    
  68.         mNetworkListner=null;    
  69.     }   

 
次に、インタフェースにbuttonを配置します.

  
  
  
  
  1. locationBtn.setOnClickListener(new OnClickListener() {  
  2.               
  3.     @Override  
  4.     public void onClick(View v) {  
  5.         //return mode  
  6.         LBSTool lbs = new LBSTool(LBStestActivity.this);  
  7.         LocationData location = lbs.getLocation(120000);  
  8.         if (location != null) {  
  9.             Log.i("---lat---",location.lat);  
  10.             Log.i("---lon---",location.lon);  
  11.             Log.i("---address---",location.address);  
  12.             Toast.makeText(LBStestActivity.this, location.lat + " " + location.lon + " " + location.address, Toast.LENGTH_LONG).show();  
  13.  
  14.         }  
  15.           
  16.     }  
  17. }); 

最後に、アクセス権を忘れないでください.

  
  
  
  
  1. <uses-permission android:name="android.permission.INTERNET" />  
  2. <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />  
  3. <uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>  
  4. <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />  
  5. <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />  

 
さらに、LocationManagerでは、重要なパラメータを設定したり、最後のロケーション情報を取得したりするなど、高度な使い方があります.

  
  
  
  
  1. Criteria criteria = new Criteria(); 
  2.         criteria.setAccuracy(Criteria.ACCURACY_FINE); //   
  3.         criteria.setAltitudeRequired(false); 
  4.         criteria.setBearingRequired(false); 
  5.         criteria.setCostAllowed(true); 
  6.         criteria.setPowerRequirement(Criteria.POWER_LOW); //   
  7.          
  8.         String bestprovider = locationManager.getBestProvider(criteria, true); //  GPS  
  9.         Location location = locationManager.getLastKnownLocation(bestprovider); //  GPS  
  10.         Log.e("--bestprovider--", bestprovider); 
  11.         Log.e("--bestprovider--", location.getLatitude()+"");