Background service is not working in Oreo

旧巷老猫 提交于 2020-01-09 07:06:08

问题


I want to run my app in background if I kill the app instance also. But after I kill my app the service also stops working. Here is my code please any one help me to solve my issue.

I followed this link for running in the background but it is not working if I remove the instance. Please can any one show me how to run a background service if the instance is removed also?

This is my MainActivity

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    ctx = this;
    setContentView(R.layout.activity_main);
    Intent alarmIntent = new Intent(MainActivity.this, AlarmReceiver.class);
    pendingIntent = PendingIntent.getBroadcast(MainActivity.this, ALARM_REQUEST_CODE, alarmIntent, 0);
    mSensorService = new SensorService(getCtx());
    mServiceIntent = new Intent(getCtx(), mSensorService.getClass());
    if (!isMyServiceRunning(mSensorService.getClass())) {
        startService(mServiceIntent);
    }
}

Ths is my service class

   public class SensorService extends Service{

public int counter=0;
public SensorService(Context applicationContext) {
    super();
    Log.i("HERE", "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("EXIT", "ondestroy!");
    Intent broadcastIntent = new Intent("uk.ac.shef.oak.ActivityRecognition.RestartSensor");
    sendBroadcast(broadcastIntent);
  }

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("in timer", "in timer ++++  "+ (counter++));
        }
    };
}

/**
 * not needed
 */


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

}


回答1:


Its a long story. I have gone through it. Still implemented it. Now my service runs on every boot_complete event and keeps running all the time ( with a notification ).

  • Official Documentation:

Big NO. Google android developer documentation is poor, with no proper sample example too. It is theoretical and just theoretical. Keep reading if interested

https://developer.android.com/about/versions/oreo/background

Synopsis 1: You can only receive BOOT_COMPLETE and only few broadcasts in traditional receiver. Rest all broadcast receivers you need to implement runtime in a service by registering them through a code from service which always runs.

Synopsis 2: Again, you can not have always running processes in or above 8.0 (Oreo)... To achieve always running process... Create a Intentservice with proper notification of type ongoing and make OnStartCommand START_STICKY and register receiver with code in OnCreate

How to implement it : I have implemented it take reference from here : Oreo: Broadcast receiver Not working

Now Your Question : I want to run my app in background if it kills the app instance also.

With the help of above implementation link of my own you can achieve it

*Terms and conditions

You device must have proper android operating system released and burnt as it is.

Yes, I am using android :

No... You are Using Funtouch OS : VIVO ( By modifying Android)

There are many devices in market COLOR OS : OPPO ( By modifying Android) .... ....

  1. Already google has made it complicated... version by version....
  2. With no proper documentation and sample codes....
  3. And Now Independent mobile device manufacturers making a lot of changes to allow only selective applications run in background like WhatsApp, Facebook, Google Twitter Instagram

Now you will ask a developer question If these app runs in background then I can make my app run in background too....

No... They are OS based modifications to check if a service is from allowed vendors then only it can be alive there in background. If they will not allow these vendors then no one take phones which does not run these famous social apps.

Hushhhhhhhh.......




回答2:


Oreo Introduced

new Concept PIP (Picture in Picture Mode ) and it have categories services control by making channels and priority to them.you have to change the code just for oreo to create notifications and services

read about google developers documentation carefully here https://developer.android.com/guide/topics/ui/notifiers/notifications both java and kotlin code is available here to create notification in oreo

https://developer.android.com/training/notify-user/build-notification

it was my effort to find the solution after searching and sharing with you.

here is some sample code :

NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(this, CHANNEL_ID)
    .setSmallIcon(R.drawable.notification_icon)
    .setContentTitle("My notification")
    .setContentText("Much longer text that cannot fit one line...")
    .setStyle(new NotificationCompat.BigTextStyle()
            .bigText("Much longer text that cannot fit one line..."))
    .setPriority(NotificationCompat.PRIORITY_DEFAULT);

for creating channels write this code:

private void createNotificationChannel() {
// Create the NotificationChannel, but only on API 26+ because
// the NotificationChannel class is new and not in the support library
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
    CharSequence name = getString(R.string.channel_name);
    String description = getString(R.string.channel_description);
    int importance = NotificationManager.IMPORTANCE_DEFAULT;
    NotificationChannel channel = new NotificationChannel(CHANNEL_ID, name, importance);
    channel.setDescription(description);
    // Register the channel with the system; you can't change the importance
    // or other notification behaviors after this
    NotificationManager notificationManager = getSystemService(NotificationManager.class);
    notificationManager.createNotificationChannel(channel);
}

}

you can see full detials for push notifications and sending messages by clicking on the above links.




回答3:


You need to create ForegroundService in order continue processing when your app is killed, as follows:

 public class SensorService extends Service{

    private PowerManager.WakeLock wakeLock;
    @Override
    public void onCreate() {
        super.onCreate();

        //wake lock is need to keep timer alive when device goes to sleep mode          
        final PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE);
        wakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "PARTIAL_WAKE_LOCK_TAG");
        createNotificationChannel(this);
        Notification notification = new NotificationCompat.Builder(this, "NOTIFICATION_CHANNEL").setSmallIcon
                (<icon>).setContentTitle("Title")
                .setContentText("Content").build();

        startForeground(1001, notification);
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        if (wakeLock.isHeld()) {
            wakeLock.release();
        }

    }

     public void createNotificationChannel() {
        // Create the NotificationChannel, but only on API 26+ because
        // the NotificationChannel class is new and not in the support library
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {

            CharSequence name = "Channel name";
            String description = "Description";
            int importance = NotificationManager.IMPORTANCE_DEFAULT;
            NotificationChannel channel = new NotificationChannel("NOTIFICATION_CHANNEL", name, importance);
            channel.setDescription(description);
            NotificationManager notificationManager = getApplicationContext().getSystemService(NotificationManager.class);
            notificationManager.createNotificationChannel(channel);
        }
    }
}

To start the service:

Intent i = new Intent(context, SensorService.class);
ContextCompat.startForegroundService(context, i)

Note:

  • You cannot run service endlessly with this approach. During doze mode if OS recognizes it as CPU intensive then your Service will be terminated.
  • You need to call stopSelf() when your Timer task has been executed successfully.


来源:https://stackoverflow.com/questions/51241184/background-service-is-not-working-in-oreo

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!