Stwórz aplikację do robienia notatek

Robienie notatek to jedna z podstawowych funkcji Androida, która zwiększa produktywność użytkowników korzystających z urządzeń z dużymi ekranami. Aplikacje do notatek umożliwiają 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ą uzyskiwać dostęp do aplikacji do robienia notatek na ekranie blokady lub podczas uruchamiania innych aplikacji.

Obsługa rysika do robienia notatek zapewnia użytkownikom wyjątkowe wrażenia.

Rola w notatkach

Rola RoleManager.ROLE_NOTES identyfikuje aplikacje do notatek i przyzna im uprawnienie LAUNCH_CAPTURE_CONTENT_ACTIVITY_FOR_NOTE.

Aby uzyskać rolę związaną z notatkami w aplikacji:

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

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

Aplikacja otwiera się w odpowiedzi na niejawne działanie ACTION_CREATE_NOTE. W przypadku wywołania z ekranu blokady urządzenia aplikacja otwiera się na pełnym ekranie, a jeśli zostanie wywołana po odblokowaniu ekranu – w pływającym oknie.

Plik manifestu aplikacji

Aby kwalifikować się do roli notatek, aplikacja musi zawierać w manifeście tę deklarację:

<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 do aplikacji roli do notatek, dzięki czemu jest to domyślna aplikacja do robienia notatek:

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

  • showWhenLocked umożliwia dostęp do aplikacji na ekranie blokady urządzenia

  • turnScreenOn umożliwia aplikacji włączanie ekranu urządzenia, gdy aplikacja jest uruchomiona

Funkcje aplikacji

Zróżnicowana aplikacja do robienia notatek na dużym ekranie ma wszystkie funkcje.

Obsługa rysika

Po wywołaniu aplikacji z dodatkowym zamiarem EXTRA_USE_STYLUS_MODE ustawionym na true aplikacja powinna otworzyć notatkę, która akceptuje wprowadzanie rysikiem (lub dotknięciem palca).

Jeśli dodatek do intencji ma wartość false, aplikacja powinna otworzyć notatkę, która akceptuje dane z klawiatury.

Dostęp do ekranu blokady

Aplikacja musi udostępniać aktywność na pełnym ekranie, gdy jest otwierana z poziomu ekranu blokady urządzenia.

Aplikacja powinna wyświetlać notatki historyczne tylko wtedy, gdy użytkownik wyraził zgodę (na urządzeniu odblokowanym) na pokazywanie wcześniejszych notatek. Jeśli tego nie zrobisz, aplikacja zawsze powinna tworzyć nową notatkę po otwarciu na ekranie blokady.

Aby sprawdzić, czy aplikacja została uruchomiona na ekranie blokady, użyj 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żliwe było kontekstowe robienie notatek, aplikacja musi udostępniać aktywność, która otwiera się w pływającym oknie, gdy uruchomiona jest inna aplikacja.

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

Rejestrowanie treści

Przechwytywanie treści to kluczowa funkcja aplikacji do notatek. Funkcja przechwytywania treści pozwala użytkownikom robić zrzuty ekranu ekranu za pływającym oknem aplikacji do robienia notatek. Użytkownicy mogą przechwycić cały ekran lub jego część, wkleić treść do notatki i wyróżnić lub dodać adnotacje do zarejestrowanej treści.

Aplikacja do notatek powinna udostępniać interfejs użytkownika, który uruchamia ActivityResultLauncher utworzony przez użytkownika registerForActivityResult(). Intencję ACTION_LAUNCH_CAPTURE_CONTENT_ACTIVITY_FOR_NOTE jest przekazywana do programu uruchamiającego bezpośrednio lub za pomocą ActivityResultContract.

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

W tym przykładzie użyto 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:

Jeśli uda się przechwycić treści, wklej do notatki przechwycony obraz, 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ć widoczna w interfejsie tylko wtedy, gdy aplikacja do robienia notatek działa w pływającym oknie, a nie w trybie pełnego ekranu, ale uruchamiana z ekranu blokady urządzenia. (użytkownicy mogą robić zrzuty ekranu aplikacji do robienia notatek z wykorzystaniem funkcji tworzenia zrzutów ekranu).

Aby określić, czy aplikacja jest w pływającym oknie (lub w 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 potwierdzić, że aplikacja jest domyślną aplikacją do robienia notatek (aplikacja może uruchamiać się w rozmowie lub w dymku innego typu, jeśli nie ma przypisanej roli notatek).

Dodatkowe materiały