Membuat aplikasi pencatat

Pembuatan catatan adalah kemampuan inti Android yang meningkatkan produktivitas pengguna di perangkat layar besar. Aplikasi pencatatan memungkinkan pengguna menulis dan membuat sketsa di jendela mengambang atau pada layar penuh, menangkap dan memberi anotasi pada konten layar, serta menyimpan catatan untuk ditinjau dan direvisi nanti.

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 pencatatan 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 membuka layar penuh; jika dipanggil saat layar dibuka kuncinya, dalam 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 pencatatan default:

  • ACTION_CREATE_NOTE menetapkan tindakan intent yang akan direspons oleh aplikasi Anda

  • showWhenLocked membuat aplikasi Anda dapat diakses dari layar kunci perangkat

  • turnScreenOn memungkinkan aplikasi mengaktifkan layar perangkat saat aplikasi berjalan

Fitur aplikasi

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

Dukungan stilus

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

Jika tambahan intent 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 mengizinkan (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 pencatatan. Dengan pengambilan konten, pengguna dapat mengambil screenshot tampilan di balik jendela mengambang aplikasi pencatat. Pengguna dapat menangkap semua atau sebagian tampilan, menempelkan konten ke catatan mereka, dan memberi anotasi atau menyoroti konten yang direkam.

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

Aktivitas sistem menangkap 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 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 lainnya