1
我是Android
的新手,並且正在構建一個跟蹤用戶距離的應用程序。它只會在用戶點擊按鈕時開始跟蹤,並在他們再次點擊時停止。似乎有關於如何做到這一點的大量混淆信息和方法,所以我至少有一個最佳實踐的總體思路。瞭解Service,LocationListener和BroadcastReceiver如何在後臺獲取位置
public class BackgroundLocationService extends Service implements GooglePlayServicesClient.ConnectionCallbacks, GooglePlayServicesClient.OnConnectionFailedListener, LocationListener {
IBinder mBinder = new LocalBinder();
private LocationClient mLocationClient;
private LocationRequest mLocationRequest;
private boolean mInProgress;
//Milliseconds per second
private static final int MILLISECONDS_PER_SECOND = 1000;
// Update frequency in seconds
private static final int UPDATE_INTERVAL_IN_SECONDS = 30;
// Update frequency in milliseconds
public static final long UPDATE_INTERVAL = MILLISECONDS_PER_SECOND * UPDATE_INTERVAL_IN_SECONDS;
// The fastest update frequency, in seconds
private static final int FASTEST_INTERVAL_IN_SECONDS = 30;
// A fast frequency ceiling in milliseconds
public static final long FASTEST_INTERVAL = MILLISECONDS_PER_SECOND * FASTEST_INTERVAL_IN_SECONDS;
private static final int TWO_MINUTES = 1000 * 60 * 2;
public Location previousBestLocation = null;
private Boolean servicesAvailable = false;
public class LocalBinder extends Binder {
public BackgroundLocationService getServerInstance() {
return BackgroundLocationService.this;
}
}
@Override
public void onCreate() {
super.onCreate();
mInProgress = false;
mLocationRequest = LocationRequest.create();
mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
mLocationRequest.setInterval(UPDATE_INTERVAL);
mLocationRequest.setFastestInterval(FASTEST_INTERVAL);
// Check that Google Play Services are connected
servicesAvailable = servicesConnected();
// Create the client
mLocationClient = new LocationClient(this, this, this);
}//end
private boolean servicesConnected() {
// Check that Google Play services is available
int resultCode = GooglePlayServicesUtil.isGooglePlayServicesAvailable(this);
// If Google Play services is available
if (ConnectionResult.SUCCESS == resultCode) {
return true;
} else {
return false;
}
}//end
public int onStartCommand (Intent intent, int flags, int startId) {
super.onStartCommand(intent, flags, startId);
if(!servicesAvailable || mLocationClient.isConnected() || mInProgress)
return START_STICKY;
setUpLocationClientIfNeeded();
if(!mLocationClient.isConnected() || !mLocationClient.isConnecting() && !mInProgress) {
mInProgress = true;
mLocationClient.connect();
}
return START_STICKY;
}//end
private void setUpLocationClientIfNeeded() {
if (mLocationClient == null)
mLocationClient = new LocationClient(this, this, this);
}
@Override
public void onLocationChanged(Location location) {
String msg = Double.toString(location.getLatitude()) + "," +Double.toString(location.getLongitude());
Toast.makeText(this, msg, Toast.LENGTH_SHORT).show();
}//end
@Override
public IBinder onBind(Intent intent) {
return mBinder;
}
public String getTime() {
SimpleDateFormat mDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
return mDateFormat.format(new Date());
}
@Override
public void onDestroy(){
// Turn off the request flag
mInProgress = false;
if(servicesAvailable && mLocationClient != null) {
mLocationClient.removeLocationUpdates(this);
// Destroy the current location client
mLocationClient = null;
}
// Display the connection status
Toast.makeText(this, DateFormat.getDateTimeInstance().format(new Date()) + ": Disconnected. Please re-connect.", Toast.LENGTH_SHORT).show();
super.onDestroy();
}
/*
* Called by Location Services when the request to connect the
* client finishes successfully. At this point, you can
* request the current location or start periodic updates
*/
@Override
public void onConnected(Bundle bundle) {
// Request location updates using static settings
mLocationClient.requestLocationUpdates(mLocationRequest, this);
}
/*
* Called by Location Services if the connection to the
* location client drops because of an error.
*/
@Override
public void onDisconnected() {
// Turn off the request flag
mInProgress = false;
// Destroy the current location client
mLocationClient = null;
// Display the connection status
Toast.makeText(this, DateFormat.getDateTimeInstance().format(new Date()) + ": Disconnected. Please re-connect.", Toast.LENGTH_SHORT).show();
}
/*
* Called by Location Services if the attempt to
* Location Services fails.
*/
@Override
public void onConnectionFailed(ConnectionResult connectionResult) {
mInProgress = false;
/*
* Google Play services can resolve some errors it detects.
* If the error has a resolution, try sending an Intent to
* start a Google Play services activity that can resolve
* error.
*/
if (connectionResult.hasResolution()) {
// If no resolution is available, display an error dialog
} else {
}
}
}
所以到我的問題:
- 從我的主要
Activity
如何開始我的服務?我該如何阻止它? - 我的
Activity
班級如何知道我的Service
是否收到Location
更新,以便我可以更新UI? - 我甚至需要
BroadcastReceiver
嗎? - 是否需要進入我的
Manifest
?
好的,我有它的工作,並提供位置更新,即使我離開了應用程序。在我的Activity中,我使用startService(new Intent(this,BackgroundLocationService.class));'開始了我的服務。仍然不清楚我的「服務」如何與我的主「活動」進行交流,以便每次獲得位置更新時都能讓它知道。 –
正在舉一個例子,很快就會報告回來 – cYrixmorten
我現在已經用'LocalBroadcastManager'工作了。我可以發送一個字符串。但我現在正在努力如何發送一個'Location'對象。 –