我正在創建一個將在其自己的進程中運行的後臺服務。它應該允許我聽取設備位置是否改變。我應該能夠在通知用戶界面之前更改移動距離等標準。在android中的位置監聽器的背景服務
我該怎麼辦?我對服務和LocationListener
實現有一點了解。任何圍繞網絡的教程將不勝感激。
我從堆棧溢出中得到了一個back-link,但是我不太瞭解它。
我正在創建一個將在其自己的進程中運行的後臺服務。它應該允許我聽取設備位置是否改變。我應該能夠在通知用戶界面之前更改移動距離等標準。在android中的位置監聽器的背景服務
我該怎麼辦?我對服務和LocationListener
實現有一點了解。任何圍繞網絡的教程將不勝感激。
我從堆棧溢出中得到了一個back-link,但是我不太瞭解它。
首先您需要創建一個Service
。在該Service
中,創建一個延伸爲LocationListener
的類。對於這一點,使用Service
下面的代碼片段:
public class LocationService extends Service
{
public static final String BROADCAST_ACTION = "Hello World";
private static final int TWO_MINUTES = 1000 * 60 * 2;
public LocationManager locationManager;
public MyLocationListener listener;
public Location previousBestLocation = null;
Intent intent;
int counter = 0;
@Override
public void onCreate()
{
super.onCreate();
intent = new Intent(BROADCAST_ACTION);
}
@Override
public void onStart(Intent intent, int startId)
{
locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
listener = new MyLocationListener();
locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 4000, 0, listener);
locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 4000, 0, listener);
}
@Override
public IBinder onBind(Intent intent)
{
return null;
}
protected boolean isBetterLocation(Location location, Location currentBestLocation) {
if (currentBestLocation == null) {
// A new location is always better than no location
return true;
}
// Check whether the new location fix is newer or older
long timeDelta = location.getTime() - currentBestLocation.getTime();
boolean isSignificantlyNewer = timeDelta > TWO_MINUTES;
boolean isSignificantlyOlder = timeDelta < -TWO_MINUTES;
boolean isNewer = timeDelta > 0;
// If it's been more than two minutes since the current location, use the new location
// because the user has likely moved
if (isSignificantlyNewer) {
return true;
// If the new location is more than two minutes older, it must be worse
} else if (isSignificantlyOlder) {
return false;
}
// Check whether the new location fix is more or less accurate
int accuracyDelta = (int) (location.getAccuracy() - currentBestLocation.getAccuracy());
boolean isLessAccurate = accuracyDelta > 0;
boolean isMoreAccurate = accuracyDelta < 0;
boolean isSignificantlyLessAccurate = accuracyDelta > 200;
// Check if the old and new location are from the same provider
boolean isFromSameProvider = isSameProvider(location.getProvider(),
currentBestLocation.getProvider());
// Determine location quality using a combination of timeliness and accuracy
if (isMoreAccurate) {
return true;
} else if (isNewer && !isLessAccurate) {
return true;
} else if (isNewer && !isSignificantlyLessAccurate && isFromSameProvider) {
return true;
}
return false;
}
/** Checks whether two providers are the same */
private boolean isSameProvider(String provider1, String provider2) {
if (provider1 == null) {
return provider2 == null;
}
return provider1.equals(provider2);
}
@Override
public void onDestroy() {
// handler.removeCallbacks(sendUpdatesToUI);
super.onDestroy();
Log.v("STOP_SERVICE", "DONE");
locationManager.removeUpdates(listener);
}
public static Thread performOnBackgroundThread(final Runnable runnable) {
final Thread t = new Thread() {
@Override
public void run() {
try {
runnable.run();
} finally {
}
}
};
t.start();
return t;
}
public class MyLocationListener implements LocationListener
{
public void onLocationChanged(final Location loc)
{
Log.i("**************************************", "Location changed");
if(isBetterLocation(loc, previousBestLocation)) {
loc.getLatitude();
loc.getLongitude();
intent.putExtra("Latitude", loc.getLatitude());
intent.putExtra("Longitude", loc.getLongitude());
intent.putExtra("Provider", loc.getProvider());
sendBroadcast(intent);
}
}
public void onProviderDisabled(String provider)
{
Toast.makeText(getApplicationContext(), "Gps Disabled", Toast.LENGTH_SHORT).show();
}
public void onProviderEnabled(String provider)
{
Toast.makeText(getApplicationContext(), "Gps Enabled", Toast.LENGTH_SHORT).show();
}
public void onStatusChanged(String provider, int status, Bundle extras)
{
}
}
}
添加此Service
任何地方在你的項目,你想要的方式! :)
完美的作品。 –
請注意:該代碼看起來可能來自[GPL'd項目](https://code.google.com/p/chataround-dto/source/browse/chataround-client/src/com/service /chataround/listener/MyLocationListener.java?r=101)(或者,它可能來自[this](https://code.google.com/p/apk/source/browse/trunk/src/com/vouov/聽衆/ MyLocationListener.java?r = 5)麻省理工學院許可的項目。任何人都知道上述代碼的許可證狀態? – Inactivist
@Nilanchala如果這對你有用比標記它正確,以便我可以幫助其他人有這樣的問題 –
我知道我發佈這個答案有點晚,但我覺得這是值得使用谷歌的保險絲位置提供商服務來獲取當前位置。
這個API的主要特點是:
1.Simple的API:讓你選擇你的準確度水平以及功耗。
2.立即可用:讓您的應用能夠立即訪問最佳的最近位置。
3.電源效率:它選擇最有效的方式用更少的功耗
獲得位置4.Versatility:滿足廣泛的需求,從需要高度精確的應用前景位置到後臺使用,需要週期性的位置更新而忽略電力影響。
它在位置更新時也很靈活。 如果您只希望當前位置在您的應用程序啓動時使用,則可以使用getLastLocation(GoogleApiClient)
方法。
如果您想更新您的位置不斷,那麼你可以使用requestLocationUpdates(GoogleApiClient,LocationRequest, LocationListener)
您可以找到有關保險絲的位置here和谷歌文檔保險絲的位置也是一個非常不錯的博客可以發現here。
更新
據他們增加的背景位置的新限制的AndroidØ開始開發文檔。
如果您的應用程序在後臺運行,位置系統服務 每小時只計算一次您的應用的新位置。即使您的應用程序請求更頻繁的位置 更新,這種情況也是如此 。 但是,如果您的應用在前臺運行,與Android 7.1.1(API級別25)相比, 位置採樣率沒有變化。
我認爲你是對的,但一些自定義Rom刪除谷歌播放服務,所以你不能使用保險絲位置提供商。 – Chen
如果你只是想大致瞭解你在某個特定時間的位置或者不太準確的跟蹤,那麼'FusedLocationProvider'沒問題,但對於需要高精度跟蹤的應用程序來說,它只是不夠好 – StuStirling
這些自定義Rom的解決方案是使用[失去](https://github.com/mapzen/LOST)從Mapzen。提供與Google的FusedLocationProviderAPI相同的功能,無需向Google Play服務註冊 –
非常容易,不需要創建類擴展LocationListener的 1-可變
private LocationManager mLocationManager;
private LocationListener mLocationListener;
private static double currentLat =0;
private static double currentLon =0;
2- onStartService()
@Override public void onStartService() {
addListenerLocation();
}
3-方法addListenerLocation()
private void addListenerLocation() {
mLocationManager = (LocationManager)
getSystemService(Context.LOCATION_SERVICE);
mLocationListener = new LocationListener() {
@Override
public void onLocationChanged(Location location) {
currentLat = location.getLatitude();
currentLon = location.getLongitude();
Toast.makeText(getBaseContext(),currentLat+"-"+currentLon, Toast.LENGTH_SHORT).show();
}
@Override
public void onStatusChanged(String provider, int status, Bundle extras) {
}
@Override
public void onProviderEnabled(String provider) {
Location lastKnownLocation = mLocationManager.getLastKnownLocation(LocationManager.NETWORK_PROVIDER);
if(lastKnownLocation!=null){
currentLat = lastKnownLocation.getLatitude();
currentLon = lastKnownLocation.getLongitude();
}
}
@Override
public void onProviderDisabled(String provider) {
}
};
mLocationManager.requestLocationUpdates(
LocationManager.GPS_PROVIDER, 500, 10, mLocationListener);
}
4 onDestroy()
@Override
public void onDestroy() {
super.onDestroy();
mLocationManager.removeUpdates(mLocationListener);
}
後臺定位服務,即使在殺應用後我也會開始。
MainActivity.java
public class MainActivity extends AppCompatActivity {
AlarmManager alarmManager;
Button stop;
PendingIntent pendingIntent;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
if (alarmManager == null) {
alarmManager = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
Intent intent = new Intent(this, AlarmReceive.class);
pendingIntent = PendingIntent.getBroadcast(this, 0, intent, 0);
alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, System.currentTimeMillis(), 30000,
pendingIntent);
}
}
}
BookingTrackingService.java
public class BookingTrackingService extends Service implements LocationListener {
private static final String TAG = "BookingTrackingService";
private Context context;
boolean isGPSEnable = false;
boolean isNetworkEnable = false;
double latitude, longitude;
LocationManager locationManager;
Location location;
private Handler mHandler = new Handler();
private Timer mTimer = null;
long notify_interval = 30000;
public double track_lat = 0.0;
public double track_lng = 0.0;
public static String str_receiver = "servicetutorial.service.receiver";
Intent intent;
@Nullable
@Override
public IBinder onBind(Intent intent) {
return null;
}
@Override
public void onCreate() {
super.onCreate();
mTimer = new Timer();
mTimer.schedule(new TimerTaskToGetLocation(), 5, notify_interval);
intent = new Intent(str_receiver);
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
this.context = this;
return START_NOT_STICKY;
}
@Override
public void onDestroy() {
super.onDestroy();
Log.e(TAG, "onDestroy <<");
if (mTimer != null) {
mTimer.cancel();
}
}
private void trackLocation() {
Log.e(TAG, "trackLocation");
String TAG_TRACK_LOCATION = "trackLocation";
Map<String, String> params = new HashMap<>();
params.put("latitude", "" + track_lat);
params.put("longitude", "" + track_lng);
Log.e(TAG, "param_track_location >> " + params.toString());
stopSelf();
mTimer.cancel();
}
@Override
public void onLocationChanged(Location location) {
}
@Override
public void onStatusChanged(String provider, int status, Bundle extras) {
}
@Override
public void onProviderEnabled(String provider) {
}
@Override
public void onProviderDisabled(String provider) {
}
/******************************/
private void fn_getlocation() {
locationManager = (LocationManager) getApplicationContext().getSystemService(LOCATION_SERVICE);
isGPSEnable = locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER);
isNetworkEnable = locationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER);
if (!isGPSEnable && !isNetworkEnable) {
Log.e(TAG, "CAN'T GET LOCATION");
stopSelf();
} else {
if (isNetworkEnable) {
location = null;
locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 1000, 0, this);
if (locationManager != null) {
location = locationManager.getLastKnownLocation(LocationManager.NETWORK_PROVIDER);
if (location != null) {
Log.e(TAG, "isNetworkEnable latitude" + location.getLatitude() + "\nlongitude" + location.getLongitude() + "");
latitude = location.getLatitude();
longitude = location.getLongitude();
track_lat = latitude;
track_lng = longitude;
// fn_update(location);
}
}
}
if (isGPSEnable) {
location = null;
locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 1000, 0, this);
if (locationManager != null) {
location = locationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER);
if (location != null) {
Log.e(TAG, "isGPSEnable latitude" + location.getLatitude() + "\nlongitude" + location.getLongitude() + "");
latitude = location.getLatitude();
longitude = location.getLongitude();
track_lat = latitude;
track_lng = longitude;
// fn_update(location);
}
}
}
Log.e(TAG, "START SERVICE");
trackLocation();
}
}
private class TimerTaskToGetLocation extends TimerTask {
@Override
public void run() {
mHandler.post(new Runnable() {
@Override
public void run() {
fn_getlocation();
}
});
}
}
// private void fn_update(Location location) {
//
// intent.putExtra("latutide", location.getLatitude() + "");
// intent.putExtra("longitude", location.getLongitude() + "");
// sendBroadcast(intent);
// }
}
AlarmReceive.java(廣播接收器)
public class AlarmReceive extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
Log.e("Service_call_" , "You are in AlarmReceive class.");
Intent background = new Intent(context, BookingTrackingService.class);
// Intent background = new Intent(context, GoogleService.class);
Log.e("AlarmReceive ","testing called broadcast called");
context.startService(background);
}
}
AndroidManifest.xml中
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<service
android:name=".ServiceAndBroadcast.BookingTrackingService"
android:enabled="true" />
<receiver
android:name=".ServiceAndBroadcast.AlarmReceive"
android:exported="false">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
</receiver>
'if(isNetworkEnable){'它可能是'if(!isNetworkEnable){'NOT NOT NOT else case。 ;) –
另外,需要檢查權限的可用性。 if(ActivityCompat.checkSelfPermission(this,Manifest.permission.ACCESS_FINE_LOCATION)!= PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this,Manifest.permission.ACCESS_COARSE_LOCATION)!= PackageManager.PERMISSION_GRANTED){return;}' –
看看這個博客帖子:http://android-developers.blogspot.ro/2011/06/deep-dive-into-location.html – Felix
見最新GoogleApiClient HTTP方法://stackoverflow.com/a/41981246/3496570 – Nepster