Membuat aplikasi pencatat

Pembuatan catatan adalah kemampuan inti Android yang meningkatkan produktivitas pengguna di perangkat layar besar. Dengan aplikasi pencatat, pengguna dapat menulis dan membuat sketsa di jendela mengambang atau layar penuh, mengambil dan menganotasi konten layar, serta menyimpan catatan untuk ditinjau dan direvisi pada lain waktu.

Pengguna dapat mengakses aplikasi pencatat dari layar kunci atau saat menjalankan aplikasi lain.

Dukungan stilus untuk pencatatan memberikan pengalaman pengguna yang luar biasa.

Peran catatan

Peran RoleManager.ROLE_NOTES mengidentifikasi aplikasi pencatat dan memberinya izin LAUNCH_CAPTURE_CONTENT_ACTIVITY_FOR_NOTE.

Untuk mendapatkan peran catatan untuk aplikasi Anda, lakukan hal berikut:

  1. Panggil isRoleAvailable() untuk memeriksa status peran.
  2. Jika peran catatan tersedia, panggil createRequestRoleIntent() untuk mendapatkan intent khusus catatan.
  3. Panggil startActivityForResult() dengan intent catatan untuk meminta pengguna memberikan peran catatan ke aplikasi Anda.

Hanya satu aplikasi yang dapat memiliki peran catatan.

Aplikasi akan terbuka sebagai respons terhadap tindakan intent ACTION_CREATE_NOTE implisit. Jika dipanggil dari layar kunci perangkat, aplikasi akan dibuka dalam layar penuh; jika dipanggil saat layar tidak terkunci, aplikasi akan dibuka di jendela mengambang.

Manifes aplikasi

Agar memenuhi syarat untuk peran catatan, aplikasi Anda harus menyertakan deklarasi berikut dalam manifes aplikasi:

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

Deklarasi ini memungkinkan pengguna menetapkan peran catatan ke aplikasi Anda, menjadikannya aplikasi pencatat default:

  • ACTION_CREATE_NOTE menetapkan tindakan intent yang akan direspons aplikasi Anda

  • showWhenLocked membuat aplikasi dapat diakses dari layar kunci perangkat

  • turnScreenOn memungkinkan aplikasi Anda mengaktifkan layar perangkat saat aplikasi berjalan

Fitur aplikasi

Aplikasi pencatat yang terdiferensiasi di perangkat layar besar memberikan kemampuan pencatatan yang lengkap.

Dukungan stilus

Saat aplikasi dipanggil dengan intent tambahan EXTRA_USE_STYLUS_MODE yang ditetapkan ke true, aplikasi harus membuka catatan yang menerima input stilus (atau sentuhan jari).

Jika intent tambahan ditetapkan ke false, aplikasi Anda harus membuka catatan yang menerima input keyboard.

Akses layar kunci

Aplikasi Anda harus menyediakan aktivitas layar penuh yang berjalan saat aplikasi dibuka dari layar kunci perangkat.

Aplikasi Anda sebaiknya hanya menampilkan catatan historis jika pengguna telah memberikan izin (dalam status perangkat tidak terkunci) untuk menampilkan catatan sebelumnya. Jika tidak, saat dibuka dari layar kunci, aplikasi Anda harus selalu membuat catatan baru.

Anda dapat memeriksa apakah aplikasi telah diluncurkan dari layar kunci dengan KeyguardManager#isKeyguardLocked(). Untuk meminta pengguna mengautentikasi dan membuka kunci perangkat, panggil 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.
  }
});

Jendela mengambang

Untuk pembuatan catatan kontekstual, aplikasi Anda harus menyediakan aktivitas yang akan terbuka di jendela mengambang saat aplikasi lain sedang berjalan.

Aplikasi Anda harus mendukung mode multi-instance sehingga pengguna dapat membuat beberapa catatan dalam beberapa jendela mengambang bahkan saat aplikasi pencatat diluncurkan dalam mode layar penuh atau dalam mode layar terpisah.

Pengambilan konten

Pengambilan konten adalah kemampuan utama aplikasi pencatat. Dengan pengambilan konten, pengguna dapat mengambil screenshot tampilan di balik jendela mengambang aplikasi pencatat. Pengguna dapat mengambil screenshot semua atau sebagian tampilan, menempelkan konten ke catatan mereka, dan memberi anotasi atau menandai konten yang diambil.

Aplikasi pencatatan harus menyediakan kemampuan UI yang meluncurkan ActivityResultLauncher yang dibuat oleh registerForActivityResult(). Tindakan intent ACTION_LAUNCH_CAPTURE_CONTENT_ACTIVITY_FOR_NOTE diberikan ke peluncur secara langsung atau melalui ActivityResultContract.

Aktivitas sistem mengambil screenshot konten, menyimpannya di perangkat, dan menampilkan URI konten ke aplikasi Anda dalam argumen callback registerForActivityResult().

Contoh berikut menggunakan kontrak StartActivityForResult umum:

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

Aplikasi Anda harus menangani semua kode hasil:

Saat pengambilan konten berhasil, tempelkan gambar yang diambil ke catatan, misalnya:

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

Fitur pengambilan konten harus diekspos melalui kemampuan UI hanya saat aplikasi pencatatan Anda berjalan di jendela mengambang—bukan saat menjalankan layar penuh, yang diluncurkan dari layar kunci perangkat. (Pengguna dapat mengambil screenshot aplikasi pencatat itu sendiri dengan kemampuan screenshot perangkat.)

Untuk menentukan apakah aplikasi Anda berada di jendela mengambang (atau balon), panggil metode berikut:

  • isLaunchedFromBubble() untuk memastikan aplikasi pencatat Anda tidak diluncurkan dalam mode layar penuh dari layar kunci perangkat
  • isRoleHeld(RoleManager.ROLE_NOTES) untuk memverifikasi bahwa aplikasi Anda adalah aplikasi pencatat default (aplikasi Anda dapat berjalan dalam percakapan atau jenis balon lainnya jika aplikasi tidak memiliki peran catatan)

Referensi tambahan