plugin_scanner_qr 0.4.1
plugin_scanner_qr: ^0.4.1 copied to clipboard
Plugin Flutter para leitura de QR Code no Android usando ML Kit e CameraX. Oferece leitura única em tela cheia e leitura contínua com preview embutido na árvore de widgets (PlatformView), com debounce [...]
0.4.1 #
Compatibilidade com páginas de memória de 16 KB #
Desde 01/11/2025 o Google Play recusa apps com targetSdk 35+ cujas
bibliotecas nativas não estejam alinhadas em 16 KB — o erro aparece no Console
como "Seu app não é compatível com tamanhos de página de 16 KB". As versões que
o plugin usava traziam duas libs alinhadas em 4 KB:
libbarhopper_v3.so, do ML Kit Barcode Scanninglibimage_processing_util_jni.so, do CameraX
Correção — dependências atualizadas para as primeiras versões realinhadas:
- ML Kit Barcode Scanning 17.2.0 → 17.3.0
- CameraX (
camera-core,camera-camera2,camera-lifecycle,camera-view) 1.3.4 → 1.4.2
Sem mudança de API pública do plugin: quem já usa a 0.4.0 só precisa subir a versão. Aplicativos que ainda não publicam na Play não são afetados pelo erro, mas se beneficiam das correções dessas versões do CameraX.
0.4.0 #
Beep de confirmação #
playBeep()— beep nativo viaToneGenerator(os tons DTMF do sistema): alto, latência praticamente zero, sem assets e sem dependência de áudio. Pensado para kiosk/totem, onde o operador depende do retorno audível de "batida aceita" vs "batida recusada" —SystemSound.playdo Flutter é discreto demais e varia por fabricante.- Parametrizável:
tone(QrBeepTone:beep,doubleBeep,confirm,deny,error,alert),duration,volume(0–100) estream(QrBeepStream:music,alarm,notification—alarmtem volume independente do de mídia, mais difícil de silenciar por acidente num totem). - Atalhos
beepSuccess()(tom de confirmação) ebeepError()(tom de erro, mais longo). - Nunca lança: se o hardware de áudio recusar, retorna
false. - Example: beep de sucesso a cada leitura + botões "beep ok"/"beep erro".
0.3.0 #
Calibração de câmera no preview embutido #
Pensada para kiosk/totem (ex.: relógio de ponto) em ambiente de muita luz e aparelhos com autofoco lento (ex.: Galaxy A03s). Tudo é opcional e com degradação segura — quem não configurar nada mantém o comportamento anterior, com uma única exceção deliberada: a resolução da análise.
- Resolução da análise configurável — novo padrão 1280x720. O default do
CameraX (640x480) entrega poucos pixels por módulo do QR, e qualquer desfoque
leve inviabiliza a leitura.
QrScannerController(analysisResolution: ...)aceitaQrAnalysisResolution.sd(640x480, comportamento antigo),.hd(novo padrão),.fullHdou um valor customizado. O CameraX negocia a resolução suportada mais próxima; a negociada aparece emgetCameraCapabilities(). - Modos de foco (
QrFocusMode) viafocusMode:no construtor ousetFocusMode()em runtime:continuous— autofoco contínuo do CameraX (padrão, igual a antes);periodic— dispara um foco no centro do frame a cada intervalo (autoFocusInterval, padrão 3 s) — para aparelhos cujo AF por contraste "caça" e trava num plano errado;fixed— desliga o AF e trava a lente numa distância fixa em dioptrias (focusDistance; 25 cm ≈ 4.0) via Camera2 Interop — ideal para totem, onde a distância de leitura é sempre a mesma. Se o aparelho não expõe foco manual, cai silenciosamente emcontinuousesetFocusMode()retornafalse.
- Compensação de exposição —
setExposureCompensation(index), com clamp automático ao range do aparelho. Índices negativos escurecem a cena (útil contra reflexo de QR em tela de celular). - Zoom linear —
setLinearZoom(0.0–1.0); um valor pequeno faz o QR ocupar mais pixels na distância típica do totem. getCameraCapabilities()— snapshot do que o hardware suporta: foco manual (e range em dioptrias), calibração da escala de foco, range/passo da exposição, range de zoom, flash e resolução de análise negociada. Feito para validar em campo o que o aparelho do totem aceita.- Example — novo painel "Calibração da câmera" no preview embutido: capabilities ao vivo, seletor de modo de foco, sliders de distância/exposição/ zoom e seletor de resolução SD/HD/FullHD (recria o preview, preservando câmera e lanterna).
Sem breaking changes.
0.2.0 #
Preview embutido (PlatformView) #
QrScannerPreview+QrScannerController— a leitura contínua agora usa uma PlatformView embutida na árvore de widgets, em vez de uma Activity de tela cheia. Isso permite desenhar UI Flutter por cima do preview: overlay de status, botões, drawer eshowDialog.- Renderização com
PreviewView.ImplementationMode.COMPATIBLE(TextureView) e Texture Layer Hybrid Composition (initSurfaceAndroidView).hybridComposition: truedisponível como alternativa. - Canais por instância (
preview_$viewId), eliminando oEventSinkestático. Eventos agora sãoMapcom discriminadortype(barcode/cameraOpened/error), em vez deStringcrua. PreviewLifecycleOwner— cada preview tem seu próprioLifecycleRegistry, combinando intenção do Dart + foreground da Activity + view anexada.pauseScanning/resumeScanningnão recriam mais as use cases do CameraX.
Correções #
- Permissão de câmera não mente mais.
requestCameraPermission()respondiatrueantes de o usuário decidir, e a Activity pedia permissão sem trataronRequestPermissionsResult— resultado: tela preta permanente na primeira execução. Agora háRequestPermissionsResultListenere oFuturesó completa após a resposta real. - Novo
hasCameraPermission()— consulta pura. O plugin não solicita permissão no caminho do preview, evitandoCan request only one set of permissions at a timequando o app usapermission_handler. - Vazamentos corrigidos: cliente do ML Kit era criado a cada
switchCamera()e nunca fechado;cameraExecutorsó era desligado no modo contínuo (sair pelo botão voltar vazava);scanEventSinkestático e singletonMlKitScannerActivity.currentremovidos; listeners de Activity agora são desregistrados no detach. unbind(preview, analysis)em vez deunbindAll()—ProcessCameraProvideré singleton de processo eunbindAll()derrubaria outros consumidores de câmera.uses-feature android:requiredpassou afalse— comotrue, era mesclado no app consumidor e o removia da Play Store para aparelhos sem câmera.- Removido o atributo
packagedo manifest da lib (obsoleto no AGP 8) e o blocodependencies {}que estava aninhado dentro deandroid {}. - Removidas ~200 linhas de pipeline CameraX morto (
startCamera,bindCameraUseCases,stopScanner,QRCodeAnalyzer) que nunca eram alcançadas. - Corrigido o teste de widget do example, que procurava um texto inexistente.
Breaking changes #
startContinuousScanrespondeUNSUPPORTED. UseQrScannerPreviewcomQrScannerController.ContinuousQrScannere os métodos globais do modo contínuo seguem disponíveis, marcados@Deprecated; os globais delegam para a últimaQrScannerPreviewcriada.requestCameraPermission()marcado@Deprecated— prefira gerenciar a permissão no app.- CameraX 1.3.1 → 1.3.4. Requer
ndkVersion = "27.0.12077973"no app consumidor.
0.1.0 #
- Leitura contínua oficializada — API pública completa com
startContinuousScan,pauseScanning,resumeScanningestopContinuousScan. - Novos modelos Dart —
ContinuousScanOptions(debounce, cooldown, câmera, orientação, torch) eQrScanResult(valor + timestamp). ContinuousQrScanner— helper de alto nível que encapsula permissão, abertura da câmera e ciclo de vida do stream.- Debounce nativo — o Android suprime reemissões do mesmo QR dentro do intervalo
duplicateDebounce(padrão 1500 ms), sem round-trip para o Flutter. - Cooldown nativo — após cada leitura, o scanner pausa automaticamente pelo tempo configurado em
cooldown(padrãoDuration.zero= sem pausa). - Toasts removidos por padrão — feedback visual de "Leitura pausada/retomada" agora só é exibido quando
showNativeFeedback: true. PluginScannerQrrefatorada como fachada fina; toda lógica de canal delegada àPluginScannerQrPlatform.onBarcodeScanned— stream oficial tipado comoStream<QrScanResult>na platform interface e no method channel.- Example atualizado para usar
ContinuousQrScannercom slider de cooldown configurável.
0.0.1 #
- Versão inicial com leitura única (
scanQRCode,scanQRCodeWithOptions).