Java 在android服务中解决长时间运行的服务的最佳方案是在几个小时后关机
业务场景: 业务场景的目标是在后台每隔15分钟向服务器更新一次经度和纬度 我使用过Alaram Manager(当android操作系统关闭服务时重新启动服务) 我在下面分享了我的代码:Java 在android服务中解决长时间运行的服务的最佳方案是在几个小时后关机,java,android,android-studio,geolocation,Java,Android,Android Studio,Geolocation,业务场景: 业务场景的目标是在后台每隔15分钟向服务器更新一次经度和纬度 我使用过Alaram Manager(当android操作系统关闭服务时重新启动服务) 我在下面分享了我的代码: public class GoogleClientFusedApiService extends Service implements GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedL
public class GoogleClientFusedApiService extends Service implements
GoogleApiClient.ConnectionCallbacks,
GoogleApiClient.OnConnectionFailedListener,
LocationListener {
private static final String TAG = "LocationService";
private boolean currentlyProcessingLocation = false;
private LocationRequest locationRequest;
private GoogleApiClient googleApiClient;
public static Boolean isRunning = false;
// The minimum time between updates in milliseconds
private static final long MIN_TIME_BW_UPDATES = 1000 * 60 * 1; // 15 minutes
@Override
public void onCreate() {
super.onCreate();
}
Handler mHandler = new Handler();
Runnable mHandlerTask = new Runnable() {
@Override
public void run() {
if (!isRunning) {
startTracking();
}
mHandler.postDelayed(mHandlerTask, 1000 * 60 * 2);
}
};
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
// if we are currently trying to get a location and the alarm manager has called this again,
// no need to start processing a new location.
if (!currentlyProcessingLocation) {
currentlyProcessingLocation = true;
//startTracking();
mHandlerTask.run();
}
//alarm.setAlarm(this);
return START_STICKY;
// return START_NOT_STICKY;
}
private void startTracking() {
Log.d(TAG, "startTracking");
if (GooglePlayServicesUtil.isGooglePlayServicesAvailable(this) == ConnectionResult.SUCCESS) {
googleApiClient = new GoogleApiClient.Builder(this)
.addApi(LocationServices.API)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.build();
if (!googleApiClient.isConnected() || !googleApiClient.isConnecting()) {
googleApiClient.connect();
}
} else {
Log.e(TAG, "unable to connect to google play services.");
}
}
@Override
public void onDestroy() {
super.onDestroy();
}
@Override
public IBinder onBind(Intent intent) {
return null;
}
@Override
public void onLocationChanged(Location location) {
if (location != null) {
String latitude = String.valueOf(location.getLatitude());
String longtitude = String.valueOf(location.getLongitude());
LocationUpdateServerCall locationUpdateServerCall = new LocationUpdateServerCall(getApplicationContext());
locationUpdateServerCall.pushLocationUpdateServerCall(latitude, longtitude);
Log.e(TAG, "position: " + location.getLatitude() + ", " + location.getLongitude() + " accuracy: " + location.getAccuracy());
// we have our desired accuracy of 500 meters so lets quit this service,
// onDestroy will be called and stop our location uodates
/* if (location.getAccuracy() < 10.0f) {
stopLocationUpdates();
}*/
}
}
private void stopLocationUpdates() {
if (googleApiClient != null && googleApiClient.isConnected()) {
googleApiClient.disconnect();
}
mHandler.removeCallbacks(mHandlerTask);
}
/**
* 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) {
Log.d(TAG, "onConnected");
locationRequest = LocationRequest.create();
locationRequest.setInterval(MIN_TIME_BW_UPDATES); // milliseconds
locationRequest.setFastestInterval(MIN_TIME_BW_UPDATES); // the fastest rate in milliseconds at which your app can handle location updates
locationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
locationRequest.setSmallestDisplacement(10); // distance travelled
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
// TODO: Consider calling
// ActivityCompat#requestPermissions
// here to request the missing permissions, and then overriding
// public void onRequestPermissionsResult(int requestCode, String[] permissions,
// int[] grantResults)
// to handle the case where the user grants the permission. See the documentation
// for ActivityCompat#requestPermissions for more details.
return;
}
if (googleApiClient.isConnected()) {
LocationServices.FusedLocationApi.requestLocationUpdates(
googleApiClient, locationRequest, this);
} else {
return;
}
}
@Override
public void onConnectionFailed(ConnectionResult connectionResult) {
Log.e(TAG, "onConnectionFailed");
startTracking();
/* stopLocationUpdates();
stopSelf();*/
}
@Override
public void onConnectionSuspended(int i) {
Log.e(TAG, "GoogleApiClient connection has been suspend");
startTracking();
}
//Start Alarm(Start Location Updates on Background)
@Override
public void onTaskRemoved(Intent rootIntent) {
Intent restartServiceTask = new Intent(getApplicationContext(), this.getClass());
restartServiceTask.setPackage(getPackageName());
PendingIntent restartPendingIntent = PendingIntent.getService(getApplicationContext(), 1, restartServiceTask, PendingIntent.FLAG_ONE_SHOT);
AlarmManager myAlarmService = (AlarmManager) getApplicationContext().getSystemService(Context.ALARM_SERVICE);
myAlarmService.setRepeating(
AlarmManager.ELAPSED_REALTIME,
SystemClock.elapsedRealtime(), 1000 * 60 * 1
, restartPendingIntent);
super.onTaskRemoved(rootIntent);
}
// Canacel Alarm (Stop Location Update)
public void cancelAlarm(Activity context) {
Intent intent = new Intent(context, GoogleClientFusedApiService.class);
PendingIntent sender = PendingIntent.getBroadcast(context, 0, intent, 0);
AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
alarmManager.cancel(sender);
}
公共类GoogleClientFusedApiService扩展服务实现
GoogleAppClient.ConnectionCallbacks,
GoogleAppClient.OnConnectionFailedListener,
位置侦听器{
私有静态最终字符串TAG=“LocationService”;
私有布尔值currentlyProcessingLocation=false;
私人位置请求位置请求;
私人GoogleapClient GoogleapClient;
公共静态布尔值isRunning=false;
//更新之间的最短时间(以毫秒为单位)
私有静态最终长分钟时间\u BW\u更新=1000*60*1;//15分钟
@凌驾
public void onCreate(){
super.onCreate();
}
Handler mHandler=新的Handler();
Runnable mHandlerTask=新的Runnable(){
@凌驾
公开募捐{
如果(!正在运行){
开始跟踪();
}
mHandler.postDelayed(mHandlerTask,1000*60*2);
}
};
@凌驾
公共int onStartCommand(Intent Intent、int标志、int startId){
//如果我们目前正试图获取一个位置,而报警管理器又再次调用了该位置,
//无需开始处理新位置。
如果(!currentlyProcessingLocation){
currentlyProcessingLocation=true;
//开始跟踪();
mHandlerTask.run();
}
//报警。设置报警(此);
返回开始时间;
//返回开始时间不粘;
}
私有void startTracking(){
日志d(标签“开始跟踪”);
if(GooglePlayServicesUtil.isGooglePlayServicesAvailable(this)=ConnectionResult.SUCCESS){
GoogleapClient=新的GoogleapClient.Builder(此)
.addApi(LocationServices.API)
.addConnectionCallbacks(此)
.addOnConnectionFailedListener(此)
.build();
如果(!googleApiClient.isConnected()| |!googleApiClient.isConnecting()){
googleApiClient.connect();
}
}否则{
Log.e(标签“无法连接到google play服务”);
}
}
@凌驾
公共空间{
super.ondestory();
}
@凌驾
公共IBinder onBind(意向){
返回null;
}
@凌驾
已更改位置上的公共无效(位置){
如果(位置!=null){
String latitude=String.valueOf(location.getLatitude());
String longtudent=String.valueOf(location.getLongitude());
LocationUpdateServerCall LocationUpdateServerCall=新建LocationUpdateServerCall(getApplicationContext());
locationUpdateServerCall.pushLocationUpdateServerCall(纬度、经度);
Log.e(标记,“位置:”+location.getLatitude()+”,“+location.getLatitude()+”精度:“+location.getAccuracy()”);
//我们期望的精度为500米,所以让我们退出这项服务,
//onDestroy将被调用并停止我们的定位
/*if(location.getAccurance()<10.0f){
stopLocationUpdates();
}*/
}
}
私有void stopLocationUpdates(){
if(googleApiClient!=null&&googleApiClient.isConnected()){
googleApiClient.disconnect();
}
mHandler.removeCallbacks(mHandlerTask);
}
/**
*请求连接时由位置服务调用
*客户端成功完成。此时,您可以
*请求当前位置或开始定期更新
*/
@凌驾
未连接的公共空间(捆绑包){
日志d(标签“未连接”);
locationRequest=locationRequest.create();
locationRequest.setInterval(最小时间更新);//毫秒
locationRequest.SetFastTestInterval(MIN_TIME_BW_UPDATES);//应用程序处理位置更新的最快速率(以毫秒为单位)
locationRequest.setPriority(locationRequest.PRIORITY\u高精度);
位置请求。设置最小位移(10);//行驶距离
if(ActivityCompat.checkSelfPermission(this,Manifest.permission.ACCESS\u FINE\u LOCATION)!=PackageManager.permission\u已授予和&ActivityCompat.checkSelfPermission(this,Manifest.permission.ACCESS\u LOCATION)!=PackageManager.permission\u已授予){
考虑到呼叫
//ActivityCompat#请求权限
//在此处请求缺少的权限,然后覆盖
//public void onRequestPermissionsResult(int-requestCode,字符串[]权限,
//int[]格兰特结果)
//处理用户授予权限的情况。请参阅文档
//对于ActivityCompat,请请求权限以获取更多详细信息。
返回;
}
if(googleApiClient.isConnected()){
LocationServices.FusedLocationApi.RequestLocationUpdate(
GoogleAppClient、locationRequest、this);
}否则{
返回;
}
}
@凌驾
公共无效onConnectionFailed(ConnectionResult ConnectionResult){
Log.e(标记“onConnectionFailed”);
开始跟踪();
/*stopLocationUpdates();
stopSelf()*/
}
@凌驾
公共空间连接暂停(int i){
Log.e(标记“GoogleAppClient连接已暂停”);
开始跟踪();
}
//启动警报(后台启动位置更新)
@凌驾
公共无效onTaskRemove