创建记事应用

记事是 Android 的一项核心功能,可提高用户在大屏设备上的工作效率。借助记事应用,用户可以在浮动窗口中或全屏上书写和草图,捕获屏幕内容并为其添加注释,以及保存记事以供日后查看和修改。

用户可以在锁定的屏幕上或在运行其他应用时访问记事应用。

针对记事功能的触控笔支持可提供卓越的用户体验。

“记事”角色

RoleManager.ROLE_NOTES 角色可识别记事应用,并向其授予 LAUNCH_CAPTURE_CONTENT_ACTIVITY_FOR_NOTE 权限。

如需为您的应用获取“记事”角色,请执行以下操作:

  1. 调用 isRoleAvailable() 以检查角色的状态。
  2. 如果“记事”角色可用,请调用 createRequestRoleIntent() 以获取记事专用 intent。
  3. 使用记事 intent 调用 startActivityForResult(),以提示用户向您的应用授予“记事”角色。

只能有一个应用具有“记事”角色。

该应用会响应隐式 ACTION_CREATE_NOTE intent 操作而打开。如果从设备锁定屏幕调用,应用会全屏打开;如果在屏幕处于解锁状态时调用,则会在浮动窗口中打开。

应用清单

如需获得使用“记事”角色的资格,您的应用必须在应用清单中添加以下声明:

<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>

通过该声明,用户可以为您的应用分配“记事”角色,使其成为默认的记事应用:

应用功能

一款与众不同的大屏记事应用,可提供全面的记事功能。

触控笔支持

通过将 EXTRA_USE_STYLUS_MODE intent extra 设置为 true 来调用您的应用时,应用应打开一条接受触控笔(或手指触控)输入的记事。

如果 intent extra 设置为 false,您的应用应打开一条接受键盘输入的记事。

锁屏访问

您的应用必须提供从设备锁定屏幕打开应用时运行的全屏 activity。

只有在用户同意(处于解锁设备状态)显示过往笔记的情况下,您的应用才应仅显示历史笔记。否则,从锁定屏幕打开时,应用应始终创建新记事。

您可以使用 KeyguardManager#isKeyguardLocked() 检查应用是否已从锁定屏幕启动。如需要求用户进行身份验证并解锁设备,请调用 KeyguardManager#requestDismissKeyguard()

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.
        }
    }
)

浮动窗口

对于上下文记事,您的应用必须提供一个当其他应用正在运行时可在浮动窗口中打开的 activity。

您的应用应支持 multi-instance 模式,以便用户可以在多个浮动窗口中创建多个记事,即使记事应用在全屏模式或分屏模式下启动也是如此。

内容截取

内容截取是记事应用的一项关键功能。借助内容截取功能,用户可以截取记事应用浮动窗口背后显示内容的屏幕截图。用户可以截取全部或部分显示内容,将内容粘贴到记事中,并对截取的内容添加注释或突出显示这些内容。

您的记事应用应提供一种界面功能,用于启动由 registerForActivityResult() 创建的 ActivityResultLauncherACTION_LAUNCH_CAPTURE_CONTENT_ACTIVITY_FOR_NOTE intent 操作可直接或通过 ActivityResultContract 提供给启动器。

系统 activity 会捕获内容,将其保存在设备上,并在 registerForActivityResult() 的回调参数中将内容 URI 返回给应用。

以下示例使用通用 StartActivityForResult 协定:

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")}
}

您的应用应处理所有结果代码:

内容截取成功后,将截取的图片粘贴到记事中,例如:

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.
        }
}

仅当您的记事应用从设备锁定屏幕启动在浮动窗口中运行时(而不是在全屏模式下运行时),才应通过界面功能提供内容截取功能。(用户可以使用设备屏幕截图功能截取记事应用本身的屏幕截图)。

如需确定应用是否在浮动窗口(或气泡)中,请调用以下方法:

  • isLaunchedFromBubble(),用于检查是否未从设备锁定屏幕以全屏模式启动您的记事应用
  • isRoleHeld(RoleManager.ROLE_NOTES),用于验证您的应用是否为默认的记事应用(如果应用不具有“记事”角色,则可以在对话或其他类型的气泡中运行)

其他资源