通知拓展服务接入

部分系统应用需要提供一些控制通知基础服务的能力,如放空空间需要屏蔽浮动通知等等,这里提供一个对外控制通知的服务,本文档主要包括接入的步骤与说明等。

0. 前言

总体思想是通知基础服务提供一个 AIDL 的服务,业务方通过绑定这个服务,然后调用相应的接口方法实现所需功能,而且该方式可以处理因为业务方应用挂掉而不会影响通知基础服务的异常情况。

下面来详述一下接入的步骤。

1. 接入 AIDL 文件

在你的项目中引入 AIDL 文件,包名为 com.android.car.notification,文件名 IMiCarNotificationService.aidl,文件内容:

📷 截图:Card

package com.android.car.notification;
 
import android.os.IBinder;
 
interface IMiCarNotificationService {
    /**
     * 通知禁用状态改变
     *
     * @param scene 场景 id
     * @param binder 当禁用通知时传递一个 binder 过来,为了监听进程挂掉时恢复通知;当恢复通知时 binder 为 null
     */
    void onNotificationForbiddenChanged(int scene, IBinder binder);
}

2. 绑定与解绑服务

2.1 服务定义

  • Action:com.android.car.notification.MI_CAR_NOTIFICATION_SERVICE
  • 包名:com.android.systemui

2.2 绑定服务

因为通知服务是实现在 SystemUI 的 user0 进程下的,所以需要通过调用 Context.bindServiceAsUser() 的方式来绑定服务,示例代码:

Intent intent = new Intent("com.android.car.notification.MI_CAR_NOTIFICATION_SERVICE")
        .setPackage("com.android.systemui");
bindServiceAsUser(intent, mServiceConnection, BIND_AUTO_CREATE, UserHandle.SYSTEM);

这里注意 UserHandle.SYSTEM 系统源码标记成了 @SystemApi,所以一般的应用是用不了的,如果你的应用无法使用的话需要引入一下 MiCarCoreSDK,可参考 MiCarCoreSDK 使用规范

然后将 UserHandle.SYSTEM 替换成 MiCarUserHandle.SYSTEM

另外注意上面的操作需要申请两个权限,如下:

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

注意这两个权限属于严重的权限,系统应用可能还需要加 privilege。

另外还需要加一个我们自定义的权限:

<uses-permission android:name="mi.car.notification.permission.MI_CAR_NOTIFICATION_SERVICE" />

2.3 解绑服务

在使用完服务记得解绑:

unbindService(mServiceConnection);

3. 功能使用

AIDL 定义的所有功能说明如下。

3.1 禁用浮动通知

方法定义:void onNotificationForbiddenChanged(int scene, IBinder binder);

参数定义:

  • scene:业务场景的 id,按位增加定义,目前定义的 id 如下:

    • 0x1:放空空间场景
  • binder:当禁用通知时业务方传递一个 new Binder(),为了监听进程挂掉时恢复通知;当恢复通知时 binder 传递 null。

3.2 还没有呢

也不希望有,哈哈