2013-10-23 49 views
0

我正在嘗試製作一個簡單的應用程序,用戶在其中點擊一個按鈕,幾個文本視圖顯示有關手機的各種信息(型號,電池%,位置,信號強度等)。我無法獲取當前的經度和緯度,因爲當我按下按鈕時,textview將顯示以前的緯度/經度(第一次顯示0,0,第二次顯示我第一次按下該位置時的位置)。Android - 使用android gps提供者在onClick()中檢索當前位置

我想要實現的是當我按下按鈕時,激活位置管理器和位置偵聽器,並使onClick()方法等待,直到緯度不等於舊的緯度。我已經嘗試了線程,處理程序和asynctask,但我沒有管理任何東西。有小費嗎?這是我的onClick()方法的外觀現在:(Infogatherer是我收集的所有信息類)

@Override 
public void onClick(View arg0) { 
    // TODO Auto-generated method stub 
    switch(arg0.getId()){ 
    case R.id.bMeasurements: 

     oldLat=InfoGatherer.getLatitude(); 
     oldLong=InfoGatherer.getLongitude(); 

      //SOMEWHERE HERE START A THREAD OR SOMETHING IN ORDER TO RETRIEVE CURRENT LOCATION 
     //Retrieval and Assignment of information to the corresponding text fields 
     DeviceName.setText(infogatherer.getDeviceName()); 

     NetworkOp.setText(infogatherer.getNetworkOp()); 

     Date.setText(infogatherer.getDate()); 

     BatteryStatus.setText(String.valueOf(infogatherer.getBatteryStatus())); 

     Generation.setText(String.valueOf(infogatherer.getGeneration())); 
     infogatherer.getLocation(); 
     Location.setText(String.valueOf(InfoGatherer.getLatitude()+","+InfoGatherer.getLatitude())); 
     infogatherer.getSignalStrength(); 
     SignalStrength.setText(String.valueOf(infogatherer.getDbm())); 

     oldLat = InfoGatherer.getLatitude(); 
     oldLong = InfoGatherer.getLongitude(); 
     break; 

    } 

這是我InfoGatherer類:

package com.example.netmap; 

import java.io.IOException; 
import java.util.Calendar; 
import java.util.List; 
import java.util.Locale; 
import android.annotation.SuppressLint; 
import android.app.Activity; 
import android.app.Application; 
import android.content.Context; 
import android.content.Intent; 
import android.content.IntentFilter; 
import android.location.Address; 
import android.location.Criteria; 
import android.location.Geocoder; 
import android.location.LocationListener; 
import android.location.LocationManager; 
import android.net.wifi.WifiInfo; 
import android.net.wifi.WifiManager; 
import android.os.BatteryManager; 
import android.os.Build; 
import android.os.Bundle; 
import android.telephony.CellInfoGsm; 
import android.telephony.CellSignalStrengthGsm; 
import android.telephony.PhoneStateListener; 
import android.telephony.SignalStrength; 
import android.telephony.TelephonyManager; 
import android.telephony.gsm.GsmCellLocation; 

public class InfoGatherer extends Application{ 

    String address,city,country; 
    int cid,lac,generation=0,ipAddress=0,signalStrngth=0; 
    private GsmCellLocation location; 
    private WifiInfo wifiInfo; 
    private LocationManager lm; 
    private LocationListener ll; 
    Geocoder geoc; 
    static public double Longitude,Latitude=0; 
    List<Address> addresses; 
    Context context; 
    Intent batteryIntent; 
    TelephonyManager tm; 
    WifiManager wifimanager; 

    public InfoGatherer(){ 

    } 
    public InfoGatherer(Context context){ 
     this.context = context; 
    } 

    public String getDate(){ 
     Calendar c = Calendar.getInstance(); 
     return Integer.toString(c.get(Calendar.DAY_OF_MONTH))+"-"+Integer.toString(c.get(Calendar.MONTH))+"-"+Integer.toString(c.get(Calendar.YEAR))+" "+Integer.toString(c.get(Calendar.HOUR_OF_DAY))+":"+Integer.toString(c.get(Calendar.MINUTE))+":"+Integer.toString(c.get(Calendar.SECOND)); 
    } 

    public String getDeviceName(){ 
     return Build.MANUFACTURER +" "+Build.MODEL; 
    } 

    public String getNetworkOp(){ 
     tm = (TelephonyManager)context.getSystemService(Context.TELEPHONY_SERVICE); 
     return tm.getNetworkOperatorName(); 

    } 

    public float getBatteryStatus() { 
     batteryIntent = context.registerReceiver(null, new IntentFilter(Intent.ACTION_BATTERY_CHANGED)); 
     return ((float)batteryIntent.getIntExtra(BatteryManager.EXTRA_LEVEL, -1)/(float)batteryIntent.getIntExtra(BatteryManager.EXTRA_SCALE, -1)) * 100.0f; 
    } 


    public int getGeneration(){ 
     tm = (TelephonyManager)context.getSystemService(Context.TELEPHONY_SERVICE); 
     return tm.getNetworkType(); 
    } 

    public int getCid(){ 
     tm = (TelephonyManager)context.getSystemService(Context.TELEPHONY_SERVICE); 
     location = (GsmCellLocation)tm.getCellLocation(); 
     return location.getCid(); 
    } 

    public int getLac(){ 
     tm = (TelephonyManager)context.getSystemService(Context.TELEPHONY_SERVICE); 
     location = (GsmCellLocation)tm.getCellLocation(); 
     return location.getLac(); 
    } 

    public String getIpAddress() { 
     // TODO Auto-generated method stub 
     wifimanager = (WifiManager) context.getSystemService(WIFI_SERVICE); 
     wifiInfo = wifimanager.getConnectionInfo(); 
     ipAddress = wifiInfo.getIpAddress(); 
     return String.format("%d.%d.%d.%d",(ipAddress & 0xff),(ipAddress >> 8 & 0xff),(ipAddress >> 16 & 0xff),(ipAddress >> 24 & 0xff)); 
    } 

    public void getLocation(){ 
     /*Criteria c = new Criteria(); 
     c.setAccuracy(Criteria.ACCURACY_FINE); 
     c.setPowerRequirement(Criteria.POWER_LOW); 
     String provider = lm.getBestProvider(c, true);*/ 

     lm = (LocationManager)context.getSystemService(Context.LOCATION_SERVICE); 
     ll = new mylocationlistener(); 

     lm.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, ll); 

    } 

    public class mylocationlistener implements LocationListener{ 

     @Override 
     public void onLocationChanged(android.location.Location location) { 
      // TODO Auto-generated method stub 
      if(location!=null){ 
       Longitude = location.getLongitude(); 
       Latitude = location.getLatitude(); 

       lm.removeUpdates(ll); 

      } 

     } 



     @Override 
     public void onProviderDisabled(String provider) { 
      // TODO Auto-generated method stub 

      //Pass views as parameters? DIscuss 
      //DeviceName.setText(String.valueOf(Latitude) +" "+String.valueOf(Longitude)); 

     } 

     @Override 
     public void onProviderEnabled(String provider) { 
      // TODO Auto-generated method stub 

     } 

     @Override 
     public void onStatusChanged(String provider, int status, 
       Bundle extras) { 
      // TODO Auto-generated method stub 

     } 

    } 

    public void getSignalStrength(){ 
     tm = (TelephonyManager)context.getSystemService(Context.TELEPHONY_SERVICE); 
     PhoneStateListener Listener = new phoneStateListener(); 
     tm.listen(Listener ,PhoneStateListener.LISTEN_SIGNAL_STRENGTHS); 
    } 

    public class phoneStateListener extends PhoneStateListener{ 
     public void onSignalStrengthsChanged(SignalStrength signalStrength){ 
      super.onSignalStrengthsChanged(signalStrength); 
      if (signalStrength.isGsm()) { 
       signalStrngth = -113 + 2 * signalStrength.getGsmSignalStrength(); 

      } 
      else 
       signalStrngth = -113 + 2 * signalStrength.getCdmaDbm(); 
     } 

    } 





    static public double getLatitude(){ 
     return Latitude; 
    } 

    static public double getLongitude(){ 
     return Longitude; 
    } 

    public String getAddress(){ 
     return address; 
    } 

    public String getCity(){ 
     return city; 
    } 

    public String getCountry(){ 
     return country; 
    } 

    public int getDbm(){ 
     return signalStrngth; 
    } 

} 
+0

請發佈您的'InfoGatherer'類 – ramaral

+0

完成!我加了! –

+0

爲什麼在'onLocationChanged'處刪除更新?嘗試沒有該行 – ramaral

回答

0

在我使用的AsyncTask結束,這讓我爲了睡覺的應用程序,而我看的位置。

private class LocationThread extends AsyncTask<Context, Void, Void> { 

    protected void onPreExecute() { 
     infogatherer.startLocationListener(); 
    } 

    @Override 
    protected Void doInBackground(Context... params) { 
     while (!infogatherer.getGo()) { 
      try { 
       Thread.sleep(1000); 
      } catch (InterruptedException e) { 
       e.printStackTrace(); 
      } 
     } 
     return null; 
    } 

    protected void onPostExecute(final Void unused) { 
     //Do whatever you wanna do after you get location 
    } 
} 

getGo是每當成爲真正的布爾給人的位置後面

public class mylocationlistener implements LocationListener { 
    @Override 
    public void onLocationChanged(android.location.Location location) { 
     if(location != null){ 
      Longitude = location.getLongitude(); 
      Latitude = location.getLatitude(); 
      lm.removeUpdates(ll); 
      go = true; 
     } 
    } 

希望你能理解的過程。乾杯。

0

你不提供足夠的時間到位置服務獲取位置。
LocationManager有時間撥打onLocationChanged之前,您要求輸入經緯度。

infogatherer.getLocation(); 
Location.setText(String.valueOf(InfoGatherer.getLatitude()+","+InfoGatherer.getLatitude())); 

致電infogatherer.getLocation(); out of onClick事件。在活動onResume()事件中這樣做。
onLocationChanged刪除lm.removeUpdates(ll);。在活動onPause()事件中調用它。

如果你想看看這個例子如何創建一個GPS Manager Class

編輯
嘗試是這樣的:注:沒有測試!

private void updateLocationText(double oldLat, double oldLong) { 
    Handler handler = new Handler(); 
    Runnable runnable = new Runnable() { 

     public void run() { 
      boolean isPositionChanged = false; 
      double lat; 
      double long; 
      while (!isPositionChanged) { 
       lat = InfoGatherer.getLatitude(); 
       long = InfoGatherer.getLongitude(); 
       if(lat != oldLat || long != oldLong)isPositionChanged = true; 
      } 
      handler.post(new Runnable(){ 
       public void run() { 
        Location.setText(String.valueOf(InfoGatherer.getLatitude()+","+InfoGatherer.getLatitude())); 
       }); 
      } 
     } 
    }; 
    new Thread(runnable).start(); 
} 

需要注意的是,如果你點擊按鈕,而不必一直沒有位置的變化,它會永遠運行。

再次編輯

另一種方法更乾淨:

更換

Location.setText(String.valueOf(InfoGatherer.getLatitude()+","+InfoGatherer.getLatitude())); 

與此

Location.postDelayed(new Runnable() { 
    @Override 
    public void run() { 
     Location.setText(String.valueOf(InfoGatherer.getLatitude()+","+InfoGatherer.getLatitude())); 
     Location.postInvalidate();//Try without, may be not necessary 
    } 
}, 3000);//Change if need 
+0

這隻會做一些工作 - 你假設活動在實質性變動時不會留在前臺。最好的辦法是觸發延遲更新過程,在此期間顯示忙圖標或舊值(可能用陰影表示它是舊的)。 –

+0

我認爲克里斯是正確的,你可以更深入地瞭解你將如何觸發延遲更新過程? –

+0

ramaral,感謝所有的編輯。最後一個似乎工作,雖然取決於用戶在哪裏(室內,戶外等),經度和緯度的提取需要更長的時間。所以我只是不能告訴程序「等待4-5秒」,我希望它更可調,並且看看數值何時改變,然後釋放線程: –

0

創建LocationListener的出Aplication的。 在Ativity中實例化類,覆蓋onLocationChanged事件並在那裏更新位置TextView。

protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 

    ......... 
    ......... 
    lm = (LocationManager)getSystemService(Context.LOCATION_SERVICE); 

    listener = new MyLocationListener(){ 
     @Override 
     public void onLocationChanged(android.location.Location location) { 
      if(location!=null){ 
       Location.setText(String.valueOf(location.getLatitude()+","+location.getLatitude())); 
       lm.removeUpdates(listener); 
      } 
     } 
    } 
} 

在的onClick()事件替換:

infogatherer.getLocation(); 
Location.setText(String.valueOf(InfoGatherer.getLatitude()+","+InfoGatherer.getLatitude())); 

lm.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, listener); 
+0

那麼這部分代碼應該在哪個類中? –

+0

在您有位置TextView和獲得當前經緯度的按鈕的活動中 – ramaral