Jak jsme ve Slevomatu vytvářeli první aplikaci pro Android TV

S vydáním Android 5.0 uvedl Google i platformu Android TV, která je dalším pokusem o proniknutí do televizí. Asi nám dáte za pravdu, že je v porovnání s nevydařeným pokusem jménem Google TV mnohem úspěšnější.
Google si uvědomil, že uživatelské rozhraní a aplikace pro TV je potřeba navrhnout tak, aby se daly snadno konzumovat i z gauče obývacího pokoje. Již nyní se běžně prodávají televize značky Philips a Sony s Android TV. Další možností je používat Android TV skrz set-top box nebo konzoli, jako je např. Nvidia Shield TV, která přišla na český trh 20. června 2016. Platforma je konečně mezi lidmi a prodává se.
Proč vyvíjet pro Android TV
- Protože je to Android. Pokud tedy máte zkušenosti s vývojem pro Android, prakticky jste vyhráli a všechny Android SDK API, které běžně znáte a používáte, jsou k dispozici.
- Pokud platí bod 1, nebude vás to stát mnoho peněz.
- Můžete recyklovat spoustu kódu, jako je datový model, komunikace s API apod.
- Vaše aplikace bude dostupná na dalších zařízeních.
- Pro telefony vyvíjí hodně lidí, ale pro TV málokdo.
Specifika vývoje na Android TV
I přes to, že vývoj pro Android TV je v zásadě vývoj pro Android, má svoje specifika vycházející z platformy, a ty je třeba respektovat:
- technické předpoklady
- nemáte k dispozici touchscreen, gps, senzory, kameru, akcelerometr a řadu dalších hw vlastností – zamyslete se, pokud vaše aplikace tyto využívá
- na druhou stranu se nemusíte bát, že se zařízení vybije
- ovládání
- otestujte, že vaše aplikace je ovladatelná ovladačem na Android TV. Pokud využíváte leanback library, popř. standardní Android widgety, nemáte problém – pokud využíváte custom views, ujistěte se, že indikujete focus stav, tak aby uživatel věděl, který prvek je zrovna zvolený
- pokud je vaše aplikace hra, adaptujte ovládání na Gamepad, popř. ovladač, je-li to možné
- design
- uvědomte si, z jaké vzdálenosti lidé sledují televizi a ujistěte se, že vaše UI je z takové vzdálenosti čitelné a ovladatelné
- vyvarujte se přehršle informací a textu – nikdo si nechce číst na televizi
- většinu věcí řeší leanback library, viz níže
Jak jsme si s tím poradili
Protože ve Slevomatu máme appku už nějaký čas, a s tím související API, nebylo daleko od nápadu zúčastnit se hackathonu, jehož výsledkem byl funkční prototyp pro Android TV. Ten jsme nakonec interně dodělali a vydali jako součást klientské aplikace:
https://play.google.com/store/apps/details?id=cz.slevomat
Aplikaci na TV lze snadno nainstalovat skrz Google Play vyhledáním aplikace “Slevomat”.
Leanback library
Vaším nejlepším přítelem při vývoji je android.support.v17.leanback library, která obsahuje řadu UI prvků, navržených přímo pro použití na Android TV.
Konkrétně v naší aplikaci využíváme:
BrowseFragment
BrowseFragment se používá jako rozcestník obsahu. V našem případě jsme jej využili tak, že vlevo máme seznam kategorií a napravo řádky s jednotlivými nabídkami.
DetailsFragment
Dále pak DetailsFragment, který, jak název napovídá, slouží k zobrazení detailu. V našem případě je to obrázek, seznam akcí, které můžete s nabídkou udělat – přehrát video, přidat do uložených, do košíku a zobrazit úplný popis.
A dále dodatečné obrázky a související nabídky.
SearchFragment
Nezapomněli jsme ani na SearchFragment, který slouží k zobrazení výsledků vyhledávání.
Tip: Protože zařízení s Android TV mají tlačítko na ovladači sloužící k nastartování vyhledávání, defaultně se spustí systémové vyhledávání. Pokud však chcete, aby uživatel zůstal v kontextu aplikace, je třeba přepsat metodu Activity onSearchRequested.
Doporučení obsahu
Další možností je generování doporučení obsahu z vnitřku vaší aplikace, pokud tedy máte nějaký content, můžete jej vysadit až na homescreenu televize a inspirovat tak uživatele i bez otevření vaší aplikace.
Řádka „doporučení” je z pohledu Android SDK brána jako notifikace (skrz Builder nastavíte BigPictureStyle a setLocalOnly), které si generujete pomocí vlastní standardní IntentService a spouštíte ji, jak je potřeba, obvykle pomocí AlarmManager v intervalech, takže je potřeba ošetřit, aby se toto po bootu nastavilo pomocí BroadcastReceiver na RECEIVE_BOOT_COMPLETED event.
Login
Výzvou, se kterou jsme se u TV potýkali, byla autorizace uživatele. Museli jsme mu totiž umožnit vložit nabídku (zážitek) do košíku, popř. do uložených nabídek.
Benefit je pro nás jasný – získáme buď nové zákazníky, nebo naše uživatele upozorňujeme e-mailem v okamžiku, kdy jejich uložená nabídka končí nebo kdy je zboží v košíku příliš dlouho.
Prvním nápadem, jak to realizovat, bylo využít Nearby Messages API pro výměnu klíče. Bohužel jsme však zjistili, že toto API, ač je součástí Google Play Services, na Android TV není přítomno (nezinicializuje se).
Proto jsme se nakonec rozhodli pro autorizaci skrz obrazovku: opsáním kódu, případně naskenováním QR kódu:
Sekvence jednotlivých kroků poté vypadá následovně:
- Uživatel se pokusí o autorizovanou akci, nebo vyvolá login ručně.
- Televize pošle serveru invite request.
- Server vrátí televizi invite kód.
- Televize ukáže invite kód uživateli.
- Uživatel skrz své zařízení vepíše kód na web (kde se případně přihlásí či registruje jako nový uživatel). A tohle je asi ten nejzapeklitější moment z hlediska uživatele (musí opsat kód – proto tam máme i QR kód).
- Server autorizuje televizi a začne s televizí komunikovat jako s přihlášeným uživatelem.
Youtube
U implementace YouTube API pro Android bohužel nemůžete počítat s ničím jiným, než že funguje třída YouTubeIntents. Spouštět videa tedy můžete takto:
YouTubeIntents.createPlayVideoIntentWithOptions(context, youtubeId, true, true);
Pro zobrazení náhledu videa lze využít veřejně známého vzoru:
http://img.youtube.com/vi/<youtubeId>/0.jpg
Google Play publikace
Pro publikaci Android TV aplikací skrz Google Play je třeba mít na mysli dvě věci:
- “I’m happy to hear you’re interested in having your app featured on Google Play as the Android TV section is a featured list.” – Google Play Support
Google Play pro Android TV je pouze featured list – tedy je to pouze výběr aplikací včetně obsahu kategorií. Nemáte tedy zaručeno, že se uživatel k vaší aplikaci nějak “dokliká” – jediné, co je zaručeno, že vás najde skrz hledání. Nelze tedy spoléhat na organické instalace. - “Thanks for submitting your app for Android TV. This is a notification that your application…is not being distributed on the Play Store for Android TV.” – Google Play Support
Aplikace pro Android TV podléhají schválení tak, aby byly k dispozici skrze hledání a instalovatelné skrze Google Play. Aplikace musí splnit vývoj TV App Quality.
ad 2) pokud je TV app součástí běžné mobilní aplikace, pak je odmítnutí často způsobeno tím, že aplikace nespecifikuje některé hardware požadavky v AndroidManifest.xml jako nepovinné:
<uses-feature android:name="android.hardware.touchscreen" android:required="false"/>
<uses-feature android:name="android.hardware.faketouch" android:required="false"/>
<uses-feature android:name="android.hardware.telephony" android:required="false"/>
<uses-feature android:name="android.hardware.camera" android:required="false"/>
<uses-feature android:name="android.hardware.nfc" android:required="false"/>
<uses-feature android:name="android.hardware.location.gps" android:required="false"/>
<uses-feature android:name="android.hardware.microphone" android:required="false"/>
<uses-feature android:name="android.hardware.sensor" android:required="false"/>
Zejména je třeba dát pozor na hardware požadavky vyplývající z permissions (např. CAMERA_PERMISSION implikuje android.hardware.camera, apod.)
Tyto požadavky jsou vcelku pochopitelné, nicméně některá odmítnutí mohou být matoucí:
REASON FOR EXCLUSION:
Your app does not contain a full-size app banner.
We are targeting 1080P, which we consider xhdpi. Apps should include the banner in the xhdpi (320 dpi) drawables folder with a size of (320px × 180px). Since no text will appear next to the banner in the launcher, text should be included in the image if necessary to disambiguate the application, and these (text-containing) banners should be localized.
V tomto případě jsme měli všechna loga dle požadavků připravena. Nicméně, jelikož je máme v aplikaci Google Play Services, tak nám přinesly mj. i více než 100 dalších lokalizací, a tím pádem naše aplikace byla odmítnuta, že pro tyto lokalizace nemáme logo. To vše jen dependencí na Google Play Services. V tomto případě je nezbytné do build.gradle uvést
defaultConfig {
// Define languages that your app supports.
resConfigs "en", "de", "fr", "es"
}
a explicitně tak omezit podporované lokalizace, což je obecně dobré pravidlo, nicméně pro Android TV nezbytné.
Závěr
I přes drobné specifika a obtíže je Android TV stále Android a pokud máte Android zvládnutý, tak pro vás vývoj pro Android TV nebude nijak obtížný. Je to snadný a zajímavý způsob, jak dostat svůj obsah k uživatelům.
Dokumentace
- Building Apps for TV – https://developer.android.com/training/tv/index.html
- Bring your Android app to Android TV in minutes – https://youtu.be/qv-e1sV3gos
- An in-depth look at the Leanback Library – https://youtu.be/QFHIfQy8_Wc
Jak přesně funguje ten krok 6 v loginu? Je to push notifikace?
Ahoj Michale, zvažovali jsme to, ale přišlo nám to jako overkill, udělali jsme polling v nějakém krátkém intervalu to checkuje status přišlo nám to, že to funguje dobře bez nutnosti další infrastruktury na back-endu a baterku to nevybíjí. Samozřejmě push nebo socket by byli víc cool.
nope, je to polling po 3-5 sec (tuším) po max. dobu platnosti invitation tokenu (15min), zvažovali jsme push nebo sockety, ale přišlo nám to jako overkill, baterku to nevybíjí, při našem testování se to ukázalo jako good enough UX
Dík za odpověď, zarazil mě směr té šipky.