在飞行模式下,设备仍然可以访问某些传感器来启用特定功能,例如屏幕旋转和拍照。 Android 10 提供了开发者选项设置来关闭设备中的所有传感器。此功能可帮助开发人员在这些传感器不可用的情况下测试应用程序的功能,并为用户提供一种控制设备中传感器的方法。
当开发人员或用户在开发人员选项(设置>系统>开发人员选项>快速设置开发人员磁贴)中启用传感器关闭时,快速设置托盘中会出现一个新磁贴。他们可以使用该磁贴来阻止应用程序访问摄像头、麦克风以及由SensorManager
类管理的所有传感器。
警告:此选项仅影响通过“SensorService”、“CameraService”和“AudioPolicyService”访问传感器的应用程序。电话功能不使用“AudioPolicyService”,并且在通话期间仍然可以访问麦克风。
执行
Android 10 包含一个处理相机、麦克风和SensorManager
传感器的参考实现。管理传感器关闭状态并通知客户端状态更改的系统服务位于frameworks/base/services/core/java/com/android/server/SensorPrivacyService.java
。便于在应用程序上下文中访问SensorPrivacyService
管理器位于frameworks/base/core/java/android/hardware/SensorPrivacyManager.java
中。
如果您的设备使用SensorService
、 CameraService
和AudioPolicyService
的默认实现,则无需对参考设计进行额外的自定义。如果您有其他传感器,请参阅自定义以了解有关支持此功能的更多详细信息。
常见问题
实现此功能时,有时相机应用程序无法正确响应onError
回调,无论是在首次尝试获取相机时还是在相机不再可用时。当启用此图块时,这通常会导致应用程序崩溃,但这可以用作指示该功能按预期运行的信号。
此行为表明应用程序未正确处理CameraDevice.StateCallback
中的onError
回调。当启用传感器关闭时,将调用onError
回调,并将CameraDevice.StateCallback.ERROR_CAMERA_DISABLED
设置为错误值。更新任何第一方应用程序以使用此值处理onError
回调,方法是在后续openCamera
调用成功之前不对CameraDevice
进行任何后续调用。
传感器行为
启用“传感器关闭”后,传感器将停止向系统或应用程序报告任何数据。当启用“传感器关闭”时,应用程序仍然可以请求传感器并注册侦听器,但要么为麦克风返回静音,要么永远不会为传感器调用onSensorChanged
回调。一旦禁用该图块,这些相同的侦听器就开始接收来自麦克风的实际输出或对onSensorChanged
预期回调,而无需执行任何其他工作。静音传感器的默认行为如下。
相机
如果应用程序在启用Sensors off的情况下使用相机,则会向onError
回调方法发送错误,并且CameraDevice
会关闭。
如果应用程序在启用传感器关闭时尝试访问相机,则会向onError
回调方法发送错误。
麦克风
启用“传感器关闭”后,仍然可以访问麦克风,但仅返回静音。如果应用程序在启用“传感器关闭”时使用麦克风,则不会生成错误,但录音会静音并仅返回一个零数组。如果在应用程序仍在使用麦克风时禁用传感器关闭,则会返回预期的音频数据。
如果应用程序在启用传感器关闭时尝试访问麦克风,麦克风将返回静音。
传感器
当应用程序在启用传感器关闭时尝试访问其他传感器时,传感器类型会影响默认行为:
- 连续传感器:处于此报告模式的传感器停止调度事件。如果在启用“传感器关闭”时应用程序正在与连续传感器交互,则在禁用该功能之前,传感器不会向应用程序发送其他数据。
- 刷新事件:启用磁贴并调用
onFlushComplete
回调以指示请求的刷新已成功完成时,可以请求传感器刷新,但不会生成带有传感器数据的新事件并返回到onSensorChanged
回调。 - 更改事件:启用“传感器关闭”时,不会报告新的更改事件。
- 触发事件:当启用传感器关闭时,触发事件停止生成。任何现有事件均已完成。
定制化
如果您的设备使用SensorService
、 CameraService
和AudioPolicyService
的默认实现,则无需对参考设计进行额外的自定义。但是,您可以支持在SensorManager
外部管理的传感器,从设备中删除传感器,或者更改开发人员快速设置图块的系统 UI 或传感器关闭图块的图标。
支持更多传感器
如果您的设备包含在SensorManager
外部管理的传感器,则应使用SensorPrivacyService
和SensorPrivacyManager
添加对它们的支持。
当传感器关闭磁贴被切换时, SensorPrivacyService
会为所有注册的侦听器调用单向回调。收到此回调后,注册的侦听器可以根据图块的状态采取必要的步骤。如果启用,则可以终止所有现有连接并返回空数据,并设置一个标志以阻止新连接。如果禁用,则可以重置该标志以允许新连接。以相机服务 ( platform/frameworks/av/services/camera/libcameraservice/
) 为例,按照以下步骤添加对新传感器的支持。
- 实现
BnSensorPrivacyListener
接口。有关更多详细信息,请参阅CameraService.h
中的SensorPrivacyPolicy
。 - 向
SensorPrivacyManager
注册并在启动时获取磁贴的状态。有关更多详细信息,请参阅CameraService.cpp
中的SensorPrivacyPolicy::registerSelf
。 - 在回调中处理传感器关闭状态变化。有关更多详细信息,请参阅
CameraService.cpp
中的SensorPrivacyPolicy::onSensorPrivacyChanged
和CameraService::blockAllClients
。 - 启用磁贴时防止访问传感器数据。有关更多详细信息,请参阅
CameraService.cpp
中的CameraService::validateClientPermissionsLocked
中的传感器隐私策略检查。
移除传感器关闭
作为用于测试的开发人员工具, Sensors off是隐藏的,因为用户必须首先启用开发人员模式,然后选择在设置中使磁贴可用。
如果您不想在设备上支持关闭传感器,请从packages/apps/Settings/AndroidManifest.xml
中删除服务标签。如果删除服务标签,则无法从开发人员快速设置磁贴页面启用“传感器关闭”磁贴。
更改 UI 中的传感器
可以为传感器关闭UI 自定义两个元素:为开发人员快速设置磁贴显示的图标以及启用磁贴时在状态栏中显示的图标。要自定义这些图标的外观,请替换这些文件:
- 快速设置磁贴图标:
packages/apps/Settings/res/drawable/tile_icon_sensors_off.xml
- 状态栏图标:
frameworks/base/packages/SystemUI/res/drawable/stat_sys_sensors_off.xml
验证
作为可选的开发人员工具,此功能没有 CTS 测试。
您可以通过安装 Google Play 中的应用程序来手动测试,该应用程序可读取并显示设备的所有传感器。当您启用“传感器关闭”磁贴时,请确保传感器的任何值都不会更改、麦克风音频保持静音且无法访问摄像头。