Tworzenie aplikacji POS na Androida, której nie można zamknąć

Opublikowany: 2022-03-11

Świat tworzenia aplikacji mobilnych jest rozległy i stale się rozwija, a nowe frameworki i technologie pojawiają się niemal codziennie. Kiedy myślisz o urządzeniu mobilnym, prawdopodobnie myślisz o telefonie lub tablecie, mimo że nie są one tak popularne jak smartfony.

iOS firmy Apple i Android firmy Google dominują na rynku mobilnym, a każdy z nich miał swoje wzloty i upadki w ciągu ostatniej dekady. Dzisiaj opowiem więcej o Androidzie i jego wykorzystaniu na urządzeniach, które niekoniecznie są mobilne.

Bycie open-source miało naprawdę interesujący efekt uboczny na mobilny system operacyjny Google. Jasne, możemy pomyśleć o wszystkich różnych forkach Androida od różnych producentów smartfonów, ale co z wszystkimi urządzeniami z Androidem, które nie są mobilne? Wszystko, począwszy od lodówek, inteligentnych piekarników, zamków do drzwi, a nawet urządzeń POS, może obecnie obsługiwać Androida. Te ostatnie są powodem, dla którego napisałem ten artykuł.

Urządzenia w punktach sprzedaży (POS) mogą obecnie obsługiwać system Android

Systemy Android POS

Mniej więcej rok temu bawiłem się urządzeniem z Androidem, które nie było zwyczajne i nie jest to coś, z czego większość ludzi prawdopodobnie korzysta. Omawiane urządzenie to oparty na Androidzie system POS od chińskiego dostawcy, który ma również zintegrowaną drukarkę termiczną (podobnie jak te używane do drukowania paragonów w sklepach lub w bankomatach).

Największą niespodzianką było jednak jego oprogramowanie: działała wersja Androida z kości. Jeśli dobrze pamiętam, w tamtym czasie był to Android 8 lub Android Oreo, jeśli wolisz kryptonimy Google. Samo urządzenie wygląda jak oldschoolowe przenośne urządzenie POS, ale zamiast fizycznej klawiatury, na której można wpisać kod PIN, ma pojemnościowy ekran dotykowy, taki jak te używane w telefonach z Androidem w przeszłości.

Moje wymaganie było proste: musiałem sprawdzić, czy istnieje sposób, w jaki moglibyśmy korzystać z funkcji tego urządzenia, takich jak drukarka termiczna, jednocześnie uruchamiając aplikację, którą tworzyliśmy. Gdy tylko zdałem sobie sprawę, że samo wymaganie jest możliwe, zwróciłem uwagę na inny problem: bezpieczeństwo .

Chodzi o to, że jeśli masz urządzenie obsługujące płatności kartą i inne rodzaje transakcji, możesz nie chcieć, aby to samo urządzenie mogło uruchamiać TikTok, Gmail lub Snapchat. To urządzenie zachowywało się dokładnie jak tablet, a nawet było fabrycznie zainstalowane w sklepie Google Play. Wyobraź sobie, że idziesz do małego sklepu spożywczego i widzisz, jak kasjer robi selfie, otwiera wiadomości e-mail od nigeryjskiego księcia i przegląda dziwne, wyładowane złośliwym oprogramowaniem strony internetowe.

A potem kasjer wręcza ci to samo urządzenie do wpisania kodu PIN. Osobiście nie czułbym się bezpiecznie, podając dane mojej karty kredytowej przez takie urządzenie.

Blokowanie użytkowników z menu Androida

Pomijając bezpieczeństwo, musiałem podjąć jeszcze ważniejsze wyzwanie: musiałem zablokować osobę korzystającą z urządzenia Android POS w mojej aplikacji. Mieszanie się z systemem operacyjnym nie wchodziło w grę, ponieważ urządzenia te były dostarczane do osób nietechnicznych.

Jasne, kasjerzy są w stanie zainstalować aplikację, ale większość z nich nie może flashować niestandardowych ROM-ów ani obsługiwać innych operacji niższego poziomu. Sama aplikacja została napisana w React Native, choć w tym kontekście nie ma to znaczenia. Wszystkie modyfikacje, które wprowadziłem, są w natywnym kodzie Java, więc bez względu na to, czego używasz do tworzenia głównej aplikacji, te poprawki powinny działać.

Jako małe zastrzeżenie, ta procedura działa tylko w aplikacjach na Androida . Apple nie daje nam kontroli, której potrzebujemy, aby łatwo wykonać coś takiego na iPhonie lub iPadzie, co jest zrozumiałe, biorąc pod uwagę zamknięty charakter iOS.

Istnieją cztery sposoby, w jakie użytkownik może wyjść z aplikacji:

  • Użyj przycisku Strona główna .
  • Użyj przycisku Wstecz .
  • Użyj przycisku Ostatnie .
  • Opuść aplikację przez pasek powiadomień .

Kliknięcie ostatniego powiadomienia lub przejście do ustawień z tego paska spowoduje wyjście użytkownika z naszej aplikacji. Masz również gesty, ale pod koniec dnia te gesty wywołują dokładnie te same czynności, co zwykłe naciśnięcia przycisków.

Ponadto posiadanie systemu PIN do odblokowania aplikacji może być naprawdę przydatne dla kogoś, kto zarządza urządzeniem. W ten sposób tylko osoba posiadająca PIN będzie mogła zainstalować inną wersję aplikacji, bez oferowania głębszego dostępu użytkownikowi końcowemu.

Przycisk Home

Aby uniemożliwić użytkownikowi naciśnięcie przycisku Home, nie musimy go faktycznie wyłączać.

Jedną z przydatnych funkcji Androida jest dostępność różnych programów uruchamiających. Zazwyczaj te aplikacje zapewniają różne ekrany główne, szuflady aplikacji i dostęp do różnych dostosowań interfejsu użytkownika. Każde urządzenie z Androidem ma jeden preinstalowany przez producenta. Ostatecznie są to po prostu normalne, zwykłe aplikacje z jednym małym, ale istotnym wyjątkiem.

Oznacza to, że gdyby system operacyjny mógł rozpoznać naszą aplikację jako program uruchamiający, moglibyśmy ustawić go jako domyślny program uruchamiający. Efektem ubocznym jest to, że za każdym razem, gdy naciśniesz przycisk Home, urządzenie przeniesie Cię do programu uruchamiającego Home. A jeśli nasza aplikacja to Home Launcher, to w zasadzie ten przycisk Home staje się bezużyteczny. Aby to zrobić, musimy edytować plik AndroidManifest XML w naszym projekcie Android i dodać te dwie linie kodu:

 <activity android:name=".MainActivity" android:label="@string/app_name" android:configChanges="keyboard|keyboardHidden|orientation|screenSize|uiMode" android:launchMode="singleTask" android:windowSoftInputMode="adjustResize"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> <category android:name="android.intent.category.HOME" /> <category android:name="android.intent.category.DEFAULT" /> </intent-filter> </activity>

Pierwsza linia umożliwi wybranie naszej aplikacji w przypadku, gdy użytkownik naciśnie przycisk Home, a druga linia pozwoli ustawić naszą aplikację jako domyślną za każdym razem, gdy ta akcja się wydarzy.

Teraz jedyne, co pozostało do zrobienia, to zainstalowanie aplikacji przez agenta terenowego na urządzeniu podczas dostarczania jej do klienta. Za każdym razem, gdy instalujesz aplikację, która ma potencjał, aby być programem uruchamiającym, Android zapyta Cię, czy chcesz użyć innego programu uruchamiającego i czy chcesz ustawić go jako domyślny.

Więc teraz, jeśli naciśniesz przycisk Home lub wyczyścisz wszystkie ostatnie aplikacje, urządzenie automatycznie przekieruje Cię do mojej aplikacji.

Tworzenie aplikacji POS na Androida, której nie można zamknąć

Przycisk Wstecz

Następnie musimy obsłużyć przycisk Wstecz. Aplikacje mobilne zwykle zapewniają na ekranie sposób przechodzenia wstecz przez ekrany, zwłaszcza że wiele urządzeń nie ma dedykowanego klawisza „wstecz”.

Kilka lat temu tak było w przypadku urządzeń Apple z systemem iOS, które miały swój już kultowy wygląd z pojedynczym fizycznym przyciskiem pod ekranem. Jednak w ostatnich latach większość urządzeń z Androidem również zrezygnowała z fizycznych przycisków Home. Najpierw przenieśli się do przycisków ekranowych, a teraz widzimy, że są one wycofywane z telefonów na rzecz gestów, ponieważ producenci telefonów przenoszą się na urządzenia z wszystkimi ekranami z małymi ramkami i podbródkiem.

Oznacza to, że przycisk Wstecz, który domyślnie zapewnia Android, nie jest tak naprawdę potrzebny, a aby uczynić ten przycisk całkowicie bezużytecznym, wystarczy dodać prosty blok kodu w naszej aktywności:

 @Override public void onBackPressed() { } 

Tworzenie aplikacji POS na Androida, której nie można zamknąć

To dość prosty blok kodu: Nasza główna działalność pozwala nam przechwytywać, gdy użytkownik naciśnie przycisk Wstecz. W naszym przypadku, ponieważ nie chcemy, aby użytkownik naciskał ten przycisk zbyt wiele razy w celu wyjścia z aplikacji, możemy po prostu nadpisać domyślną metodę tą, która nic nie robi, mówiąc naszej aplikacji, aby nic nie robiła w przypadku przycisk jest wciśnięty.

W ten sposób niektóre aplikacje proszą o potwierdzenie, zanim przypadkowo wyjdziesz z nich, wracając zbyt wiele razy.

Przycisk Ostatnie

Nadal musimy obsługiwać przycisk Ostatnie, a ten jest najtrudniejszy. Ponadto zdecydowanie nie jest to najlepsza praktyka ani coś, co powinieneś wypchnąć do Sklepu Play, ale działa to w naszej niszowej sprawie.

W ten sam sposób, w jaki główna aktywność pozwala nam wiedzieć, kiedy przycisk Wstecz jest naciśnięty, pozwala nam również wiedzieć, kiedy aplikacja jest wstrzymana. Co to znaczy? Ten kod jest uruchamiany za każdym razem, gdy nasza aplikacja przełącza się z aplikacji pierwszoplanowej na działającą w tle.

Podczas przechwytywania tego zdarzenia otrzymamy identyfikator zadania naszej aktualnej aplikacji i powiemy menedżerowi aktywności, aby przeniósł to zadanie na przód. Aby to zrobić, potrzebujemy jednego specjalnego uprawnienia w tym samym pliku manifestu Androida, który edytowaliśmy wcześniej.

 <manifest xmlns:andro package="com.johnwick"> <uses-permission android:name="android.permission.INTERNET" /> <uses-permission android:name="android.permission.REORDER_TASKS" /> <application android:name=".MainApplication" android:label="@string/app_name" android:icon="@mipmap/ic_launcher" android:roundIcon="@mipmap/ic_launcher_round" android:allowBackup="false" android:theme="@style/AppTheme"> <activity android:name=".MainActivity" android:label="@string/app_name" android:configChanges="keyboard|keyboardHidden|orientation|screenSize|uiMode" android:launchMode="singleTask" android:windowSoftInputMode="adjustResize"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> <category android:name="android.intent.category.HOME" /> <category android:name="android.intent.category.DEFAULT" /> </intent-filter> </activity> <activity android:name="com.facebook.react.devsupport.DevSettingsActivity" /> </application> </manifest>

Umożliwi nam to odczytywanie bieżących zadań i wprowadzanie zmian w tych zadaniach. Ponadto nadal musimy przechwycić moment, w którym nasza aplikacja jest wysyłana w tle. Możemy ponownie przesłonić w naszej aktywności metodę onPause .

Tutaj dostajemy menedżera zadań i zmuszamy go do przeniesienia konkretnego zadania na pierwszy plan. W naszym przypadku tym konkretnym zadaniem jest to, które właśnie zostało wysłane do tła (nasza aplikacja).

 @Override public void onPause() { super.onPause(); ActivityManager activityManager = (ActivityManager) getApplicationContext().getSystemService(Context.ACTIVITY_SERVICE); activityManager.moveTaskToFront(getTaskId(), 0); }

Teraz za każdym razem, gdy będziesz chciał przejść do menu z aktualnościami, aplikacja automatycznie zmieni ostrość. Jasne, czasami możesz trochę migotać, ale nie będziesz w stanie wyjść z tej aplikacji. I jeszcze jedna fajna rzecz – pamiętasz, jak mówiłem, że możesz też wyjść, klikając powiadomienie lub przechodząc bezpośrednio do ustawień przez tacę powiadomień? Cóż, wykonanie tych czynności spowoduje, że aplikacja będzie działać w tle, co uruchomi nasz kod, a następnie użytkownik zostanie wepchnięty z powrotem.

Wszystko to dzieje się tak szybko, że użytkownik nie zauważy, co dzieje się w tle. Kolejną miłą częścią tego podejścia jest to, że szybkie przełączanie są nadal dostępne. Nadal możesz na przykład wybrać sieć Wi-Fi lub wyłączyć dźwięki, ale wszystko, co wymaga przejścia do rzeczywistej aplikacji Ustawienia, jest niedozwolone.

Tworzenie aplikacji POS na Androida, której nie można zamknąć

Rozwiązanie

Nie jestem pewien, czy jest to najlepszy sposób na zrobienie tego, ale mimo wszystko był to naprawdę interesujący proces podczas badania tematu, o którym nawet nie wiedziałem, że jest możliwy. I to działa! Słowo ostrzeżenia: w tym momencie istnieją tylko dwa sposoby wyjścia z aplikacji jako programista - albo ponownie instalujesz system operacyjny, albo zabijasz / odinstalowujesz aplikację przez ADB.

Jeśli w jakiś sposób stracisz połączenie ADB z urządzeniem, nie jestem świadomy łatwego sposobu, który mógłby cię wydostać. Aby tego uniknąć, zbudowałem system PIN.

Przypadki krawędzi

Jest kilka sytuacji, z których musimy się upewnić. Przede wszystkim, co się stanie, jeśli urządzenie się zrestartuje? Nie musi to być ręczne ponowne uruchomienie, może to być również awaria systemu operacyjnego.

Ponieważ wcześniej ustawiliśmy naszą aplikację jako domyślny program uruchamiający, jak tylko system operacyjny uruchomi się z powrotem, powinien on automatycznie uruchomić naszą aplikację. Ale skąd Android wie, że ma ładować ekran główny podczas uruchamiania? Dzieje się tak, ponieważ po prostu ładuje domyślny program uruchamiający. Ponieważ w tym momencie jesteśmy domyślnym programem uruchamiającym, ponowne uruchomienie nie powinno stanowić problemu. I czy Android może w pewnym momencie zabić naszą aplikację? Teoretycznie może to zabić aplikację, jeśli pamięć RAM się zapełni, ale w rzeczywistości jest to prawie niemożliwe. Ponieważ naszej aplikacji nie można zamknąć, nikt nie może otwierać innych aplikacji, więc pamięć RAM nie powinna się zapełniać.

Jedyny sposób, w jaki mogę myśleć o tym, że się zapełni, to sytuacja, w której nasza aplikacja ma ogromny wyciek pamięci, ale w takim przypadku mielibyśmy większe problemy niż trzymanie użytkownika w aplikacji. Mimo to, nawet jeśli Android w jakiś sposób wyzwoli sygnał „zabicia” do naszej aplikacji, za każdym razem, gdy spróbujesz wrócić do domu, system operacyjny spróbuje ponownie uruchomić naszą aplikację, ponieważ jest to domyślny program uruchamiający, w ten sposób blokując użytkownika.

Budowanie tylnych drzwi

Jako szybkie wyjaśnienie, w ustawieniach aplikacji znalazło się miejsce, w którym można było wpisać PIN, aby odblokować aplikację. Jeśli PIN jest poprawny, wyłączy ograniczenia ustawione przez nasze metody onPause i onBackPressed, wykonując prostą instrukcję warunkową. Stamtąd użytkownik będzie mógł wejść do ustawień za pomocą menu szybkiego przełączania. Następnie zawsze możesz ustawić domyślny program uruchamiający z powrotem na standardowy, co całkowicie pozbawi Cię aplikacji. Istnieje wiele sposobów, w jakie można poradzić sobie z tą częścią, ale dobrze jest mieć mechanizm wyłączający te same ograniczenia, które wprowadziłeś. Może mógłbyś wykonać uwierzytelnianie odciskiem palca, aby odblokować. Możliwości są prawie nieograniczone.

Tworzenie aplikacji Android POS, której nie można zamknąć

Zawijanie

W końcu zostałem z aplikacją, której nikt nie mógł zamknąć ani zabić. Nawet ponowne uruchomienie urządzenia nie pomogłoby, ponieważ włączyłoby się ono bezpośrednio do domyślnego programu uruchamiającego, którym obecnie jest nasza aplikacja. Okazało się to przydatne w naszym projekcie, a satysfakcja z wypróbowania czegoś tak zwariowanego i nietypowego była naprawdę świetna i bardzo motywująca.

Istnieje wiele urządzeń i przypadków użycia, w których Android ułatwił życie programistom. Obecnie pisanie aplikacji na Androida jest znacznie łatwiejsze niż używanie wielu różnych języków i narzędzi specyficznych dla platformy. Pomyśl o urządzeniach IoT, aplikacjach kioskowych, systemach punktów sprzedaży, bramkach nawigacyjnych i płatniczych dla taksówek i wielu innych.

Są to przypadki użycia, w których Android ułatwił tworzenie aplikacji, ale także niszowe przypadki użycia, w których chcesz ograniczyć dostęp w sposób podobny do tego, który pokazaliśmy w tym artykule.