后台服务暂停,然后在OREO上自动重新启动 [英] Background service pause and start again automatically on OREO

查看:86
本文介绍了后台服务暂停,然后在OREO上自动重新启动的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经创建了一个后台服务,用于注册SCREEN_ON和SCREEN_OFF意向以使用广播接收器捕获事件,但是由于未知原因,有一段时间我的服务没有将意向传递给我的主应用程序.为了测试,我使用十秒计时器生成了日志文件,它是我的后台服务是否工作.我在下面附上了.我遇到一个问题,我的后台服务暂停了一段时间并自动启动.

I have created a background service for registering SCREEN_ON and SCREEN_OFF intent to catch an event using broadcast receiver but some time due to unknown reason my service does not pass intent to my main application. For testing i have generated log file using ten second timer that it is my background service working or not. Which i have attached below. I got a issue that my background service pause some time and start it automatically.

这是我的后台服务

public class MyBackgroundService extends Service {

    BroadcastReceiver receiver;
    private static final String LOG_TAG = "MyBackgroundService";

    @Override
    public void onCreate() {
        super.onCreate();
        Timber.i("Foreground Service OnCreate");
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {

        Timber.i("Start Foreground Service");

        receiver = new ScreenStateReceiver();
        registerReceiver(receiver,  new IntentFilter(Intent.ACTION_SCREEN_ON));
        registerReceiver(receiver, new IntentFilter(Intent.ACTION_SCREEN_OFF));

        if (intent.getAction().equals(Constants.STARTFOREGROUND_ACTION)) {

            Intent notificationIntent = new Intent(this, HomeActivity.class);

            PendingIntent pendingIntent = PendingIntent.getActivity(this, 0,
                    notificationIntent, 0);

            Notification notification = new NotificationCompat.Builder(this)
                    .setContentTitle("text")
                    .setTicker("text")
                    .setContentText("text")
                    .setSmallIcon(R.drawable.logo_icon)
                    .setContentIntent(pendingIntent)
                    .setOngoing(true).build();

            startForeground(Constants.NOTIFICATION_ID.FOREGROUND_SERVICE,
                    notification);

        }
        startTimer();

        return START_STICKY;
    }

    @Override
    public boolean onUnbind(Intent intent) {
        Timber.i("Foreground Service onUnbind");
        return super.onUnbind(intent);
    }

    @Override
    public void onTaskRemoved(Intent rootIntent) {
        Timber.i("Foreground Service onTaskRemoved");
        super.onTaskRemoved(rootIntent);
    }

    @Override
    public void onDestroy() {
        stopForeground(true);
        Timber.i("Foreground Service onDestroy");
        stoptimertask();
        super.onDestroy();
    }

    @Override
    public IBinder onBind(Intent intent) {
        // Used only in case of bound services.
        return null;
    }

    private Timer timer;
    private TimerTask timerTask;
    public void startTimer() {
        //set a new Timer
        timer = new Timer();

        //initialize the TimerTask's job
        initializeTimerTask();

        //schedule the timer, to wake up every 1 second
        timer.schedule(timerTask, 10000, 10000); //
    }

    /**
     * it sets the timer to print the counter every x seconds
     */
    public void initializeTimerTask() {
        timerTask = new TimerTask() {
            public void run() {
                Timber.i("Timer");
            }
        };
    }

    /**
     * not needed
     */
    public void stoptimertask() {
        //stop the timer, if it's not already null
        if (timer != null) {
            timer.cancel();
            timer = null;
        }
    }

}

这是我的广播接收器

public class ScreenStateReceiver extends BroadcastReceiver {

    public ScreenStateReceiver(){
    }

    @Override
    public void onReceive(Context context, Intent intent) {

        String action = intent.getAction();
        if(action.equals(Intent.ACTION_SCREEN_OFF)){

            Timber.i("Screen OFF");
       }
        else if (intent.getAction().equals(Intent.ACTION_SCREEN_ON)) {
            Timber.i("Screen ON");
        }
    }
}

Menifest,xml文件声明

Menifest,xml file declaration

<uses-permission android:name="android.permission.WAKE_LOCK"/>

    <service android:name=".service.MyBackgroundService"/>

    <receiver android:name=".receiver.ScreenStateReceiver" android:enabled="true" android:exported="true">
        <intent-filter >
            <action android:name="android.intent.action.SCREEN_OFF" />
            <action android:name="android.intent.action.SCREEN_ON" />
        </intent-filter>
    </receiver>

我正在使用意图启动服务

I am starting Service using intent

Intent service = new Intent(getContext().getApplicationContext(), MyBackgroundService.class);

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {

    service.setAction(Constants.STARTFOREGROUND_ACTION);
    getContext().getApplicationContext().startForegroundService(service);
}
else{

    service.setAction(Constants.MAIN_ACTION);
    getContext().getApplicationContext().startService(service);
}

这是我的日志文件的图片 日志文件 使用此日志文件,您可以看到后台服务正在停止并自动启动. 请帮助我解决此问题.

Here this picture of my log file LOG FILE using this log file you can see background service is stop and start automatically. please help me resolve this issue.

推荐答案

奥利奥(Oreo)以后对服务有限制,只有在应用程序处于前台时,才可以通过调用startService()来启动服务.当您退出应用程序(应用程序在后台)时,它会显示几分钟的窗口,在该应用程序中可以运行该服务.在窗口结束时,应用程序被认为是空闲的,此时系统停止了后台服务.为了甚至在后台运行服务,要么必须实现前台服务,要么必须使用作业调度程序等.

There is a restriction for service in Oreo onward, We can start a service by calling startService() only when the application is in foreground. When you exit from the app (app is in background), then it has a window of several minute, in that app can run the service. At the end of window, app considered to be idle,that time system stop the background service. In order to achieve run a service even in background, either we have to implement foreground service or we have to use job scheduler etc.

这篇关于后台服务暂停,然后在OREO上自动重新启动的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆