Android14 front-end service adaptation guide

Android14 front-end service adaptation guide

Android 10 introduces theandroid:foregroundServiceType attribute to help developers define front-end services more purposefully. This attribute is mandatory in Android 14 and the appropriate foreground service type must be specified. The following types of front desk services are available:

  1. camera: Camera application.
  2. connectedDevice: Apps related to connected devices.
  3. dataSync: Data synchronization application.
  4. health: Health-related applications.
  5. location: Location-related applications.
  6. mediaPlayback: Media playback application.
  7. mediaProjection: Media projection application.
  8. microphone: Microphone related applications.
  9. phoneCall: Phone calling application.
  10. remoteMessaging: Remote messaging application.
  11. shortService: Short-term service applications.
  12. specialUse: Special purpose applications.
  13. systemExempted: System exception application.

If the application's foreground service is not related to the above types, it is recommended to migrate to other methods such as WorkManager or user-triggered data transfer jobs.

It is worth noting that health, remoteMessaging, shortService, are newly added in Android 14 specialUse and systemExempted types. The application must declare the front-end service type in the manifest file as follows:

<manifest ...>
  <uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
  <uses-permission android:name="android.permission.FOREGROUND_SERVICE_MEDIA_PLAYBACK" />
  <application ...>
    <service
        android:name=".MyMediaPlaybackService"
        android:foregroundServiceType="mediaPlayback"
        android:exported="false">
    </service>
  </application>
</manifest>

For applications targeting Android 14, if no foreground service type is defined, the system will throw an exception when calling startForeground(). This change is intended to improve app security and user privacy protection. MissingForegroundServiceTypeException

Android14 front desk service adaptation

  1. Declare new permissions: When an application targeting Android 14 uses a front-end service type, it must declare specific permissions based on the front-end service type. These permissions are listed in the Intended Use Cases and Enforcement sections for each front-end service type and are labeled "Permissions you must declare in the manifest file". These permissions are general permissions and cannot be revoked by the user. If an app calls startForeground() but does not declare the appropriate foreground service type permissions, the system will throw an SecurityException exception.

  2. Contains the foreground service type at runtime: For applications that start foreground services, it is recommended to use the overloaded version of startForeground(), in which one or more values ​​of the foreground service type can be passed. In general, you should only declare front-end service types that are relevant to a specific use case. If a foreground service is started with multiple types, it should comply with the enforcement requirements of all types.

  3. System runtime checks: The system checks for appropriate use of the foreground service type and verifies that the app has requested the appropriate runtime permissions or used the required APIs. For example, when an application uses the FOREGROUND_SERVICE_TYPE_LOCATION foreground service type, it needs to request ACCESS_COARSE_LOCATION or ACCESS_FINE_LOCATION permissions. Apps must strictly follow a specific sequence of requesting permissions and starting foreground services. The required permissions must be requested and obtained before callingstartForeground(). If the app does not meet the runtime requirements for the foreground service, the system will throw after calling startForeground(), which prevents the foreground service from starting, possibly causing the app to crash. SecurityException

The Intended Use Cases and Enforcement sections for each front-end service type provide details about the platform-enforced requirements that app developers should follow to ensure proper operation of their apps.

Expected use cases and enforcement for each front-end service type

Only a few services such as cameras, connected devices, and data synchronization are explained. For more types of usage, please refer to the link below.

https://developer.android.google.cn/about/versions/14/changes/fgs-types-required?hl=zh-cn

To use a specific front-end service type, the following conditions should be met:

  1. Declare specific permissions in the manifest file.

  2. Meet specific runtime requirements.

  3. The app must meet one of the expected set of use cases for that type.

The requirements for specific front-end service types are as follows:

  • Camera:

    • Statement limit:FOREGROUND_SERVICE_CAMERA.
    • Runtime requirement: Request camera runtime permission.
    • Use case: Continue to access the camera in the background, such as a video chat app that supports multitasking.
  • Connected devices:

    • Statement limit:FOREGROUND_SERVICE_CONNECTED_DEVICE.
    • Runtime requirements: Specific permissions or runtime permissions must be met.
    • Use case: Interact with external devices requiring Bluetooth, NFC, IR, USB or network connectivity. Use cases can include Bluetooth connectivity, network connectivity, etc.
  • data synchronization:

    • Statement limit:FOREGROUND_SERVICE_DATA_SYNC.
    • Runtime requirements: None.
    • Use cases: data transfer operations, such as data upload, backup, import and export, file processing, etc. This front-end service type will be deprecated and it is recommended to use WorkManager or user-initiated data transfer jobs.
  • Health (preview, new in Android 14):

    • Statement limit:FOREGROUND_SERVICE_HEALTH.
    • Runtime requirements: Specific permissions or runtime permissions must be met.
    • Use cases: Power long-running use cases for apps in the fitness category, such as fitness trackers.
  • Location:

    • Statement limit:FOREGROUND_SERVICE_LOCATION.
    • Runtime requirement: Request permission to use location information, including ACCESS_COARSE_LOCATION or ACCESS_FINE_LOCATION.
    • Use cases: Long-running location use cases, such as navigation and location sharing.

Meeting the requirements of these front-end service types is key to ensuring that the application can properly use related functions. Developers should follow these rules in manifest files and runtime permission requests to ensure that the application can function properly as a foreground service type.

The front-end service is used for user data transmission business

In Android 14, the foreground service rules are stricter and require apps to meet conditions before they can use foreground services. Introducing a new API to specify user-initiated data transfer jobs, suitable for long-term data transfer. This type of job requires manual startup by the user with RUN_USER_INITIATED_JOBS permissions. Improvements are aimed at improving system stability and user experience.

Start user job

To run a user-initiated job, follow these steps:

  1. Declare in manifest file RUN_USER_INITIATED_JOBS Permissions:
<manifest ...>
    <uses-permission android:name="android.permission.RUN_USER_INITIATED_JOBS" />
    <application ...>
        ...
    </application>
</manifest>
  1. Use the new and methods when constructing JobInfo objects. It is recommended that you provide an estimated payload size, using the method:setUserInitiated()setDataTransfer()setEstimatedNetworkBytes()
val networkRequestBuilder = NetworkRequest.Builder()
        .addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)
        .addCapability(NetworkCapabilities.NET_CAPABILITY_VALIDATED)

val jobInfo = JobInfo.Builder()
        // ...
        .setUserInitiated(true)
        .setDataTransfer(true)
        .setRequiredNetwork(networkRequestBuilder.build())
        .setEstimatedNetworkBytes(1024 * 1024 * 1024)
        // ...
        .build()
  1. Schedule a job when the app is visible or when allowed conditions are met:
val jobScheduler: JobScheduler =
        context.getSystemService(Context.JOB_SCHEDULER_SERVICE) as JobScheduler
jobScheduler.schedule(jobInfo)
  1. When executing a job, be sure to call for the JobService object, which notifies the user that the job is running:setNotification()
val notification = Notification.Builder(applicationContext, NOTIFICATION_CHANNEL_ID)
        .setContentTitle("My user-initiated data transfer job")
        .setSmallIcon(android.R.mipmap.myicon)
        .setContentText("Job is running")
        .build()

class CustomJobService : JobService() {
    
    
  override fun onStartJob(params: JobParameters?): Boolean {
    
    
      setNotification(params, notification.id, notification, JobService.JOB_END_NOTIFICATION_POLICY_DETACH)
      // 执行作业任务。
  }
}
  1. Please note that if setNotification() is not called in time, it may cause an ANR in the application.

  2. Notifications are updated regularly so users know the status and progress of their jobs. If the transfer size cannot be determined before scheduling the job, use the new API updateEstimatedNetworkBytes() to update the transfer size once the transfer size is known.

  3. After job execution is complete, call jobFinished() to indicate to the system that the job is complete or that the job needs to be rescheduled.

Stop user job

  1. Stop a user-initiated data transfer job:

    • Both the user and the system can stop a user-initiated transfer job.
    • Users can stop user-initiated transfer jobs through the Stop action in Task Manager.
    • When the user stops a job, the system terminates the app's processes, including any running jobs or foreground services.
    • The system will not call onStopJob() to terminate the job and will prevent user-visible jobs from being rescheduled.
    • It is recommended to provide controls in published job notifications to allow users to stop and reschedule jobs.
    • In some cases, the Stop button may not appear in Task Manager or the job may not appear at all.
  2. Stop jobs provided by the system:

    • Unlike regular jobs, user-initiated data transfer jobs are not affected by app standby mode bucket quotas.
    • However, the system still stops the job for several reasons:
      • The developer-defined constraints are no longer met.
      • The system considers the job to be running longer than it takes to complete the data transfer.
      • The system needs to prioritize system health and may stop operations due to excessive equipment temperature.
      • The application process was terminated due to insufficient device memory.
    • When the system stops a job (not due to insufficient memory), the system calls onStopJob() and retries the job at a time the system deems best.
    • Developers should ensure that applications retain data transfer state even when onStopJob() is not called, and restore the state when onStartJob() is called again.

User job constraints

Summarized as follows:

  1. To support jobs that run at optimal times, Android provides the ability to assign constraints to each job type, available starting in Android 13.

  2. Constraints allowed for user-initiated data transfer jobs include:

    • setBackoffCriteria(JobInfo.BACKOFF_POLICY_EXPONENTIAL)
    • setClipData()
    • setEstimatedNetworkBytes()
    • setMinimumNetworkChunkBytes()
    • setPersisted()
    • setNamespace()
    • setRequiredNetwork()
    • setRequiredNetworkType()
    • setRequiresBatteryNotLow()
    • setRequiresCharging()
    • setRequiresStorageNotLow()

test

The steps for testing an application job include:

  • Get the job ID.
  • The command adb shell cmd jobscheduler run -f APP_PACKAGE_NAME JOB_ID allows you to run or retry a stopped job immediately.
  • With the command adb shell cmd jobscheduler timeout TEST_APP_PACKAGE TEST_JOB_ID you can simulate the system forcibly stopping the job, for example due to system health conditions or exceeded quota conditions.

Guess you like

Origin blog.csdn.net/u011897062/article/details/134291685