Search code examples
androidandroid-activitybluetooth-lowenergyforeground-service

How can i open a activity from a foreground service (Find phone smartwatch function)


I'm working on a find phone feature on my company's BLE smartwatch.

The user accesses the option on a smartwatch and it sends a Bluetooth event informing that the user accessed the "find phone" option.

I use a foreground service to send and receive information from the watch.

According to the android documentation, it is not allowed to display a activity from a foreground.

https://developer.android.com/guide/components/activities/background-starts

However, the Samsung Watch has exactly the same function, and they display a screen, even with the apps closed.

Galaxy Watch - Find Phone

How do they do this?

Is it possible to do the same in my app?


Solution

  • This can be achieved by the following steps

    1. Grant permission to overlay the app on top of other apps.
    • Add permission

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

      in the AndroidManifest.xml file.

    • From app settings allow "Appear on Top" to allow your app to draw over other apps.

    1. Add flags Intent.FLAG_ACTIVITY_NEW_TASK, Intent.FLAG_ACTIVITY_SINGLE_TOP to Intent when launching the activity from service like this on the event

      val intent = Intent(applicationContext, MainActivity::class.java)

      intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)

      intent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP)

      startActivity(intent)

    to launch the activity (in my case it is MainActivity)

    NB:

    • Intent.FLAG_ACTIVITY_NEW_TASK: This flag is crucial when launching an activity from a background context (like a foreground service). It ensures that the activity is launched in a new task, which is necessary for proper behavior when your app isn't in the foreground.
    • Intent.FLAG_ACTIVITY_SINGLE_TOP: This flag helps optimize the launch process. If the target activity (MainActivity) is already at the top of the activity stack, it won't be recreated. Instead, the existing instance will receive the new intent in its onNewIntent() method. This prevents unnecessary duplication and maintains a smoother user experience.