应用被杀死时,广播接收器未致电服务 [英] Broadcast Receiver not calling Service while app was killed

查看:69
本文介绍了应用被杀死时,广播接收器未致电服务的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的目标是重新启动服务,当应用程序处于后台甚至被扫荡从主页中杀死时。应用程式和当应用程序处于前台和后台时,服务运行良好,但是当我强行杀死应用程序(从主页清除)时,服务停止了工作。没关系,但是我实现了广播接收器以重新启动服务,但其(广播接收器)甚至都没有称为自身服务,而应用被强行杀死/从主页清除。

My target was Restarting the Service when app is in background or even killed from home page by sweeping. App & Service is working nice while app is in foreground and background but while I killed the app by force(sweeping out from home page), the Service stopped working. That's okay but I implemented a Broadcast Receiver to restart the Service but it seems like its (Broadcast Receiver) not even called itself or the Service while app was killed forcefully / sweeping from home page.

我的设备是:小米Redmi注意事项4

我在这里包括了我的代码:

I included my codes here :

MainActivity.java

package com.turzo.servicetest;

import android.app.ActivityManager;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.net.ConnectivityManager;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;

public class MainActivity extends AppCompatActivity {

    private String TAG = "ServiceTest";
    Intent mServiceIntent;
    private SensorService mSensorService;

    Context ctx;

    public Context getCtx() {
        return ctx;
    }



    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        ctx = this;
        registerRec();
        setContentView(R.layout.activity_main);

        mSensorService = new SensorService(getCtx());
        mServiceIntent = new Intent(getCtx(), mSensorService.getClass());
        if (!isMyServiceRunning(mSensorService.getClass())) {
            startService(mServiceIntent);
        }

    }

    private boolean isMyServiceRunning(Class<?> serviceClass) {
        ActivityManager manager = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);
        for (ActivityManager.RunningServiceInfo service : manager.getRunningServices(Integer.MAX_VALUE)) {
            if (serviceClass.getName().equals(service.service.getClassName())) {
                Log.i (TAG, true+"");
                return true;
            }
        }
        Log.i (TAG, false+"");
        return false;
    }


    @Override
    protected void onDestroy() {
       stopService(mServiceIntent);
        Log.i(TAG, "onDestroy!");
        super.onDestroy();

    }

    public void registerRec(){


        SensorRestarterBroadcastReceiver myreceiver = new SensorRestarterBroadcastReceiver();
        IntentFilter intentFilter = new IntentFilter();
        intentFilter.addAction(ConnectivityManager.CONNECTIVITY_ACTION);
        registerReceiver((BroadcastReceiver) myreceiver, intentFilter);
    }







}

SensorService.java

package com.turzo.servicetest;

import android.app.Service;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.net.ConnectivityManager;
import android.os.IBinder;
import android.support.annotation.Nullable;
import android.util.Log;

import java.util.Timer;
import java.util.TimerTask;


public class SensorService extends Service {
    public int counter=0;
    private String TAG = "ServiceTest";
    public SensorService(Context applicationContext) {
        super();
        Log.i(TAG , "here I am!");
    }

    public SensorService() {
    }

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

        startTimer();
        return START_STICKY;
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        Log.i(TAG , "ondestroy!");
        Intent broadcastIntent = new Intent("com.turzo.servicetest.ActivityRecognition.RestartSensor");
        sendBroadcast(broadcastIntent);
        stoptimertask();
    }

    private Timer timer;
    private TimerTask timerTask;
    long oldTime=0;
    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, 1000, 1000); //
    }

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

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

    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }


} 

SensorRestarterBroadcastReceiver.java

package com.turzo.servicetest;

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.util.Log;


public class SensorRestarterBroadcastReceiver extends BroadcastReceiver {

    @Override
    public void onReceive(Context context, Intent intent) {
        Log.i(SensorRestarterBroadcastReceiver.class.getSimpleName(), "Service Stops! Oooooooooooooppppssssss!!!!");

        context.startService(new Intent(context, SensorService.class));
    }

}

AndroidManifext.xml

    <?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.turzo.servicetest">

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        <activity android:name=".MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>


        <service
            android:name="com.turzo.servicetest.SensorService"
            android:enabled="true" >
        </service>

        <receiver
            android:name="com.turzo.servicetest.SensorRestarterBroadcastReceiver"
            android:enabled="true"
            android:exported="true"
            android:label="RestartServiceWhenStopped">
            <intent-filter>
                <action android:name="com.turzo.servicetest.ActivityRecognition.RestartSensor"/>
            </intent-filter>
        </receiver>


    </application>

</manifest> 


推荐答案

您应重新启动 Service onTaskRemoved()中。

  @Override
    public void onTaskRemoved(Intent rootIntent) {
        Intent restartService = new Intent(getApplicationContext(),
                this.getClass());
        restartService.setPackage(getPackageName());
        PendingIntent restartServicePI = PendingIntent.getService(
                getApplicationContext(), 1, restartService,
                PendingIntent.FLAG_ONE_SHOT);
        AlarmManager alarmService = (AlarmManager) getApplicationContext().getSystemService(Context.ALARM_SERVICE);
        alarmService.set(AlarmManager.ELAPSED_REALTIME, SystemClock.elapsedRealtime() + 1000, restartServicePI);
    }

注意:-从android O开始。您不能调用 startService

NOTE:- Starting from android O . You can not call startService.


startService()方法现在抛出IllegalStateException如果针对Android 8.0的应用尝试在不允许创建后台服务的情况下使用该方法。

The startService() method now throws an IllegalStateException if an app targeting Android 8.0 tries to use that method in a situation when it isn't permitted to create background services.

不适用于用户注意到的前台服务。它可以在后台运行,并在顶部显示通知。默认情况下,这些限制仅适用于面向Android 8.0(API级别26)或更高版本的应用。但是,即使该应用的目标API级别低于26,用户也可以从设置屏幕为任何应用启用这些限制中的大多数。因此,如果用户为低于API 26的限制启用了您的 Service 不起作用。

阅读背景执行限制

This does not apply to foreground services, which are noticeable to the user. It can run in background with a notification on top. By default, these restrictions only apply to apps that target Android 8.0 (API level 26) or higher. However, users can enable most of these restrictions for any app from the Settings screen, even if the app targets an API level lower than 26. So in case if user enables the restrictions for below API 26 your Service will not work.
Read Background Execution Limits.

因此,请尽量避免使用 Service 。如果符合要求,请使用 WorkManager

So Try to avoid using Service if you can . Make use of WorkManager if it fits the requirements.

这篇关于应用被杀死时,广播接收器未致电服务的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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