-
Android 13 - FGS Task Manager프로그래밍/Android 2022. 5. 11. 19:11반응형
What it is?
- FGS
- Foreground Service
- FGS Task Manager
- Regardless of target SDK version.
- Android 13 allows users to stop foreground services.
더보기Foreground services
Foreground services perform operations that are noticeable to the user.
It show a status bar notification, so that users are actively aware that your app is performing a task in the foreground and is consuming system resources. The notification cannot be dismissed unless the service is either stopped or removed from the foreground.
Examples of apps that would use foreground services include the following:
- A music player app that plays music in a foreground service. The notification might show the current song that is being played.
- A fitness app that records a user's run in a foreground service, after receiving permission from the user. The notification might show the distance that the user has traveled during the current fitness session.
How?
- Foreground Services (FGS) Task Manager
- New UI on notification drawer
- Shows a list of apps that are currently running a foreground service.
- On Android 13 device
Why?
- Foreground service needs to start with notification.
- From Android 13,
- users are now able to swipe away the notification.
- users can select it doesn't allow post notifications included FGS's.
- Service needs to be aware but the user can forget if something is still running in the background. This can be abuse. To solve this problem Android 13 allows the user stops foreground service.
User action stops
When the user presses the Stop button next to your app in the FGS Task Manager, then your entire app stops, not just the running foreground service.
Comparing behavior with "swipe up" and "force stop" user actions
"swipe up" : Finish the application from the Recents screen
"force stop" : Finish the application for a misbehaving app. ex) crash, won't response
Comparing application behavior
FGS Task Manager Swipe up Force stop Immediately removes app from memory O O Media playback is stopped O O FGS stopped / Associated notification removed O O Removes the activity back stack O O O Removes app from history O O Scheduled jobs are canceled O Alarms are canceled O - Foreground service -> Exception -> JobScheduler doesn't work.
- Foreground service -> "Stop" -> JobScheduler works well.
Comparing lifecycle
// Example codes // MyApplication.kt class MyApplication : Application {...} // MainActivity.kt class MainActivity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { startForegroundService(Intent(this, MyPlayerService::class.java)) } else { startService(Intent(this, MyPlayerService::class.java)) } } } // MyPlayerService.kt class MyPlayerService : Service() { override fun onStartCommand(intent: Intent, flags: Int, startId: Int): Int { ... startForeground(NOTIFICATION_ID, notification) } override fun onTaskRemoved(rootIntent: Intent?) { super.onTaskRemoved(rootIntent) stopSelf() } }
// Swipe up MyApplication: onCreate() LogActivity: onCreate() savedInstanceState=null LogActivity: onStart() LogActivity: onResume() MyPlayerService: onCreate() MyPlayerService: onStartCommand() // swipe up LogActivity: onPause() LogActivity: onStop() LogActivity: onDestroy() MyPlayerService: onTaskRemoved() MyPlayerService: onDestroy() // relaunched. LogActivity: onCreate() savedInstanceState=null LogActivity: onStart() LogActivity: onResume() MyPlayerService: onCreate() MyPlayerService: onStartCommand()
// Crash MyApplication: onCreate() LogActivity: onCreate() savedInstanceState=null LogActivity: onStart() LogActivity: onResume() MyPlayerService: onCreate() MyPlayerService: onStartCommand() // crashed application // relaunched. MyApplication: onCreate() LogActivity: onCreate() savedInstanceState=null LogActivity: onStart() LogActivity: onResume() MyPlayerService: onCreate() MyPlayerService: onStartCommand()
// FGS stop button LogActivity: onCreate() savedInstanceState=null LogActivity: onStart() LogActivity: onResume() MyPlayerService: onCreate() MyPlayerService: onStartCommand() // tap stop button // relaunched. MyApplication: onCreate() LogActivity: onCreate() savedInstanceState=null LogActivity: onStart() LogActivity: onResume() MyPlayerService: onCreate() MyPlayerService: onStartCommand()
No callbacks sent when user stops app from FGS Task Manager
The system doesn't send your app any callbacks when the user presses the Stop button. When your app starts back up, it might be helpful for you to check for the new REASON_USER_REQUESTED reason that's part of the existing ApplicationExitInfo API.
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) { val am = getSystemService(Context.ACTIVITY_SERVICE) as ActivityManager val applicationExitInfos = am.getHistoricalProcessExitReasons(null, 0, 0) val exitInfo = applicationExitInfos.firstOrNull() ?: return Log.d("TAG", """applicationExitInfos: reason=${exitInfo.reason} " + "|description=${exitInfo.description} " + "|date=${Date(exitInfo.timestamp)}""".trimMargin()) } // applicationExitInfos: reason=REASON_USER_REQUESTED // description=fully stop com.example.examplefgs/0 by user request // date=Mon May 16 22:22:08 GMT+09:00 2022
System prompts related to long-running foreground services
If the system detects that your app runs a foreground service for a long period of time—at least 20 hours within a 24-hour window—the system sends a notification to the user, inviting them to interact with the FGS Task Manager.
https://developer.android.com/about/versions/13/changes/battery#system-notification-long-running-fgs
Exemptions
Exemptions from appearing in the FGS Task Manager at all
The following apps can run a foreground service and not appear in the task manager at all:
- System-level apps
- Safety apps; that is, apps that have the ROLE_EMERGENCY role. (RoleManager from Android 10)
- Devices that are in demo mode
Exemptions from being stoppable by users
When the following types of apps run a foreground service, they appear in the FGS Task Manager, but there is no Stop button next to the app's name for the user to press:
- Device owner apps
- Profile owner apps
- Persistent apps
- Apps that have the ROLE_DIALER role
RoleManager?
- RoleManager : This class provides information about and manages roles. It can make set the application as a default application.
// AndroidManifest.xml // ROLE_DIALER <activity android:name=".rolemanager.RoleManagerActivity" android:exported="true"> <intent-filter> <action android:name="android.intent.action.DIAL" /> <category android:name="android.intent.category.DEFAULT" /> <data android:scheme="tel" /> </intent-filter> <intent-filter> <action android:name="android.intent.action.DIAL" /> <category android:name="android.intent.category.DEFAULT" /> </intent-filter> </activity> class RoleManagerActivity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) requestRole() } private fun requestRole() { val roleManager: RoleManager = this.getSystemService(ROLE_SERVICE) as RoleManager // Check whether a role is available in the system. val isDialerRoleAvailable = roleManager.isRoleAvailable(RoleManager.ROLE_DIALER) // Check whether the calling application is holding a particular role. val isDialerRoleHeld = roleManager.isRoleHeld(RoleManager.ROLE_DIALER) if (isDialerRoleAvailable && !isDialerRoleHeld) { launchRequestDialerRoleIntent(roleManager) } } private fun launchRequestDialerRoleIntent(roleManager: RoleManager) { val intent: Intent = roleManager.createRequestRoleIntent(RoleManager.ROLE_DIALER) val resultLauncher = registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { result -> if (result.resultCode == RESULT_OK) { // do nothing } } resultLauncher.launch(intent) } }
How to migration?
Use JobSchedule or AlarmManager rather than believe in foreground service.
Because lifecycle can be strange.
// Not called when tap "Stop" button in FGS Task Manager LogActivity: onPause() LogActivity: onStop() LogActivity: onDestroy() MyPlayerService: onTaskRemoved() MyPlayerService: onDestroy()
https://youtu.be/t1_8WSEguDY?t=648
https://developer.android.com/about/versions/13/changes/fgs-manager
반응형'프로그래밍 > Android' 카테고리의 다른 글
Android 13 - Programmable shaders (0) 2022.06.03 Android 13 - Granular media permissions (0) 2022.05.23 R8로 난독화된 stack trace 를 Retrace 하기 (0) 2022.04.12 Large Screen - 태블릿(Large screen) 앱 품질 (0) 2021.09.07 Large screen - 다양한 화면 크기 지원 (0) 2021.09.06 - FGS