---
title: "Cum construiești o aplicație de scanare coduri de bare pentru depozit, pe scanere Android"
description: "O aplicație de scanare pentru depozit transformă codul citit de un terminal Android industrial într-un răspuns pe care culegătorul îl înțelege dintr-o privire. Luăm scanarea de la scanerul hardware ca broadcast, trecem toate ecranele prin același handler de scanare, scriem stările ca etichete scurte, cu culoarea pentru gravitate, și măsurăm fiecare culoare de text pe fiecare fundal, în tema de zi și în cea de noapte. Majoritatea bug-urilor noastre au fost reparații care existau pe un ecran și lipseau de pe celelalte."
date: 2026-10-11
lang: ro
canonical: https://goingstellar.ro/ro/metode/aplicatie-scanare-depozit-scanere-android/
author: Going Stellar
publisher: GOING STELLAR S.R.L.
topic: Inginerie / Scanare în depozit
license: CC BY 4.0
alternate_en: https://goingstellar.ro/methods/warehouse-scanning-app-android-rugged-scanners/
---

# Cum construiești o aplicație de scanare coduri de bare pentru depozit, pe scanere Android

*O aplicație de scanare pentru depozit transformă codul citit de un terminal Android industrial într-un răspuns pe care culegătorul îl înțelege dintr-o privire. Luăm scanarea de la scanerul hardware ca broadcast, trecem toate ecranele prin același handler de scanare, scriem stările ca etichete scurte, cu culoarea pentru gravitate, și măsurăm fiecare culoare de text pe fiecare fundal, în tema de zi și în cea de noapte. Majoritatea bug-urilor noastre au fost reparații care existau pe un ecran și lipseau de pe celelalte.*

> Inginerie · Scanare în depozit · 2026-10-11 · https://goingstellar.ro/ro/metode/aplicatie-scanare-depozit-scanere-android/

## Pe scurt

- Pe scanerele Android industriale, modul Intent cu livrare Broadcast ajunge la aplicație pe orice ecran; aceeași setare pe Start Activity pare corectă și nu livrează nimic.
- Într-o aplicație cu mai multe ecrane care scanează, o reparație făcută pe un ecran nu ajunge la celelalte, deci caută același cod de scanare pe toate ecranele înainte să închizi un bug.
- Textul de stare de pe un scaner de depozit trebuie să fie o etichetă „câmp: valoare”, cu culoarea pentru gravitate, pentru că culegătorul îl citește dintr-o privire, cu coletul în mână.
- Tema de noapte e corectă doar când fiecare culoare de text și fiecare culoare de fundal au o pereche care trece pragul de contrast în ambele lumini, inclusiv jetoanele care se inversează între teme.
- Un APK mare servit de un singur proces al aplicației poate bloca cererea mică de verificare a versiunii, așa că fișierele mari se servesc din serverul web.

## Ce trebuie să facă o aplicație de scanare pentru depozit

O aplicație de scanare pentru depozit este programul de pe un terminal Android industrial (un calculator de mână cu scaner de coduri de bare încorporat) care primește fiecare cod citit și îi arată culegătorului ce are de făcut: cărei comenzi îi aparține coletul, dacă e deja pregătit, dacă a plecat deja. Ca aplicația să funcționeze, primești scanarea de la scanerul hardware ca broadcast Android, treci toate ecranele printr-o singură cale de scanare și nu pierzi niciodată o scanare în tăcere.

Avem o aplicație internă de scanare în stațiile noastre de depozit, iar nucleul ei l-am portat ulterior în **Pick Forge**, aplicația noastră publică de Shopify pentru culesul comenzilor verificat prin cod de bare. Pick Forge este aprobată și listată în Shopify App Store, dar încă nedovedită în depozitul unui comerciant real. Lecțiile de mai jos vin din aplicația internă.

## Pasul 1: scoate scanarea din scanerul hardware

Pe terminalele Urovo, aplicația de setări le numește **Keystroke** (scanerul tastează codul ca o tastatură) și **Intent** (scanerul trimite un broadcast Android cu codul într-un câmp extra). Un terminal nou sau resetat nu vine configurat pe niciunul așa cum se așteaptă aplicația, iar simptomul e mereu același: „scanez și nu se întâmplă nimic”.

**Modul Intent e alegerea sigură.** Broadcastul ajunge la aplicație pe orice ecran, indiferent ce câmp are focus. Capcana e modul de livrare: dacă e pus pe *Start Activity* sau *Start Service* în loc de *Broadcast*, totul pare configurat, iar receptorul aplicației nu primește nimic. Modul Clipboard nu merge deloc.

**Modul Keystroke cere sufixul Enter.** Fără terminator, codul se scrie în bara de scanare și rămâne acolo. Tot modul Keystroke ajunge doar într-un câmp cu focus, așa că ecranul de bază strânge tastele până la Enter cât timp niciun câmp de scris n-are focus și dă codul aceluiași handler pe care îl folosește modul Intent.

**Diagnosticul se pune din bara de scanare, nu din cont.** Dacă codul apare în bară și nu se deschide nimic, Keystroke n-are sufixul Enter. Dacă nu apare nimic, modul Intent are livrarea greșită, terminalul e pe Clipboard sau scanerul e oprit. Dacă se deschide comanda, scanerul e bun. Un coleg nou a pierdut odată aproape o oră cât am căutat pe server și în drepturile lui; diferența era terminalul. Când ceva nu merge la un singur om, întreabă întâi ce arată bara de scanare.

## Pasul 2: o singură cale de scanare pentru toate ecranele

O aplicație de scanare ajunge să aibă mai multe ecrane care scanează: ecranul principal, culesul în lot, culesul în val, ambalarea. Dacă fiecare ecran are propriul handler, o reparație pe unul nu ajunge la celelalte. La noi, fiecare handler ieșea imediat cât timp cererea anterioară era încă în lucru, deci scanarea următoare se pierdea în tăcere. Pe ecranul principal fusese reparat, cu un comentariu care descria exact simptomul: „omul scana 10 colete și jumătate nu se înregistrau”. Ecranele de lot și de ambalare păstraseră aceeași linie, iar oamenii au raportat-o mai târziu ca „se încarcă greu”.

Reparația, pe fiecare ecran, e o coadă plus afișare din cache. Scanările intră la rând și se procesează în ordine. Cardul comenzii apare imediat dintr-un instantaneu local de pe terminal, iar serverul îl reconciliază în liniște. Măsurat pe o zi, 67,2% din codurile scanate erau deja în instantaneul local. Bipul și avertismentele („deja pregătită”, „a plecat”) așteaptă în continuare răspunsul serverului, pentru că instantaneul local nu știe starea culesului.

Depozitul ceruse ca scanările să fie strânse **5** secunde într-o singură cerere. Am măsurat întâi: o scanare costa **47** ms pe server, deci comasarea ar fi economisit vreo **100** ms în schimbul a cinci secunde de orbire. Când repari un comportament de scanare, caută aceeași linie pe toate ecranele înainte să închizi sarcina.

## Pasul 3: scrie pentru o privire, nu pentru citit

Textul de stare dintr-o aplicație de scanare trebuie să fie o etichetă de forma **câmp: valoare**, nu o propoziție. Culegătorul citește ecranul dintr-o privire, cu coletul în mână. „AWB vechi: [număr] · anulat” se vede instant, ca un câmp de formular; „lucrezi acum pe o etichetă nouă” trebuie citit și înțeles și pare un chat, nu o unealtă. Responsabilul depozitului a respins toate formulările conversaționale pe care le-am încercat. Culoarea poartă gravitatea: verde pentru fluxul normal, roșu doar pentru o problemă reală.

Am scos și toate emoji-urile și glifele decorative din interfață, după ce ni s-a cerut de două ori. Starea și categoria sunt text simplu, cu un punct colorat sau o pastilă în nuanță pală acolo unde ajută. Săgeata de navigare dintr-o listă rămâne, fiindcă e o convenție standard.

## Pasul 4: tema de noapte e o regulă despre perechi de culori

Tema de noapte a unei aplicații Android funcționează doar dacă fiecare culoare de text are pereche de noapte *și* fiecare culoare de fundal are și ea una. Noaptea, culegătorii nu mai vedeau scrisul, pentru că multe culori nu treceau deloc prin temă. Culorile ajungeau pe ecran pe trei canale: resursele temei, care se schimbă singure; culorile scrise direct în cod, care nu se schimbă niciodată; și referințele XML spre jetoane de culoare fără variantă de noapte. Am numărat 351 de culori scrise în cod, dintre care 169 folosite ca text, iar 77 dintre acestea erau noaptea sub pragul WCAG AA. Cea mai rea avea 1,03:1, practic invizibilă.

Am încetat să alegem culori din ochi. Un mic analizor extrage fiecare culoare scrisă în cod, o clasifică drept text sau fundal după linia pe care stă și calculează contrastul WCAG față de fiecare fundal al temei, în ambele lumini. Un al doilea script găsește cea mai apropiată culoare care atinge un prag, păstrând nuanța.

**Bug-ul în oglindă: un jeton de text folosit ca fundal.** Un jeton închis ziua și deschis noaptea e corect pentru text și greșit ca umplutură sub text alb fix. Am adăugat un jeton neutru de umplutură, închis în ambele teme, și o verificare care caută toată clasa de cazuri. Când schimbi înțelesul unui jeton, caută-i și folosirile pe rolul vechi: am remapat un jeton pe umplutură, iar 5 locuri care îl foloseau ca text au căzut la 2,23:1, la câteva minute după.

Paletele de accent alese de utilizator sunt atribute de temă; toate cele 10 combinații, 5 palete × 2 teme, trec de 4,5:1 pentru text și 3:1 pentru umpluturi. Accentul nu intră pe textul de stare: pe paleta verde ieșea la 1,01:1 față de verdele care înseamnă „e bine”.

## Actualizări și setări pe magazin

**Servește APK-ul din serverul web, nu din procesul aplicației.** Culegătorii au spus că nu apare nicio actualizare. Comparația de versiuni era corectă; verificarea expira. APK-ul de 29 MB trecea prin singurul proces Python, care răspundea și la cererea minusculă de versiune. Pe o zi cu 235 de verificări, cele de lângă o descărcare de APK aveau percentila 90 de 14,97 s, iar 8 au eșuat; cele fără descărcare în preajmă durau 0,02 s. Serviți de serverul web, cei 29 MB au venit în 0,23 s. Verificarea avea și două căi de eșec tăcute care arătau exact ca „ești la zi”; o verificare cerută explicit spune acum când a eșuat.

**Învață cuvintele depozitului înainte să construiești pe ele.** Când ni s-a cerut ca un administrator să aleagă „pentru ce categorie” e obligatorie scanarea produsului, am construit pe tipurile de produs din platforma magazinului, 83 doar într-un magazin. În depozit, „categorie” însemna magazinul. Cheia corectă pentru o setare pe magazin s-a dovedit prefixul numărului de comandă, pe care l-am măsurat unu-la-unu cu magazinul pe 30 de magazine, în 30 de zile. Setarea se decide pe server, într-un singur loc, și validează prefixul la scriere, ca o greșeală de tastare să nu creeze o setare care nu se potrivește tăcut cu nimic.

## Unde am greșit și ce nu garantează metoda

Greșeala noastră recurentă a avut aceeași formă de mai multe ori: o reparație care trăia pe un singur ecran sau pe o singură cale de cod. Acum întrebarea „ce alte ecrane fac asta?” face parte din fiecare reparație.

Stocul numărat fizic la o stație e o capcană separată. Dacă aduni numărătoarea peste stocul existent, inventezi marfă; întrebarea de pus întâi e dacă marfa a fost mutată din altă locație (deci e deja în sistem) sau a venit direct la stație (deci nu e). La o numărătoare reală de 34 de SKU-uri, doar 12 au fost urcate. În Shopify Admin API, `inventoryMoveQuantities` nu mută stoc între locații; pentru asta folosești `inventorySetQuantities` cu o linie negativă și una pozitivă.

Metoda nu garantează că un terminal vine configurat, că verificarea de contrast acoperă culori pe care nu le treci prin ea. Nici magazinele altora nu seamănă cu ale noastre: la primul test real al Pick Forge, numerele de comandă erau pur numerice și multe linii n-aveau SKU, două cazuri pe care prefixele noastre interne le ascunseseră.

## Listă de verificare

**1. **Scanerul pe Intent cu livrare Broadcast sau pe Keystroke cu sufix Enter; niciodată Clipboard. **2. **O singură cale de scanare pe toate ecranele; nicio ieșire timpurie care aruncă o scanare. **3. **Coadă plus card din cache; avertismentele doar pe răspunsul serverului. **4. **Starea scrisă „câmp: valoare”, culoarea pentru gravitate, fără emoji. **5. **Fiecare pereche text-fundal măsurată în ambele teme. **6. **Fișierele mari servite de serverul web; o verificare eșuată nu arată niciodată ca una reușită.

## Întrebări și răspunsuri

### De ce scanerul Android citește codul, dar aplicația nu face nimic?

Pe terminalele Android industriale, de exemplu Urovo, scanerul trimite codurile în modul Keystroke sau Intent. Dacă în bara de scanare apare codul, dar nu se deschide nimic, modului Keystroke îi lipsește sufixul Enter. Dacă nu apare nimic, de obicei modul Intent are livrarea pe Start Activity sau Start Service în loc de Broadcast, terminalul e pe Clipboard sau scanerul e oprit. Verifică bara de scanare înainte de conturi sau server.

### Aplicația de depozit ar trebui să folosească modul tastatură sau broadcast?

Mai bine broadcast, pentru că un broadcast ajunge la aplicație pe orice ecran, indiferent ce câmp are focus. Modul tastatură, numit Keystroke pe terminalele Urovo, merge doar cu sufixul Enter și ajunge doar într-un câmp cu focus, dacă aplicația nu strânge ea tastele până la Enter. Dacă le suporți pe amândouă printr-un singur handler comun, merg terminalele configurate în oricare mod.

### Cum oprești o aplicație de scanare să piardă scanări când culegătorul scanează repede?

Aplicația pierde scanări când handlerul ignoră o scanare nouă cât timp cererea anterioară e încă în lucru. Pune scanările într-o coadă și procesează-le în ordine, iar cardul comenzii arată-l imediat dintr-un instantaneu local, cât serverul confirmă. Avertismente precum „deja pregătită” rămân pe răspunsul serverului. Aplică aceeași reparație pe fiecare ecran care scanează, pentru că fiecare ecran are adesea propriul handler.

### Cum faci lizibilă tema de noapte într-o aplicație Android de depozit?

Treci toate culorile prin temă și măsoară contrastul în loc să alegi din ochi. Culorile scrise direct în cod nu se schimbă cu tema, iar jetoanele de text închise ziua și deschise noaptea devin ilizibile când sunt folosite ca fundal sub text alb fix. Măsoară contrastul WCAG pentru fiecare pereche text-fundal în ambele lumini și folosește un jeton separat de umplutură, care rămâne închis în ambele teme.

### E bine să pui iconițe și emoji într-o aplicație de scanare pentru depozit?

La noi, nu. Culegătorii citesc ecranul dintr-o privire, așa că arătăm starea ca etichete scurte „câmp: valoare”, în text simplu, cu un punct colorat sau o pastilă în nuanță pală unde ajută, iar culoarea spune gravitatea: verde pentru fluxul normal, roșu doar pentru o problemă reală. Săgeata de navigare dintr-o listă rămâne, ca convenție standard; glifele decorative și emoji-urile au fost scoase.

## Cum se citează

**Citare:** Going Stellar (2026). *Cum construiești o aplicație de scanare coduri de bare pentru depozit, pe scanere Android*. GOING STELLAR S.R.L.. https://goingstellar.ro/ro/metode/aplicatie-scanare-depozit-scanere-android/

```bibtex
@misc{goingstellar2026warehouse,
  title  = {Cum construiești o aplicație de scanare coduri de bare pentru depozit, pe scanere Android},
  author = {{Going Stellar}},
  year   = {2026},
  url    = {https://goingstellar.ro/ro/metode/aplicatie-scanare-depozit-scanere-android/},
  note   = {2026-10-11}
}
```

Licență. Se poate cita liber, cu atribuire.

## Mai există și

- Pagina în HTML: https://goingstellar.ro/ro/metode/aplicatie-scanare-depozit-scanere-android/
- Același articol în engleză: https://goingstellar.ro/methods/warehouse-scanning-app-android-rugged-scanners/
