メモ作成アプリを作成する

メモ作成は、大画面デバイスでユーザーの生産性を向上させる Android の重要な機能です。メモ作成アプリを使用すると、ユーザーはフローティング ウィンドウまたは全画面で文書やスケッチを作成したり、画面上のコンテンツをキャプチャして注釈を付けたり、メモを保存して後で確認、修正したりできます。

メモ作成アプリには、ロック画面からでも、他のアプリの実行中でもアクセスできます。

メモ作成のタッチペン サポートにより、ユーザー エクスペリエンスが向上します。

メモのロール

RoleManager.ROLE_NOTES ロールはメモ作成アプリを識別し、LAUNCH_CAPTURE_CONTENT_ACTIVITY_FOR_NOTE 権限を付与します。

アプリでメモのロールを取得する手順は次のとおりです。

  1. isRoleAvailable() を呼び出してロールのステータスを確認します。
  2. メモのロールが利用可能な場合は、createRequestRoleIntent() を呼び出してメモ固有のインテントを取得します。
  3. メモのインテントを指定して startActivityForResult() を呼び出し、アプリにメモのロールを付与するようユーザーに求めます。

メモのロールを所有できるアプリは 1 つのみです。

アプリは暗黙的な 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 モードをサポートする必要があります。

コンテンツ キャプチャ

コンテンツ キャプチャはメモ作成アプリの重要な機能です。コンテンツ キャプチャにより、ユーザーはメモ作成アプリのフローティング ウィンドウの背後にあるディスプレイのスクリーンショットを撮ることができます。ディスプレイの全体または一部をキャプチャし、コンテンツをメモに貼り付けて、キャプチャしたコンテンツに注釈またはハイライトを付けることができます。

メモ作成アプリには、registerForActivityResult() によって作成された ActivityResultLauncher を起動する UI アフォーダンスが必要です。ACTION_LAUNCH_CAPTURE_CONTENT_ACTIVITY_FOR_NOTE インテントのアクションは、直接または ActivityResultContract を介してランチャーに提供されます。

システム アクティビティは、コンテンツをキャプチャしてデバイスに保存し、registerForActivityResult() のコールバック引数でアプリにコンテンツ URI を返します。

次の例では、汎用の 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));
        });
}

アプリは以下のすべての結果コードを処理する必要があります。

コンテンツ キャプチャに成功したら、キャプチャした画像をメモに貼り付けます。次に例を示します。

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): アプリがデフォルトのメモ作成アプリであることを確認します(アプリにメモのロールがない場合は、会話または他のタイプのバブルで実行できます)。

参考情報