2015-05-16 109 views
3

我正在android中使用地理位置的Android應用程序。我正在使用位置管理器獲取地理位置座標。20秒後獲取地理位置

locationManager.requestLocationUpdates(provider, 0, 0, this); 
    Location location = locationManager.getLastKnownLocation(provider); 

並使用postDelayed()函數連續稱爲getLastKnownLocation()爲地理位置。並設置間隔時間1000(1秒)。但是我在20秒後得到了迴應。 任何人都可以解釋爲什麼會發生。我是Android新手。

+0

你能告訴你哪裏調用'postDelayed()'? –

回答

3

請注意,你不應該調用getLastKnownLocation()每一秒,如果你有一個位置監聽器設置(它看起來像你這樣做)的問題。只需使用onLocationChanged()回調中給出的最新值即可。

此代碼適用於我,它註冊一個位置監聽器,它更新緯度/經度成員變量,然後Runnable以1秒的初始間隔運行,然後每隔5秒(5000毫秒)運行並顯示大多數當前位置值。

我輸入Toast以確保Runnable每隔5秒由handler.postDelayed()運行。

以下是完整的活動代碼:

import android.content.Context; 
import android.location.Location; 
import android.location.LocationListener; 
import android.location.LocationManager; 
import android.os.Handler; 
import android.support.v7.app.ActionBarActivity; 
import android.os.Bundle; 
import android.view.Menu; 
import android.view.MenuItem; 
import android.widget.TextView; 
import android.widget.Toast; 


public class MainActivity extends ActionBarActivity implements LocationListener { 

    LocationManager locationManager; 
    Handler handler; 
    Location location; 

    double latitude; 
    double longitude; 

    TextView lat; 
    TextView lon; 

    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.activity_main); 

     handler = new Handler(); 

     lat = (TextView) findViewById(R.id.latitudeTextView); 
     lon = (TextView) findViewById(R.id.longitudeTextView); 

     locationManager = (LocationManager) this.getSystemService(Context.LOCATION_SERVICE); 
     locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 0, 0, this); 
     location = locationManager.getLastKnownLocation(LocationManager.NETWORK_PROVIDER); 
     if (location != null){ 
      latitude = location.getLatitude(); 
      longitude = location.getLongitude(); 
     } 

     handler.postDelayed(runLocation, 1000); 
    } 

    public Runnable runLocation = new Runnable(){ 
     @Override 
     public void run() { 
      lat.setText(String.valueOf(latitude)); 
      lon.setText(String.valueOf(longitude)); 
      Toast.makeText(MainActivity.this, "location check", Toast.LENGTH_SHORT).show(); 

      MainActivity.this.handler.postDelayed(MainActivity.this.runLocation, 5000); 
     } 
    }; 


    @Override 
    public boolean onCreateOptionsMenu(Menu menu) { 
     // Inflate the menu; this adds items to the action bar if it is present. 
     getMenuInflater().inflate(R.menu.menu_main, menu); 
     return true; 
    } 

    @Override 
    public boolean onOptionsItemSelected(MenuItem item) { 
     // Handle action bar item clicks here. The action bar will 
     // automatically handle clicks on the Home/Up button, so long 
     // as you specify a parent activity in AndroidManifest.xml. 
     int id = item.getItemId(); 

     //noinspection SimplifiableIfStatement 
     if (id == R.id.action_settings) { 
      return true; 
     } 

     return super.onOptionsItemSelected(item); 
    } 

    @Override 
    public void onLocationChanged(Location location) { 
     latitude = location.getLatitude(); 
     longitude = location.getLongitude(); 
    } 

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

    } 

    @Override 
    public void onProviderEnabled(String provider) { 

    } 

    @Override 
    public void onProviderDisabled(String provider) { 

    } 
} 

編輯:

作爲替代方案,你可以取出來使用postDelayed(),並且只使用onLocationChanged()事件。

在下面的例子中,我使用了NETWORK_PROVIDERGPS_PROVIDER

這是需要在AndroidManifest.xml:

<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" /> 
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" /> 

這裏是修改後的代碼,其中註冊活動作爲兩個網絡位置回調和GPS位置回調位置監聽器,用最小時間間隔一秒。請注意,事件可能會以比一秒鐘更長的時間間隔進行,但啓用GPS位置後,我發現它們每秒都會進入(僅在啓用網絡位置的情況下耗時更長)。

public class MainActivity extends ActionBarActivity implements LocationListener { 

    LocationManager locationManager; 
    Handler handler; 
    Location location; 

    double latitude; 
    double longitude; 

    TextView lat; 
    TextView lon; 

    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.activity_main); 

     handler = new Handler(); 

     lat = (TextView) findViewById(R.id.latitudeTextView); 
     lon = (TextView) findViewById(R.id.longitudeTextView); 

     locationManager = (LocationManager) this.getSystemService(Context.LOCATION_SERVICE); 
     locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 1000, 0, this); 
     locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 1000, 0, this); 
     location = locationManager.getLastKnownLocation(LocationManager.NETWORK_PROVIDER); 
     if (location != null){ 
      latitude = location.getLatitude(); 
      longitude = location.getLongitude(); 
     } 

     //handler.postDelayed(runLocation, 1000); 
    } 
/* 
    public Runnable runLocation = new Runnable(){ 
     @Override 
     public void run() { 
      lat.setText(String.valueOf(latitude)); 
      lon.setText(String.valueOf(longitude)); 
      Toast.makeText(MainActivity.this, "location check", Toast.LENGTH_SHORT).show(); 

      MainActivity.this.handler.postDelayed(MainActivity.this.runLocation, 5000); 
     } 
    }; 
*/ 

    @Override 
    public boolean onCreateOptionsMenu(Menu menu) { 
     // Inflate the menu; this adds items to the action bar if it is present. 
     getMenuInflater().inflate(R.menu.menu_main, menu); 
     return true; 
    } 

    @Override 
    public boolean onOptionsItemSelected(MenuItem item) { 
     // Handle action bar item clicks here. The action bar will 
     // automatically handle clicks on the Home/Up button, so long 
     // as you specify a parent activity in AndroidManifest.xml. 
     int id = item.getItemId(); 

     //noinspection SimplifiableIfStatement 
     if (id == R.id.action_settings) { 
      return true; 
     } 

     return super.onOptionsItemSelected(item); 
    } 

    @Override 
    public void onLocationChanged(Location location) { 
     latitude = location.getLatitude(); 
     longitude = location.getLongitude(); 

     lat.setText(String.valueOf(latitude)); 
     lon.setText(String.valueOf(longitude)); 
     Toast.makeText(MainActivity.this, "location changed: " + latitude + " " + longitude, Toast.LENGTH_SHORT).show(); 
    } 

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

    } 

    @Override 
    public void onProviderEnabled(String provider) { 

    } 

    @Override 
    public void onProviderDisabled(String provider) { 

    } 
} 
+0

即使設備未更改位置,它是否會向我發送回覆... –

+0

@SourbhGupta是的,因爲您的主要問題是關於使用'postDelayed()',所以我將它包含在答案中。你也可以完全不使用'postDelayed()',而只需使用'onLocationChanged()'事件。你能描述你想要完成的事情嗎? –

+0

@SourbhGupta我剛剛更新了一個不使用'postDelayed()'的替代實現的答案。 –

1

使用谷歌地圖API V2

例如

public class MapActivity extends FragmentActivity { 
protected GoogleMap map; 
protected LatLng start; 
protected LatLng end; 
TextView tvDistance,tvTime; 
CameraPosition mCameraPosition; 
    // LatLng currentLocation ; 
Context context; 
public static boolean loadMapChk = false; 
double getlatitute, getlongitute; 
String addressGeo; 
/** 
* This activity loads a map and then displays the route and pushpins on it. 
*/ 
@Override 
public void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.map); 
    context = this; 

    Bundle bundle = getIntent().getExtras(); 
    if (bundle != null) { 

     getlatitute = bundle.getDouble("getlatitute"); 
     getlongitute = bundle.getDouble("getlongitute"); 
     addressGeo = bundle.getString("addressGeo"); 
    } 


    tvDistance = (TextView) findViewById(R.id.tvDistance); 
    tvTime = (TextView) findViewById(R.id.tvTime); 

    SupportMapFragment fm = (SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.map); 
    map = fm.getMap(); 

    map.setMyLocationEnabled(true); 
    map.setOnMyLocationChangeListener(myLocationChangeListener); 




} 
private GoogleMap.OnMyLocationChangeListener myLocationChangeListener = new GoogleMap.OnMyLocationChangeListener() { 
    @Override 
    public void onMyLocationChange (Location location) { 
     LatLng loc = new LatLng (location.getLatitude(), location.getLongitude()); 

// Toast.makeText(getApplicationContext(),"location.getLongitude()>>>>>>>"+location.getLongitude(),Toast.LENGTH_LONG).show(); 

    // map.animateCamera(CameraUpdateFactory.newLatLngZoom(loc, 16.0f)); 
     Bitmap bitmapicon = BitmapFactory.decodeResource(context.getResources(), 
       R.drawable.start_blue); 
     map.addMarker(new MarkerOptions().position(
       new LatLng(location.getLatitude(), location.getLongitude())).title("My Location").icon(BitmapDescriptorFactory.fromBitmap(bitmapicon))); 

     if (!loadMapChk) 
     {  
     map.animateCamera(CameraUpdateFactory.newLatLngZoom(new LatLng(location.getLatitude(), location.getLongitude()), 12.5f), 4000, null); 
     loadMapChk = true; 
     } 
     start = new LatLng(location.getLatitude(), location.getLongitude()); 
     end = new LatLng(getlatitute, getlongitute); 

     Bitmap bitmapiconEnd = BitmapFactory.decodeResource(context.getResources(), 
       R.drawable.end_green); 
     map.addMarker(new MarkerOptions().position(
       new LatLng(getlatitute, getlongitute)).title(addressGeo).icon(BitmapDescriptorFactory.fromBitmap(bitmapiconEnd))); 

     Routing routing = new Routing(Routing.TravelMode.DRIVING); 
     routing.registerListener(routingListener); 
     routing.execute(start, end); 


    } 
}; 


@Override 
protected void onResume() { 
    // TODO Auto-generated method stub 
    super.onResume(); 
    loadMapChk = false; 
} 

     public RoutingListener routingListener = new RoutingListener() { 

@Override 
public void onRoutingSuccess(PolylineOptions mPolyOptions, Route route) { 
     PolylineOptions polyOptions = new PolylineOptions(); 
     polyOptions.color(Color.CYAN); 
     polyOptions.width(8); 
     polyOptions.addAll(mPolyOptions.getPoints()); 
     tvDistance.setText("Distance : "+route.getDistanceText()); 
     tvTime.setText("Time : "+route.getDurationText()); 
     // Toast.makeText(getApplicationContext(), "Distance : "+route.getDistanceText()+" & Time = "+route.getDurationText(),6).show(); 
     map.addPolyline(polyOptions); 

     // Start marker 
     MarkerOptions options = new MarkerOptions(); 


     // End marker 
     options = new MarkerOptions(); 
     options.position(end); 
     options.icon(BitmapDescriptorFactory.fromResource(R.drawable.end_green)); 
     map.addMarker(options);  
} 

@Override 
public void onRoutingStart() { 
    // TODO Auto-generated method stub 

} 

@Override 
public void onRoutingFailure() { 
    // TODO Auto-generated method stub 

} 

};

}

0

使用定時器handeller來實現延遲。

Total time= Time delay+ Server response 

你可能面臨因爲如此

+0

我認爲這不是原因,因爲當我嘗試我接受的答案。它給了我2秒的結果。 –

2

將此類用作普通的類。

package com.ibl.commonClass; 
import android.app.AlertDialog; 
import android.app.Service; 
import android.content.Context; 
import android.content.DialogInterface; 
import android.content.Intent; 
import android.location.Location; 
import android.location.LocationListener; 
import android.location.LocationManager; 
import android.os.Bundle; 
import android.os.IBinder; 
import android.provider.Settings; 
import android.util.Log; 

public class GPSTracker extends Service implements LocationListener { 

private final Context mContext; 

// flag for GPS status 
boolean isGPSEnabled = false; 

// flag for network status 
boolean isNetworkEnabled = false; 

// flag for GPS status 
boolean canGetLocation = false; 

Location location; // location 
double latitude; // latitude 
double longitude; // longitude 

// The minimum distance to change Updates in meters 
private static final long MIN_DISTANCE_CHANGE_FOR_UPDATES = 10; // 10 meters 

// The minimum time between updates in milliseconds 
private static final long MIN_TIME_BW_UPDATES = 1000 * 60 * 1; // 1 minute 

// Declaring a Location Manager 
protected LocationManager locationManager; 

public GPSTracker(Context context) { 
    this.mContext = context; 
    getLocation(); 
} 

public Location getLocation() { 
    try { 
     locationManager = (LocationManager) mContext 
       .getSystemService(LOCATION_SERVICE); 

     // getting GPS status 
     isGPSEnabled = locationManager 
       .isProviderEnabled(LocationManager.GPS_PROVIDER); 

     // getting network status 
     isNetworkEnabled = locationManager 
       .isProviderEnabled(LocationManager.NETWORK_PROVIDER); 

     if (!isGPSEnabled && !isNetworkEnabled) { 
      // no network provider is enabled 
     } else { 
      this.canGetLocation = true; 
      // First get location from Network Provider 
      if (isNetworkEnabled) { 
       locationManager.requestLocationUpdates(
         LocationManager.NETWORK_PROVIDER, 
         MIN_TIME_BW_UPDATES, 
         MIN_DISTANCE_CHANGE_FOR_UPDATES, this); 
       Log.d("Network", "Network"); 
       if (locationManager != null) { 
        location = locationManager 
          .getLastKnownLocation(LocationManager.NETWORK_PROVIDER); 
        if (location != null) { 
         latitude = location.getLatitude(); 
         longitude = location.getLongitude(); 
        } 
       } 
      } 
      // if GPS Enabled get lat/long using GPS Services 
      if (isGPSEnabled) { 
       if (location == null) { 
        locationManager.requestLocationUpdates(
          LocationManager.GPS_PROVIDER, 
          MIN_TIME_BW_UPDATES, 
          MIN_DISTANCE_CHANGE_FOR_UPDATES, this); 
        Log.d("GPS Enabled", "GPS Enabled"); 
        if (locationManager != null) { 
         location = locationManager 
           .getLastKnownLocation(LocationManager.GPS_PROVIDER); 
         if (location != null) { 
          latitude = location.getLatitude(); 
          longitude = location.getLongitude(); 
         } 
        } 
       } 
      } 
     } 

    } catch (Exception e) { 
     e.printStackTrace(); 
    } 

    return location; 
} 

/** 
* Stop using GPS listener Calling this function will stop using GPS in your 
* app 
* */ 
public void stopUsingGPS() { 
    if (locationManager != null) { 
     locationManager.removeUpdates(GPSTracker.this); 
    } 
} 

/** 
* Function to get latitude 
* */ 
public double getLatitude() { 
    if (location != null) { 
     latitude = location.getLatitude(); 
    } 

    // return latitude 
    return latitude; 
} 

/** 
* Function to get longitude 
* */ 
public double getLongitude() { 
    if (location != null) { 
     longitude = location.getLongitude(); 
    } 

    // return longitude 
    return longitude; 
} 

/** 
* Function to check GPS/wifi enabled 
* 
* @return boolean 
* */ 
public boolean canGetLocation() { 
    return this.canGetLocation; 
} 

/** 
* Function to show settings alert dialog On pressing Settings button will 
* lauch Settings Options 
* */ 
public void showSettingsAlert() { 
    AlertDialog.Builder alertDialog = new AlertDialog.Builder(mContext); 

    // Setting Dialog Title 
    alertDialog.setTitle("GPS is settings"); 

    // Setting Dialog Message 
    alertDialog 
      .setMessage("GPS is not enabled. Do you want to go to settings menu?"); 

    // On pressing Settings button 
    alertDialog.setPositiveButton("Settings", 
      new DialogInterface.OnClickListener() { 
       public void onClick(DialogInterface dialog, int which) { 
        Intent intent = new Intent(
          Settings.ACTION_LOCATION_SOURCE_SETTINGS); 
        mContext.startActivity(intent); 
       } 
      }); 

    // on pressing cancel button 
    alertDialog.setNegativeButton("Cancel", 
      new DialogInterface.OnClickListener() { 
       public void onClick(DialogInterface dialog, int which) { 
        dialog.cancel(); 
       } 
      }); 

    // Showing Alert Message 
    alertDialog.show(); 
} 

@Override 
public void onLocationChanged(Location location) { 
} 

@Override 
public void onProviderDisabled(String provider) { 
} 

@Override 
public void onProviderEnabled(String provider) { 
} 

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

@Override 
public IBinder onBind(Intent arg0) { 
    return null; 
} 

} 

這個代碼onCreate方法在你的活動把在

GPSTracker gps; 
gps = new GPSTracker(NearMeActivity.this); 

    if (gps.canGetLocation()) { 

     latitude = gps.getLatitude(); 
     longitude = gps.getLongitude(); 

     // Toast.makeText(
     // getApplicationContext(), 
     // "Your Location is - \nLat: " + latitude + "\nLong: " 
     // + longitude, Toast.LENGTH_LONG).show(); 
    } else { 
     gps.showSettingsAlert(); 
    } 

    Log.e("latlong", "" + latitude + "" + longitude);