Android后台服务在屏幕休眠保持运行

Android App中的Service可以保持后台运行,比如音乐播放就是Service的典型应用,在开发移动APP时,很多业务场景需要用到Service保持在后台运行,在实现过程中让Service在屏幕休眠下继续保持运行,往往没有按照预期运行,下面例程中实现后台服务定时上报GPS数据,尝试多种方式勉强实现。

1、将服务设置为前台服务,在屏幕左上角显示一个图标

Android后台服务在屏幕休眠保持运行_第1张图片
在Service的onStartCommand方法里面,将服务放置前台
Android后台服务在屏幕休眠保持运行_第2张图片
在onDestroy方法里面
Android后台服务在屏幕休眠保持运行_第3张图片

2、只将Service放置到前台前提下,继续设置电源控制

在onCreate方法里面,添加电源控制
Android后台服务在屏幕休眠保持运行_第4张图片

在onDestroy方法里面
Android后台服务在屏幕休眠保持运行_第5张图片

3、在设置1、2前题下,继续实现后台播放无声音乐

在onStartCommand添加音乐播放音乐
Android后台服务在屏幕休眠保持运行_第6张图片
在onDestroy方法里面
Android后台服务在屏幕休眠保持运行_第7张图片

4、设置前台服务可以在APP退出后可以释放资源

在onStartCommand返回START_NOT_STICKY,否则前台服务无法退出
Android后台服务在屏幕休眠保持运行_第8张图片

5、使用高德地图API定时采集GPS数据

@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());
                }
            }
        }
    };
}

你可能感兴趣的:(Android)