Verdetto
Português (Brasil)

Escanear a partir de outro app

O Verdetto responde a três intents e a um compartilhamento. Nada aqui precisa de permissão, biblioteca ou chave. A pessoa mantém todas as verificações de segurança e todas as configurações do app; seu app recebe o texto do código no momento em que ela o confirma.

Os intents

AçãoFiltro no manifestoO que aconteceResultado
com.google.zxing.client.android.SCANSim, intents implícitos funcionam.Abre o leitor. O primeiro código que a pessoa fixa é devolvido, como o ZXing Barcode Scanner fazia.RESULT_OK com SCAN_RESULT e SCAN_RESULT_FORMAT
app.scanner.action.SCANSim.Abre o leitor. Iniciado para um resultado (um result launcher ou startActivityForResult), devolve o código do mesmo jeito; iniciado sem mais, só abre o app no leitor.RESULT_OK com os dois extras quando iniciado para um resultado
app.scanner.action.CARDSem filtro: apenas um intent explícito com o pacote com.verdettoqr.scanner.Abre o editor do cartão de contato da própria pessoa, o código que ela mostra para compartilhar seus dados. Feito para os widgets e atalhos do próprio app; outro app pode chamá-lo, mas nada volta.Nenhum
android.intent.action.SEND com image/*Sim.Decodifica uma imagem: o app mostra a folha de resultado com os códigos que ela contém.Nenhum

A pessoa pode desligar a devolução em Configurações, em "Entregar resultados a outros apps" ("Quando um app pede um escaneamento, o código volta para ele"), que vem ligada. Desligada, qualquer das duas ações de leitura abre o leitor como uma abertura normal e seu launcher recebe RESULT_CANCELED quando a pessoa sai. Voltar do leitor também é RESULT_CANCELED.

Nenhum extra da requisição é lido hoje: nem SCAN_MODE, SCAN_FORMATS, PROMPT_MESSAGE, SAVE_HISTORY, nem qualquer outro. O leitor lê todas as simbologias que conhece em toda chamada. Um código que as verificações do app sinalizam ainda é devolvido; a pessoa vê o alerta primeiro e decide.

O resultado

  • SCAN_RESULT (String): o conteúdo do código, exatamente os bytes que ele carregava, decodificados como texto (UTF-8 onde a simbologia permite, e o conjunto de caracteres da própria simbologia nos outros casos).
  • SCAN_RESULT_FORMAT (String): a simbologia em maiúsculas com sublinhados, com os nomes do ZXing onde existem. Entregues hoje: QR_CODE, MICRO_QR_CODE, RMQR_CODE, DATA_MATRIX, AZTEC, PDF417, MAXICODE, HAN_XIN, EAN_13, EAN_8, UPC_A, UPC_E, CODE_128, CODE_39, CODE_93, CODABAR, ITF, DATABAR, DATABAR_EXPANDED, DATABAR_LIMITED, DX_FILM_EDGE, e as outras simbologias que os decodificadores próprios do app acrescentam, na mesma grafia (o nome mostrado na folha de resultado, em maiúsculas, com espaços e hifens como sublinhados).

Nada mais viaja: nenhuma imagem, nenhuma localização, nenhum histórico.

Kotlin

private val scan = registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { result ->
    if (result.resultCode == Activity.RESULT_OK) {
        val text = result.data?.getStringExtra("SCAN_RESULT")
        val format = result.data?.getStringExtra("SCAN_RESULT_FORMAT")
        // use text and format
    }
}

fun startScan() {
    val intent = Intent("app.scanner.action.SCAN")
    if (intent.resolveActivity(packageManager) != null) scan.launch(intent)
    else startActivity(Intent(Intent.ACTION_VIEW, Uri.parse(GET_VERDETTO)))
}

// the store page, with the developers referrer
private const val GET_VERDETTO =
    "https://play.google.com/store/apps/details?id=com.verdettoqr.scanner&referrer=utm_source%3Ddevelopers%26utm_medium%3Ddocs%26utm_campaign%3Ddevelopers"

No Android 11 e posteriores, adicione a consulta ao seu manifesto para que resolveActivity consiga ver o app:

<queries>
    <intent>
        <action android:name="app.scanner.action.SCAN" />
    </intent>
</queries>

Java

private final ActivityResultLauncher<Intent> scan = registerForActivityResult(
        new ActivityResultContracts.StartActivityForResult(), result -> {
            if (result.getResultCode() == Activity.RESULT_OK && result.getData() != null) {
                String text = result.getData().getStringExtra("SCAN_RESULT");
                String format = result.getData().getStringExtra("SCAN_RESULT_FORMAT");
                // use text and format
            }
        });

void startScan() {
    Intent intent = new Intent("app.scanner.action.SCAN");
    if (intent.resolveActivity(getPackageManager()) != null) scan.launch(intent);
    else startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse(GET_VERDETTO)));
}

A ação do ZXing

Código escrito para o ZXing Barcode Scanner continua funcionando: envie com.google.zxing.client.android.SCAN do mesmo jeito e leia os mesmos dois extras. Se mais de um leitor no celular responder, o sistema pergunta à pessoa qual usar; enviar o intent para o pacote com.verdettoqr.scanner pula isso.

O que a pessoa vê

O leitor abre como sempre, com suas próprias verificações. Quando um código é fixado, o app o devolve e fecha; nada seu aparece na tela, e nada dela (histórico, configurações, lista de segurança) é tocado pela chamada.

Testar em um celular sem o app. A página da loja com o referrer de desenvolvedores, o mesmo endereço que o fallback dos exemplos abre: Disponível no Google Play. A fonte desta página é o INTENT.md do próprio app; quando os dois divergem, o repositório do app está certo e esta página está atrasada.