Criar um app de anotações

A criação de anotações é um recurso importante do Android, que aumenta a produtividade do usuário em em dispositivos de tela grande. Os apps de anotações permitem que os usuários escrevam e desenhem em uma janela flutuante ou em tela cheia, capturam e fazem anotações do conteúdo da tela, e salvar anotações para revisão posterior.

Os usuários podem acessar os apps de anotação na tela de bloqueio ou ao executar outros apps.

O suporte da stylus à criação de anotações proporciona uma experiência excepcional aos usuários.

Papel de anotações

A RoleManager.ROLE_NOTES identifica apps de anotação e concede a eles o LAUNCH_CAPTURE_CONTENT_ACTIVITY_FOR_NOTE permissão.

Para adquirir o papel de anotações do seu app, faça o seguinte:

  1. Chamar isRoleAvailable() para verificar o status da função.
  2. Se o papel de anotações estiver disponível, chame createRequestRoleIntent(). para receber uma intent específica.
  3. Chamar startActivityForResult() com a intent de anotações para solicitar que o usuário conceda esse papel à sua app.

Apenas um app pode ter esse papel.

O app é aberto em resposta a uma ACTION_CREATE_NOTE ação da intent. Se invocado pela tela de bloqueio do dispositivo, o app é aberto completamente tela; se invocado enquanto a tela está desbloqueada, em uma janela flutuante.

Manifesto do app

Para se qualificar para o papel de anotações, o app precisa incluir a seguinte declaração no manifesto do app:

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

A declaração permite que os usuários atribuam o papel de anotações ao app, o que faz o aplicativo de anotações padrão:

  • ACTION_CREATE_NOTE define a ação da intent à qual seu app responde

  • showWhenLocked torna o app acessível na tela de bloqueio do dispositivo

  • O turnScreenOn ativa seu app para ativar a tela do dispositivo quando ele for executado

Recursos do app

Um app de anotações diferenciado para telas grandes oferece um complemento completo de recursos de anotação.

Compatibilidade com stylus

Quando seu app é invocado com o EXTRA_USE_STYLUS_MODE definido como true, o app abrirá uma anotação que aceite a stylus (ou entrada por toque do dedo).

Se o extra da intent estiver definido como false, seu app precisará abrir uma anotação que aceite a entrada do teclado.

Acesso pela tela de bloqueio

O app precisa oferecer uma atividade em tela cheia que é executada quando ele é aberto na tela de bloqueio do dispositivo.

Seu aplicativo só deve mostrar notas de histórico se o usuário tiver consentido (na estado do dispositivo desbloqueado) para mostrar notas anteriores. Caso contrário, quando aberto do da tela de bloqueio, seu app deve sempre criar uma nova anotação.

É possível verificar se o app foi iniciado na tela de bloqueio com KeyguardManager#isKeyguardLocked() Para pedir ao usuário para autenticar e desbloquear o dispositivo, chame 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.
  }
});

Janelas flutuantes

Para anotações contextuais, o app precisa oferecer uma atividade que se abra em uma uma janela flutuante quando outro aplicativo está em execução.

Seu app precisa oferecer suporte multi-instance para que os usuários possam criar várias notas em diversas janelas flutuantes quando o app de anotações é iniciado em tela cheia ou em tela dividida. modo

Captura de conteúdo

A captura de conteúdo é um recurso importante dos apps de anotação. Com conteúdo captura, os usuários podem fazer capturas da tela por trás das anotações da janela flutuante do app. Os usuários podem capturar toda a tela ou parte dela, colar o o conteúdo nas notas e anotar ou destacar o conteúdo capturado.

Seu app de anotações precisa fornecer uma funcionalidade de interface que inicie uma ActivityResultLauncher criado por registerForActivityResult() A ACTION_LAUNCH_CAPTURE_CONTENT_ACTIVITY_FOR_NOTE é fornecida ao inicializador diretamente ou por meio de um ActivityResultContract

Uma atividade do sistema captura o conteúdo, salva-o no dispositivo e retorna URI de conteúdo para seu app no argumento de retorno de chamada de registerForActivityResult():

O exemplo a seguir usa uma expressão StartActivityForResult contrato:

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

Seu app precisa processar todos os códigos de resultado:

Quando a captura de conteúdo for concluída, cole a imagem capturada na nota para exemplo:

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

O recurso de captura de conteúdo deve ser exposto por meio de uma funcionalidade de interface somente quando seu app de anotações está sendo executado em uma janela flutuante, não quando executado em tela cheia, iniciado a partir da tela de bloqueio do dispositivo. (Os usuários podem capturas de tela do próprio app de anotações com a captura de tela do dispositivo recursos.

Para determinar se o app está em uma janela flutuante (ou um balão), chame o método seguintes métodos:

  • isLaunchedFromBubble() para verificar se o app de anotações não foi iniciado em tela cheia pela a tela de bloqueio do dispositivo
  • isRoleHeld(RoleManager.ROLE_NOTES) verificar se o app é o padrão para anotações (ele pode ser executado em uma conversa ou outro tipo de balão se o aplicativo não contiver o anotações)
.

Outros recursos