Android App中的Service可以保持后台运行,比如音乐播放就是Service的典型应用,在开发移动APP时,很多业务场景需要用到Service保持在后台运行,在实现过程中让Service在屏幕休眠下继续保持运行,往往没有按照预期运行,下面例程中实现后台服务定时上报GPS数据,尝试多种方式勉强实现。
在Service的onStartCommand方法里面,将服务放置前台
在onDestroy方法里面
在onStartCommand添加音乐播放音乐
在onDestroy方法里面
在onStartCommand返回START_NOT_STICKY,否则前台服务无法退出
@Override
public void onCreate() {
super.onCreate();
PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE);
wakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, TimerLocationService.class.getName());
wakeLock.acquire();
locationClient = new AMapLocationClient(this.getApplicationContext());
locationClient.setLocationOption(getDefaultOption());
locationClient.setLocationListener(locationListener);
// 启动定位
locationClient.startLocation();
IntentFilter filter= new IntentFilter();
filter.addAction(Intent.ACTION_TIME_TICK);
registerReceiver(receiver,filter);
Util.service = this;
}
完全实现1-5中的代码,可以保证服务在屏幕休眠后保持运行,后台播放无声音乐缺点是比较耗电。
package com.hk.ecology.service;
import android.app.Notification;
import android.app.PendingIntent;
import android.app.Service;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.graphics.BitmapFactory;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.media.MediaPlayer;
import android.os.Bundle;
import android.os.Handler;
import android.os.IBinder;
import android.os.PowerManager;
import android.util.Log;
import com.amap.api.location.AMapLocation;
import com.amap.api.location.AMapLocationClient;
import com.amap.api.location.AMapLocationClientOption;
import com.amap.api.location.AMapLocationListener;
import com.hk.ecology.activity.LoadingActivity;
import com.hk.ecology.logic.HttpCallBack;
import com.hk.ecology.logic.HttpRequest;
import com.hk.ecology.logic.RequestCodeSet;
import com.hk.ecology.model.BaseModel;
import com.hk.ecology.model.WxOrderInfo;
import com.hk.ecology.receiver.CheckReceiver;
import com.hk.ecology.R;
import com.hk.ecology.util.SPUtil;
import com.hk.ecology.util.Util;
import java.util.List;
import java.util.Timer;
import java.util.TimerTask;
public class TimerLocationService extends Service implements HttpCallBack, RequestCodeSet, MediaPlayer.OnCompletionListener {
private AMapLocationClientOption locationOption = new AMapLocationClientOption();
private AMapLocationClient locationClient = null;
public static TimerLocationService instance = null;
private final BroadcastReceiver receiver = new CheckReceiver();
private MediaPlayer mMediaPlayer;
private PowerManager pm;
private PowerManager.WakeLock wakeLock = null;
public TimerLocationService() {
TimerLocationService.instance = this;
}
@Override
public void onCreate() {
super.onCreate();
PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE);
wakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, TimerLocationService.class.getName());
wakeLock.acquire();
locationClient = new AMapLocationClient(this.getApplicationContext());
locationClient.setLocationOption(getDefaultOption());
locationClient.setLocationListener(locationListener);
// 启动定位
locationClient.startLocation();
IntentFilter filter= new IntentFilter();
filter.addAction(Intent.ACTION_TIME_TICK);
registerReceiver(receiver,filter);
Util.service = this;
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
//id = intent.getStringExtra("id");
Notification.Builder builder = new Notification.Builder(this.getApplicationContext());
Intent nfIntent = new Intent(this, LoadingActivity.class);
builder.setContentIntent(PendingIntent.getActivity(this, 0, nfIntent, 0))
.setLargeIcon(BitmapFactory.decodeResource(this.getResources(), R.drawable.ic_default_head))
.setContentTitle("古方红糖-绿色农产品")
.setSmallIcon(R.mipmap.ic_launcher)
.setContentText("发货跟踪")
.setWhen(System.currentTimeMillis());
Notification notification = builder.build();
startForeground(startId, notification);
mMediaPlayer = MediaPlayer.create(getApplicationContext(), R.raw.no_notice);
mMediaPlayer.setLooping(true);
if (mMediaPlayer != null && !mMediaPlayer.isPlaying()) {
mMediaPlayer.setOnCompletionListener(this);
mMediaPlayer.start();
}
//flags = START_STICKY;
//return super.onStartCommand(intent, flags, startId);
return START_NOT_STICKY;
}
public void requestServer(double longitude,double latitude) {
String loginId = Util.fmtStr(SPUtil.getString("loginId"));
String password = Util.fmtStr(SPUtil.getString("password"));
Log.e("requestServer######################################","loginId="+loginId+",password="+password);
if(!Util.isNull(loginId)) {
HttpRequest.getInstance().track(this, this, String.valueOf(longitude), String.valueOf(latitude), "1");
}
}
@Override
public void onCompletion(MediaPlayer mp) {
Log.e("######################################","onCompletion");
//Location myLoc = locationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER);
//HttpRequest.getInstance().track(this, this,id,String.valueOf(myLoc.getLongitude()),String.valueOf(myLoc.getLatitude()),"1");
}
@SuppressWarnings("deprecation")
@Override
public void onDestroy() {
exitService();
super.onDestroy();
}
public void exitService()
{
stopForeground(true);
if (mMediaPlayer != null) {
mMediaPlayer.stop();
}
if (wakeLock != null) {
wakeLock.release();
wakeLock = null;
}
this.stopSelf();
}
@Override
public IBinder onBind(Intent intent) {
return null;
}
@Override
public void onSuccess(BaseModel result) {
if(result != null)
{
List<WxOrderInfo> orderList = (List<WxOrderInfo>)result.getResult();
Log.e("orderList--------------------------------------",orderList.toString());
String orderId = "";
for(WxOrderInfo ord:orderList)
{
orderId = orderId + ord.getId() + ",";
}
if(orderId.endsWith(","))
orderId = orderId.substring(0,orderId.length()-1);
SPUtil.saveString("orderId",orderId);
}
}
@Override
public void onFailure(BaseModel result) {
}
@Override
public void onFinish(BaseModel result) {
}
private AMapLocationClientOption getDefaultOption(){
AMapLocationClientOption mOption = new AMapLocationClientOption();
mOption.setLocationMode(AMapLocationClientOption.AMapLocationMode.Hight_Accuracy);
mOption.setGpsFirst(true);//设置GPS定位优先
mOption.setHttpTimeOut(30000);//设置网络请求超时时间
mOption.setInterval(10000);//设置定位间隔。默认为2秒
mOption.setNeedAddress(true);//设置是否返回逆地理地址信息。默认是true
mOption.setOnceLocation(false);//设置是否单次定位。默认是false
AMapLocationClientOption.setLocationProtocol(AMapLocationClientOption.AMapLocationProtocol.HTTP);//设置网络请求的协议。可选HTTP或者HTTPS。默认为HTTP
mOption.setLocationCacheEnable(false); //设置是否使用缓存定位,默认为true
return mOption;
}
AMapLocationListener locationListener = new AMapLocationListener() {
@Override
public void onLocationChanged(AMapLocation loc) {
Log.e("locationListener--------------------------------------",loc.toString());
if (null != loc) {
if(loc.getLongitude()!=0.0 && loc.getLatitude() != 0.0){
requestServer(loc.getLongitude(),loc.getLatitude());
}
}
}
};
}