2013-05-15 22 views
0

我想要做的是從2個提供商處獲得GPS位置,第一個是GPS,它是最準確的,第二個是aGPS,它是GPS和網絡的結合。我這樣做是因爲當正常的GPS需要更多時間獲取時,即使在高層建築中,GPS也可以獲得位置。 我想要的是嘗試從第一個提供者(GPS)獲取位置10秒,如果在那10秒鐘內我得到一個位置!= null,我打破定時循環並將結果帶到主線程,這是主要活動。否則,請從第二提供商(aGPS)獲取該位置(如果可用)。如果沒有哪個提供者能夠獲得位置,我將在10秒後返回null。 我面臨的問題是,當我做一個定時循環時,應用程序凍結10秒,所以我無法獲得主要活動的位置。Android嘗試在沒有凍結應用程序的情況下獲取X秒位置

在這裏,我想獲得在延伸的HomeActivity類的位置活動:

Button btnRedCross = (Button) this.findViewById(R.id.btnRedCross); 
     btnRedCross.setOnClickListener(new OnClickListener() { 

      @Override 
      public void onClick(View arg0) { 
       OutRequestsDatabaseHandler db =new OutRequestsDatabaseHandler(); 
       OutRequest outreq = new OutRequest(); 
       outreq.setName("Red Cross"); 
       //TODO get the message from LocalUser db 
       Calendar cal = Calendar.getInstance(); 
       outreq.setDate(cal.getTimeInMillis()); 
       outreq.setMessage("My Message"); 
       outreq.setType("RedCross"); 
       //outreq.setLongitude(12.123456); 
       //outreq.setLatitude(12.123456); 
       db.addOutRequest(HomeActivity.this, outreq); 
       //HERE I AM TRYING TO GET THE LOCATION 
       GPSTracker locationtracker=new GPSTracker(HomeActivity.this); 
       location=locationtracker.getLocation(); 
       Log.i("LocationGetter","Result: Longitude:"+location[0]+" Latitude:"+location[1]); 
      } 
     }); 
    } 

這是GPSTracker類,其中2個提供商試圖獲得位置:

public class GPSTracker{ 
    Context con; 
    LocationManager locMgr; 
    private double longgps; 
    private double latgps; 
    private double longnetwork; 
    private double latnetwork; 
    private LocationListener gpsLocationListener; 
    private LocationListener networkLocationListener; 
    public GPSTracker(final Context context){ 
     con = context; 
     locMgr = (LocationManager) context 
       .getSystemService(Context.LOCATION_SERVICE); 
     LocationProvider high = locMgr.getProvider(locMgr.getBestProvider(
       createFineCriteria(), true)); 
     LocationProvider low = locMgr.getProvider(locMgr.getBestProvider(
       createCoarseCriteria(), true)); 
     //GET LOCATION FROM GPS 
     gpsLocationListener = new LocationListener() { 

      @Override 
      public void onStatusChanged(String provider, int status, 
        Bundle extras) { 
      } 

      @Override 
      public void onProviderEnabled(String provider) { 
      } 

      @Override 
      public void onProviderDisabled(String provider) { 
       AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(
         context); 
       alertDialogBuilder 
         .setMessage(
           "Please Enable GPS and Network For Accurate Result") 
         .setCancelable(false) 
         .setPositiveButton("Enable GPS", 
           new DialogInterface.OnClickListener() { 
            public void onClick(DialogInterface dialog, 
              int id) { 
             Intent callGPSSettingIntent = new Intent(
               android.provider.Settings.ACTION_LOCATION_SOURCE_SETTINGS); 
             context.startActivity(callGPSSettingIntent); 
            } 
           }); 
       alertDialogBuilder.setNegativeButton("Cancel", 
         new DialogInterface.OnClickListener() { 
          public void onClick(DialogInterface dialog, int id) { 
           dialog.cancel(); 
          } 
         }); 
       AlertDialog alert = alertDialogBuilder.create(); 
       alert.show(); 
      } 

      @Override 
      public void onLocationChanged(Location location) { 
       longgps = location.getLongitude(); 
       latgps = location.getLatitude(); 
       //Log.i("LocationGetter", "GPS: Longitude:" + longgps+ " Latitude:" + latgps); 

      } 
     }; 
     locMgr.requestLocationUpdates(high.getName(), 0, 0f,gpsLocationListener); 
     //GET LOCATION FROM GPS + NETWORK 
     networkLocationListener=new LocationListener() { 

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

      } 

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

      } 

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

      } 

      @Override 
      public void onLocationChanged(Location location) { 
       longnetwork = location.getLongitude(); 
       latnetwork = location.getLatitude(); 
       //Log.i("LocationGetter", "Network: Longitude:"+ longnetwork + " Latitude:" + latnetwork); 

      } 
     }; 
     locMgr.requestLocationUpdates(low.getName(), 0, 0f,networkLocationListener); 
    } 

    public static Criteria createFineCriteria() { 

     Criteria c = new Criteria(); 
     c.setAccuracy(Criteria.ACCURACY_FINE); 
     c.setAltitudeRequired(false); 
     c.setBearingRequired(false); 
     c.setSpeedRequired(false); 
     c.setCostAllowed(true); 
     c.setPowerRequirement(Criteria.POWER_HIGH); 
     return c; 

    } 

    public static Criteria createCoarseCriteria() { 

     Criteria c = new Criteria(); 
     c.setAccuracy(Criteria.ACCURACY_COARSE); 
     c.setAltitudeRequired(false); 
     c.setBearingRequired(false); 
     c.setSpeedRequired(false); 
     c.setCostAllowed(true); 
     c.setPowerRequirement(Criteria.POWER_HIGH); 
     return c; 
    } 

    public double[] getLocation() { 
    double location[] = new double[2]; 
    Calendar cal = Calendar.getInstance(); 
    Long endtime = cal.getTimeInMillis() + 10000; 
    while (Calendar.getInstance().getTimeInMillis() < endtime) { 
     if (longgps != 0 && latgps != 0) { 
      location[0] = longgps; 
      location[1] = latgps; 
      Log.i("LocationGetter", "GPS: Longitude:" + location[0] 
        + " Latitude:" + location[1]); 
      break; 
     } else if (longnetwork != 0 && latnetwork != 0) { 
      location[0] = longnetwork; 
      location[1] = latnetwork; 
      Log.i("LocationGetter", "Network: Longitude:" + location[0] 
        + " Latitude:" + location[1]); 
     } 
    } 
    locMgr.removeUpdates(networkLocationListener); 
    locMgr.removeUpdates(gpsLocationListener); 
    networkLocationListener = null; 
    gpsLocationListener = null; 
    return location; 
} 
} 
+0

你不能等待10秒,然後你的代碼最有可能會獲得網絡位置固定的類。 –

+0

如果GPS在10秒內進入,但要比網絡晚,您是否要等GPS? –

+0

Hoan我會在10秒後獲得網絡位置。但在10秒內如果我將得到GPS位置,10秒循環中斷,我會得到GPS位置。 – Xing

回答

0

」不是個這只是一個多線程問題。可以創建第二個線程,而不是在主線程上工作,以便該線程閒置10秒無關緊要。順便提一下,我認爲最好是使用所有的提供商並根據他們的準確性使用卡爾曼濾波器來信任他們,而不是依靠任何一家提供商。請參閱my answer here瞭解一個簡單的卡爾曼濾波器,該濾波器似乎適用於Android位置提供商。

0

通過聲明方法updatedLocation(Location loc)沒有正文,使您的GPSTracker類抽象。在代碼

public abstract class GPSTracker{ 
    ....... 
    private Location mLocation; 

    public void updateLocation(Location loc); 

    private CountDownTimer mNetworkCountDown = new CountDownTimer(10000, 10000) 
    { 

     @Override 
     public void onTick(long millisUntilFinished) 
     { 

     } 

     @Override 
     public void onFinish() 
     { 
         // this onFinish() will be called if not cancel by Gps 
      locMgr.removeUpdates(networkLocationListener); 
         updateLocation(mLocation); 
     } 
    }; 

     private CountDownTimer mGpsCountDown = new CountDownTimer(10000, 10000) 
    { 

     @Override 
     public void onTick(long millisUntilFinished) 
     { 

     } 

     @Override 
     public void onFinish() 
     { 
      locMgr.removeUpdates(gpsLocationListener); 
     } 
    }; 
     ......... 
     gpsLocationListener = new LocationListener() { 
     .......... 
     @Override 
     public void onLocationChanged(Location location) { 
      // Get a gps fix cancel both countdowns and listeners 
      mGpsCountDown.cancel(); 
      mNetworkCountDown.cancel(); 
      locMgr.removeUpdates(gpsLocationListener); 
      locMgr.removeUpdates(networkLocationListener); 
      // The calling class will get the fix 
      updateLocation(location); 

      longgps = location.getLongitude(); 
      latgps = location.getLatitude(); 
      //Log.i("LocationGetter", "GPS: Longitude:" + longgps+ " Latitude:" + latgps); 

     } 
    }; 
    locMgr.requestLocationUpdates(high.getName(), 0, 0f,gpsLocationListener); 
    mGpsCountDown.start(); 
    ....... 
    networkLocationListener=new LocationListener() { 
    .......... 
    @Override 
     public void onLocationChanged(Location location) { 
      // No cancelation here, Gps will cancel if it gets a fix 
      mLocation = location; 
      longnetwork = location.getLongitude(); 
      latnetwork = location.getLatitude(); 
      //Log.i("LocationGetter", "Network: Longitude:"+ longnetwork + " Latitude:" + latnetwork); 

     } 
    }; 
    locMgr.requestLocationUpdates(low.getName(), 0, 0f,networkLocationListener); 
    mNetworkCountDown.start(); 
    ......... 
    // remove the getLocation() 
} 

在HomeActivity類創建一個擴展GPSTracker

public class HomeActivity extends Activity { 
......... 
    public class MyGPSTracker extends GPSTracker 
    { 
     public void updateLocation(Location location) 
     { 
       // location would be null if both Gps and Network did not 
       // get a fix in 10 seconds 
       if (location != null) 
       { 
        // do whatever you want with this location fix 
        // If you want to know if this fix is from GPS or Network 
        // just use String provider = location.getProvider() 
        Log.i("LocationGetter","Result: Longitude:"+location.getLongitude()+" Latitude:"+location.getLatitude); 
       } 
     } 
    } 

    Button btnRedCross = (Button) this.findViewById(R.id.btnRedCross); 
    btnRedCross.setOnClickListener(new OnClickListener() { 

     @Override 
     public void onClick(View arg0) { 
      OutRequestsDatabaseHandler db =new OutRequestsDatabaseHandler(); 
      OutRequest outreq = new OutRequest(); 
      outreq.setName("Red Cross"); 
      //TODO get the message from LocalUser db 
      Calendar cal = Calendar.getInstance(); 
      outreq.setDate(cal.getTimeInMillis()); 
      outreq.setMessage("My Message"); 
      outreq.setType("RedCross"); 
      //outreq.setLongitude(12.123456); 
      //outreq.setLatitude(12.123456); 
      db.addOutRequest(HomeActivity.this, outreq); 
      //HERE I AM TRYING TO GET THE LOCATION 
      GPSTracker locationtracker=new MyGPSTracker(HomeActivity.this); 
      // You will get the location when updateLocation is called by the 
      // MyGPSTracker class 
      Log.i("LocationGetter","Result: Longitude:"+location[0]+" Latitude:"+location[1]); 
     } 
    }); 
} 
相關問題