Stwórz aplikację do robienia notatek

Robienie notatek to podstawowa funkcja Androida, która zwiększa produktywność użytkowników urządzeń z dużym ekranem. Aplikacje do notatek umożliwiają użytkownikom pisanie i szkicowanie w pływającym oknie lub na pełnym ekranie, przechwytywanie i dodawanie adnotacji do zawartości ekranu oraz zapisywanie notatek do późniejszego przejrzenia i poprawienia.

Użytkownicy mogą korzystać z aplikacji do robienia notatek na ekranie blokady lub podczas uruchamiania innych aplikacji.

Obsługa rysika w przypadku robienia notatek zwiększa wygodę korzystania z urządzenia.

Rola dotycząca notatek

Rola RoleManager.ROLE_NOTES określa aplikacje do robienia notatek i przyznaje im uprawnienia LAUNCH_CAPTURE_CONTENT_ACTIVITY_FOR_NOTE.

Aby przypisać rolę notatek do aplikacji, wykonaj te czynności:

  1. Aby sprawdzić stan roli, wywołaj isRoleAvailable().
  2. Jeśli rola notatek jest dostępna, wywołaj createRequestRoleIntent(), aby uzyskać intencję związaną z notatkami.
  3. Wywołaj startActivityForResult() z intencją notatek, by poprosić użytkownika o przypisanie roli notatek do Twojej aplikacji.

Rolę do notatek może mieć tylko jedna aplikacja.

Aplikacja otwiera się w odpowiedzi na ukryte działanie ACTION_CREATE_NOTE. Jeśli wywołasz ją z ekranu blokady urządzenia, otworzy się pełny ekran, a jeśli zostanie wywołana przy odblokowanym ekranie – w pływającym oknie.

Plik manifestu aplikacji

Aby kwalifikować się do roli notatek, w manifeście aplikacji musi znajdować się ta deklaracja:

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

Deklaracja umożliwia użytkownikom przypisanie roli notatek do Twojej aplikacji, dzięki czemu jest ona domyślną aplikacją do robienia notatek:

  • ACTION_CREATE_NOTE określa działanie intencji, na które reaguje aplikacja

  • showWhenLocked umożliwia dostęp do aplikacji z ekranu blokady urządzenia

  • turnScreenOn umożliwia aplikacji włączanie ekranu urządzenia po jej uruchomieniu

Funkcje aplikacji

Aplikacja do robienia notatek z rozmaitymi funkcjami na dużym ekranie oferuje pełny zestaw funkcji robienia notatek.

Obsługa rysika

Gdy aplikacja zostanie wywołana z dodatkową intencją EXTRA_USE_STYLUS_MODE ustawioną na true, aplikacja powinna otworzyć notatkę, która obsługuje wprowadzanie za pomocą rysika (lub dotykania palca).

Jeśli dodatkowa intencja ma wartość false, aplikacja powinna otworzyć notatkę, która akceptuje wprowadzanie tekstu z klawiatury.

Dostęp do ekranu blokady

Aplikacja musi udostępniać działanie pełnoekranowe, uruchamiane po otwarciu na ekranie blokady urządzenia.

Aplikacja powinna wyświetlać wcześniejsze notatki tylko wtedy, gdy użytkownik wyraził zgodę na wyświetlanie wcześniejszych notatek (w stanie odblokowanym urządzenia). W przeciwnym razie po otwarciu aplikacji na ekranie blokady aplikacja powinna zawsze tworzyć nową notatkę.

Aby sprawdzić, czy Twoja aplikacja została uruchomiona na ekranie blokady, użyj narzędzia KeyguardManager#isKeyguardLocked(). Aby poprosić użytkownika o uwierzytelnienie i odblokowanie urządzenia, wywołaj metodę 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.
  }
});

Pływające okna

Aby można było tworzyć kontekstowe notatki, aplikacja musi udostępniać działanie, które otwiera się w pływającym oknie, gdy działa inna aplikacja.

Aplikacja powinna obsługiwać tryb multi-instance, aby użytkownicy mogli tworzyć wiele notatek w wielu pływających oknach, nawet gdy aplikacja do robienia notatek jest uruchomiona na pełnym ekranie lub w trybie podzielonego ekranu.

Rejestrowanie treści

Przechwytywanie treści to jedna z najważniejszych funkcji aplikacji do robienia notatek. Dzięki funkcji przechwytywania treści użytkownicy mogą zrobić zrzuty ekranu wyświetlacza znajdującego się za pływającym oknem aplikacji do sporządzania notatek. Użytkownicy mogą zarejestrować cały obraz lub jego część, wkleić treść do notatki, a także dodać adnotacje lub wyróżnienia.

Aplikacja do robienia notatek powinna zapewniać interfejs użytkownika uruchamiający ActivityResultLauncher utworzony przez registerForActivityResult(). Działanie intencji ACTION_LAUNCH_CAPTURE_CONTENT_ACTIVITY_FOR_NOTE jest przekazywane do programu uruchamiającego bezpośrednio lub przez ActivityResultContract.

Aktywność systemu przechwytuje treść, zapisuje ją na urządzeniu i zwraca identyfikator URI treści do aplikacji w argumencie wywołania zwrotnego registerForActivityResult().

Ten przykład korzysta z ogólnej umowy 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));
        });
}

Aplikacja powinna obsługiwać wszystkie kody wyników:

Gdy przechwytywanie treści się powiedzie, wklej przechwycony obraz do notatki, na przykład:

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

Funkcja przechwytywania treści powinna być dostępna za pośrednictwem interfejsu użytkownika tylko wtedy, gdy aplikacja do robienia notatek działa w pływającym oknie – nie wtedy, gdy jest uruchomiona na pełnym ekranie, uruchamiana z poziomu ekranu blokady urządzenia. Użytkownicy mogą robić zrzuty ekranu samej aplikacji do robienia notatek za pomocą funkcji wykonywania zrzutów ekranu na urządzeniu.

Aby określić, czy aplikacja jest w pływającym oknie (lub dymku), wywołaj te metody:

  • isLaunchedFromBubble(), aby sprawdzić, czy aplikacja do robienia notatek nie została uruchomiona na pełnym ekranie z ekranu blokady urządzenia
  • isRoleHeld(RoleManager.ROLE_NOTES), aby sprawdzić, czy aplikacja jest domyślną aplikacją do robienia notatek (może działać w ramach rozmowy lub w innym dymku, jeśli nie pełni funkcji notatek).

Dodatkowe materiały