2013-10-23 45 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