The technical implementation of adding shortcut switches to the Android notification bar

insert image description here
We can usually see switch buttons such as "airplane mode", "mobile data", and "screen recording" on the notification bar. These buttons belong to the shortcut switches on the notification bar. Clicking the shortcut switch can easily call a certain system capability or open A specific page of an application. Is it possible to customize a shortcut switch on the notification bar? The answer is yes, specifically through the TileService solution.

TileService inherits from Service, so it is also one of the four major components of Android, but it is a special component, developers do not need to manually open the call, the system can automatically identify and complete the call, the system will bind the service (bindService) method call.

Created using:

Shortcut switch is a new capability of Android 7 (target 24), so before using this capability, you must first determine the version size (greater than or equal to target 24).
1. Customize a TileService class.

class MyQSTileService: TileService() {
    
    
  override fun onTileAdded() {
    
        
      super.onTileAdded()  
  }

  override fun onStartListening() {
    
        
      super.onStartListening()  
  }

  override fun onStopListening() {
    
        
      super.onStopListening()  
  }

  override fun onClick() {
    
        
      super.onClick()  
  }

  override fun onTileRemoved() {
    
        
      super.onTileRemoved()  
  }
}

TileService is called by binding service (bindService), therefore, the four typical callback methods (onCreate(), onBind(), onUnbind() and onDestroy()) included in the bound service life cycle will be called . However, TileService also includes the following special lifecycle callback methods:

onTileAdded(): It will be called when the user adds a shortcut switch from the edit bar to the quick setting of the notification bar.
onTileRemoved(): Called when the user removes the shortcut switch from the quick settings in the notification bar.
onClick(): Called when the user clicks the shortcut switch.
onStartListening(): Called when the user opens the quick settings of the notification shade. It will not be called when the shortcut switch is not dragged from the formula bar to the settings bar. Called once after TileAdded is added.
onStopListening(): Called when the user opens the quick settings of the notification shade. It will not be called when the shortcut switch is not dragged from the formula bar to the settings bar. Called once before TileRemoved is removed.

2. Declare TileService in the manifest file of the application.

<service
     android:name=".MyQSTileService"
     android:label="@string/my_default_tile_label"  
     android:icon="@drawable/my_default_icon_label"
     android:exported="true"
     android:permission="android.permission.BIND_QUICK_SETTINGS_TILE">
     <intent-filter>
         <action android:name="android.service.quicksettings.action.QS_TILE" />
     </intent-filter>
 </service>

name: The class name of the custom TileService.
label: The name of the shortcut switch displayed on the notification bar.
icon: The icon displayed on the notification bar for the shortcut switch.
exported: Whether the service can be called by external applications. This property must be true. If it is false, the function of the shortcut switch will be invalid. The reason is that when exported="false", TileService will not support external application calls, and the mobile phone system will naturally no longer be able to interact with the shortcut switch. Must be configured.
permission: The permission that needs to be configured for the service, BIND_QUICK_SETTINGS_TILE allows the application to bind to the third-party quick settings. Must be configured.
intent-filter: Intent filter, the service can only be invoked if it matches the internal action. Must be configured.

Listening Mode
There are two listening modes (or start mode) of TileService, one is active mode and the other is standard mode.
Active mode
In active mode, when TileService is requested, the service will be bound, and onStartListening of TileService will also be called. This mode needs to be declared in the AndroidManifeast manifest file:

<service ...>
    <meta-data android:name="android.service.quicksettings.ACTIVE_TILE"
         android:value="true" />
    ...
</service>

Through the static method of TileService.requestListeningState(), the request to TileService can be realized. The example is as follows:

      TileService.requestListeningState(
            applicationContext, ComponentName(
                BuildConfig.APPLICATION_ID,
                MyQSTileService::class.java.name
            )
        )

In the active mode, it is worth noting that
when the user clicks the shortcut switch in the quick setting of the notification bar, TileService will automatically complete the binding, and the onStartListening of TileService will be called.
Whether TileService is bound by clicking or by requestListeningState request, the process where TileService is located will be called.

Standard mode
In standard mode, when the TileService is visible (that is, the user pulls down the notification bar to see the shortcut switch), the service will be bound, and the onStartListening of the TileService will also be called. The standard mode does not require additional declarations in the AndroidManifeast manifest file, and the default is the standard mode.

It is worth noting that in the standard mode:
the same as the active mode, when the TileService is bound, the process where the TileService is located will be called.
Different from the active mode, the binding of the TileService in the standard mode is realized by the user pulling down the notification bar, which means that the process where the TileService is located will be invoked multiple times. Therefore, in order to prevent the main process from being frequently invoked and to avoid data statistics such as DAU being affected, we also need to specify a specific sub-process for TileService, and set it in the Androidmanifest manifest file:

      <service
            ......
            android:process="自定义子进程的名称">
            ......
        </service>

Update the shortcut switch
If you need to update the data of the shortcut switch, you can get the object of the shortcut switch through getQsTile(), and then use setIcon (update icon), setLable (update name), setState (update state, including STATE_ACTIVE - means open or Enabled state, STATE_INACTIVE—indicates the closed or suspended state, STATE_UNAVAILABLE: indicates the temporarily unavailable state, in this state, the user cannot interact with your tile) and other methods to set the new data of the shortcut switch, and finally call the updateTile() method to achieve .

  override fun onStartListening() {
    
    
    super.onStartListening()
    if (qsTile.state === Tile.STATE_ACTIVE) {
    
    
        qsTile.label = "inactive"
        qsTile.icon = Icon.createWithResource(context, R.drawable.inactive)
        qsTile.state = Tile.STATE_INACTIVE
    } else {
    
    
        qsTile.label = "active"
        qsTile.icon = Icon.createWithResource(context, R.drawable.active)
        qsTile.state = Tile.STATE_ACTIVE
    }
    qsTile.updateTile()
  }

Operation shortcut switch

If you want to close the notification bar and jump to a certain page when you click the shortcut switch, you can call the following method:

startActivityAndCollapse(Intent intent)

If you want to pop up a dialog box for interaction when you click the shortcut switch, you can call the following method:

override fun onClick() {
    
    
    super.onClick()
    if(!isLocked()) {
    
    
        showDialog()
    }
 }

Because the shortcut switch may appear when the user locks the screen, the judgment of isLocked() must be added. The dialog will only appear when the screen is not locked.

If the shortcut switch contains sensitive information, you need to use isSecure() to judge the security of the device. Only when the device is safe, can you execute the logic related to the shortcut switch (such as the logic of clicking). When the device is insecure (the phone is in the locked screen state), you can call unlockAndRun(Runnable runnable) to prompt the user to unlock the screen and perform a custom runnable operation.

Guess you like

Origin blog.csdn.net/qq_24252589/article/details/131387835