笔记功能是 Android 的核心功能,可增强用户在大屏幕设备上的生产力。笔记应用使用户能够在浮动窗口或全屏上进行书写和绘图、捕获和批注屏幕内容,以及保存笔记以便日后查看和修改。
用户可以从锁屏或在运行其他应用时访问笔记应用。
对笔记的触控笔支持提供了卓越的用户体验。
笔记角色
RoleManager.ROLE_NOTES
角色标识笔记应用并授予它们 LAUNCH_CAPTURE_CONTENT_ACTIVITY_FOR_NOTE
权限。
要为您的应用获取笔记角色,请执行以下操作
- 调用
isRoleAvailable()
检查角色的状态。 - 如果笔记角色可用,则调用
createRequestRoleIntent()
获取特定于笔记的意图。 - 使用笔记意图调用
startActivityForResult()
以提示用户向您的应用授予笔记角色。
只有一个应用可以拥有笔记角色。
该应用响应隐式 ACTION_CREATE_NOTE
意图操作而打开。如果从设备锁屏调用,则应用全屏打开;如果在屏幕解锁时调用,则在浮动窗口中打开。
应用清单
要符合笔记角色的条件,您的应用必须在应用清单中包含以下声明
<activity
android:name="YourActivityName"
android:exported="true"
android:showWhenLocked="true"
android:turnScreenOn="true">
<intent-filter>
<action android:name="android.intent.action.CREATE_NOTE" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>
此声明使用户能够将笔记角色分配给您的应用,使其成为默认的笔记应用
ACTION_CREATE_NOTE
设置您的应用响应的意图操作showWhenLocked
使您的应用可从设备锁屏访问turnScreenOn
使您的应用能够在应用运行时打开设备屏幕
应用功能
大屏幕差异化笔记应用提供了全面的笔记功能。
触控笔支持
当您的应用使用 EXTRA_USE_STYLUS_MODE
意图额外内容设置为 true
调用时,应用应打开接受触控笔(或手指触摸)输入的笔记。
如果意图额外内容设置为 false
,则您的应用应打开接受键盘输入的笔记。
锁屏访问
您的应用必须提供一个全屏活动,在从设备锁屏打开应用时运行。
如果用户已同意(在解锁设备状态下)显示过去的笔记,则您的应用应仅显示历史笔记。否则,从锁屏打开时,您的应用应始终创建新的笔记。
您可以使用 KeyguardManager#isKeyguardLocked()
检查您的应用是否是从锁屏启动的。要要求用户进行身份验证并解锁设备,请调用 KeyguardManager#requestDismissKeyguard()
Kotlin
val keyguardManager = getSystemService(KEYGUARD_SERVICE) as KeyguardManager keyguardManager.requestDismissKeyguard( this, object : KeyguardDismissCallback() { override fun onDismissError() { // Unlock failed. Dismissing keyguard is not feasible. } override fun onDismissSucceeded() { // Unlock succeeded. Device is now unlocked. } override fun onDismissCancelled() { // Unlock failed. User cancelled operation or request otherwise cancelled. } } )
Java
KeyguardManager keyguardManager = (KeyguardManager) getSystemService(KEYGUARD_SERVICE); boolean isLocked = keyguardManager.isKeyguardLocked(); keyguardManager.requestDismissKeyguard( this, new KeyguardManager.KeyguardDismissCallback() { @Override public void onDismissError() { // Unlock failed. Dismissing keyguard is not feasible. } @Override public void onDismissSucceeded() { // Unlock succeeded. Device is now unlocked. } @Override public void onDismissCancelled() { // Unlock failed. User cancelled operation or request otherwise cancelled. } });
浮动窗口
对于情境化笔记,您的应用必须提供一个在运行其他应用程序时在浮动窗口中打开的活动。
您的应用应支持 multi-instance
模式,以便用户即使在全屏启动或分屏模式下启动笔记应用,也可以在多个浮动窗口中创建多个笔记。
内容捕获
内容捕获是笔记应用的关键功能。使用内容捕获,用户可以截取笔记应用浮动窗口后面的显示屏的屏幕截图。用户可以捕获全部或部分显示屏,将内容粘贴到笔记中,并批注或突出显示捕获的内容。
您的笔记应用应提供一个 UI 组件,该组件启动由 registerForActivityResult()
创建的 ActivityResultLauncher
。 ACTION_LAUNCH_CAPTURE_CONTENT_ACTIVITY_FOR_NOTE
意图操作直接或通过 ActivityResultContract
提供给启动器。
系统活动捕获内容,将其保存在设备上,并将内容 URI 返回到 registerForActivityResult()
的回调参数中的应用。
以下示例使用通用的 StartActivityForResult
合同
Kotlin
private val startForResult = registerForActivityResult( ActivityResultContracts.StartActivityForResult()) { result: ActivityResult -> if (result.resultCode == Intent.CAPTURE_CONTENT_FOR_NOTE_SUCCESS) { val uri = result.data?.data // Use the URI to paste the captured content into the note. } } override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContent { NotesTheme { Surface(color = MaterialTheme.colorScheme.background) { CaptureButton( onClick = { Log.i("ContentCapture", "Launching intent...") startForResult.launch(Intent(ACTION_LAUNCH_CAPTURE_CONTENT_ACTIVITY_FOR_NOTE)) }) } } } } @Composable fun CaptureButton(onClick: () -> Unit) { Button(onClick = onClick) {Text("Capture Content")} }
Java
private final ActivityResultLauncher<Intent> startForResult = registerForActivityResult( new ActivityResultContracts.StartActivityForResult(), result -> { if (result.getResultCode() == Intent.CAPTURE_CONTENT_FOR_NOTE_SUCCESS) { Uri uri = result.getData() != null ? result.getData().getData() : null; // Use the URI to paste the captured content into the note. } }); @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); Button captureButton = findViewById(R.id.capture_button); captureButton.setOnClickListener( view -> { Log.i("ContentCapture", "Launching intent..."); startForResult.launch(new Intent(ACTION_LAUNCH_CAPTURE_CONTENT_ACTIVITY_FOR_NOTE)); }); }
您的应用应处理所有结果代码
CAPTURE_CONTENT_FOR_NOTE_SUCCESS
CAPTURE_CONTENT_FOR_NOTE_FAILED
CAPTURE_CONTENT_FOR_NOTE_USER_CANCELED
CAPTURE_CONTENT_FOR_NOTE_WINDOW_MODE_UNSUPPORTED
CAPTURE_CONTENT_FOR_NOTE_BLOCKED_BY_ADMIN
内容捕获成功后,将捕获的图像粘贴到笔记中,例如
Kotlin
registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { result: ActivityResult -> if (result.resultCode == Intent.CAPTURE_CONTENT_FOR_NOTE_SUCCESS) { val uri = result.data?data // Use the URI to paste the captured content into the note. } }
Java
registerForActivityResult(new ActivityResultContracts.StartActivityForResult(), result -> { if (result.getResultCode() == Intent.CAPTURE_CONTENT_FOR_NOTE_SUCCESS) { Uri uri = result.getData() != null ? result.getData().getData() : null; // Use the URI to paste the captured content into the note. } });
只有当您的笔记应用在浮动窗口中运行时(而不是全屏运行或从设备锁屏启动时),才应通过 UI 组件公开内容捕获功能。(用户可以使用设备屏幕截图功能截取笔记应用本身的屏幕截图。)
要确定您的应用是否在浮动窗口(或气泡)中,请调用以下方法
isLaunchedFromBubble()
检查您的笔记应用不是从设备锁屏全屏启动的isRoleHeld(RoleManager.ROLE_NOTES)
验证您的应用是否是默认的笔记应用(如果应用不持有笔记角色,则您的应用可以在对话或其他类型的泡泡中运行)