1

I would like to start a foreground service, as soon as the Acitvity gets visible. I tried this, by overriding the onResume, but when I compile and run my app, it gets called even if the screen is turned off.

If the screen is turned off, I get IllegalStateException if I try to start a foreground service.

I wrapped the code inside a try-catch block. It mostly works, but sometimes it is not called after the screen gets visible, just right before that.

How is it possible to run a code every time when my Activity is visible by the user?

Iter Ator
  • 8,226
  • 20
  • 73
  • 164
  • 1
    `onResume()` is your best shot. Check whether there are any other triggers which starts the service. Try putting a debug point or a log to `onResume()` and check whether it really gets called when the app is in background. I highly doubt it. – Roshana Pitigala Nov 02 '20 at 14:23
  • Can you give more context? Why do you get `IllegalStateException` in `Service`? What is the root cause of it? Never met such an exception in services. – Nazarii Moshenskiy Nov 07 '20 at 03:51
  • Or share the code and I will try to reproduce it – Nazarii Moshenskiy Nov 07 '20 at 03:53
  • Can you share the exception stack trace. It is helpful to find root cause. I don't think it's a problem of `onResume()` – ShreeshaDas Nov 08 '20 at 06:04
  • you async method inside onStart then start your foreground service there – Vishwajeet Barve Nov 08 '20 at 09:33
  • There is NO such "single" method in Android framework, you will have to use several callbacks to be 100% sure. But that is everyday reality of Android programming, right? – Gordon Freeman Nov 09 '20 at 13:55

3 Answers3

1

Well onResume is not you method. Here is a pretty neet explanation of basic differences between onCreate and onStart

As you've already understood the method you need is onStart because it gets called directly after the activity becomes visible to a user.

Pavlo Ostasha
  • 14,527
  • 11
  • 35
  • `onStart` does not guarantee that the activity is **visible**. See my answer below. – Tobi Nov 07 '20 at 22:32
1

For Foreground Services it's not important from which callback of Activity you start them, because they can work even if app is working background.

You can get IllegalStateException if you start Foreground Service without calling startForeground method. Make sure the code of your Service contains code similar to the following:

class ExampleService : Service() {

   override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
        // prepare pending intent
        val pendingIntent = val pendingIntent: PendingIntent =
        Intent(this, ExampleActivity::class.java).let { notificationIntent ->
            PendingIntent.getActivity(this, 0, notificationIntent, 0)
        }

        // build notification to display while foreground service is running
        val notification = 
            NotificationCompat.Builder(context, "channel_id")
               .setContentTitle("Title")
               .setContentText("Text")
               .setContentIntent(pendingIntent)
               .setSmallIcon(R.drawable.small_icon)
               .build()

        val notificationId = 42

        // call tell the system run your service as foreground service
        startForeground(notificationId, notification)
     
        // implement the business logic  
        ....
    }
   
}

You can find more info about Foreground Services here: https://developer.android.com/guide/components/foreground-services

bobrusha
  • 36
  • 2
0

Well actually also onStart can be called before the content is visible. I had the same issue when I wanted to start an animation only after it is really visible..

If you want to be 100% sure that the view is visible before running your code, you can do the following:

        requireActivity().getWindow().getDecorView().post(new Runnable() {
            @Override
            public void run() {
                // your code
            }
        });

This will create a runnable that is queued up and runs after all other UI components are loaded. You can call this in onViewCreated(), onResume() or onStart() it doesn't matter.

Tobi
  • 858
  • 7
  • 15