我正在创建一个将在其自己的进程中运行的后台服务。它应该允许我听取设备位置是否改变。我应该能够在通知用户界面之前更改移动距离等标准。在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