Broadcast Receiver не вызывает службу, когда приложение было убито - PullRequest
0 голосов
/ 18 мая 2018

Моей целью было Перезапуск службы , когда приложение работает в фоновом режиме или даже убито с домашней страницы путем подметания.App & Service работает хорошо, пока приложение находится на переднем плане и в фоне, но пока я принудительно убивал приложение (выметая с домашней страницы), Service перестал работать.Это нормально, но я реализовал Broadcast Receiver для перезапуска Service , но похоже, что его (Broadcast Receiver) даже не называется сам или Служба пока приложение было принудительно убито / сметается с домашней страницы.

Мое устройство: Xiaomi Redmi Note 4

Я включил здесь свои коды:

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> 

1 Ответ

0 голосов
/ 18 мая 2018

Вы должны перезагрузить 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.

Метод startService () теперь генерирует исключение IllegalStateException, если приложение, ориентированное на Android 8.0, пытается использовать этот метод в ситуации, когда ему не разрешено создавать фоновые службы..

Это не относится к приоритетным службам, которые заметны для пользователя.Он может работать в фоновом режиме с уведомлением сверху.По умолчанию эти ограничения применяются только к приложениям, ориентированным на Android 8.0 (уровень API 26) или выше.Однако пользователи могут включить большинство этих ограничений для любого приложения на экране «Настройки», даже если приложение предназначено для уровня API ниже 26. Так что в случае, если пользователь включает ограничения для API ниже 26, Service не будет работать.
Чтение Пределы выполнения фона .

Поэтому старайтесь избегать использования Service, если можете.Используйте WorkManager , если он соответствует требованиям.

...