nedeľa 25. decembra 2016

Android developer options

V oblasti Android developu sa pohybujem už nejaký čas. Mnohokrát som sa čudoval, aké rôzne možnosti pre vývojara ponúka Developer options, Mnohé možnosti sú úzko špecializované a ani ja nepoužívam všetky. V tomto článku si dám za úlohu vysvetliť tieto nastavenia. Niektoré nastavenia sú špecifické pre jednotlivé verzie a s každou novou verziou môže pribudnúť nové nastavenie alebo sa odstrániť staré nepotrebné.

Povolenie vývojarských nastavení

Ako prvé je nutné povoliť nastavenia, začínajúci developeri budú mať možno na začiatku problém, keďže nastavenia sú defaultne skryté v menu. Skúsenejší už vedia, čo treba spraviť. Aby sme si vedeli ich zobraziť, treba postupovať nasledujúco:
1) otvoriť nastavenia telefónu (Settings)
2) ísť do sekcie "Informácie o telefónne" (About device)
3) rýchlo treba tapnúť na položku "Číslo zostavy" (Build number)

Po týchto krokoch by sa malo zobraziť krátke upozornenie, že ste sa stali developerom na mobilnom zariadení. Stačí vyjsť zo sekcie o úroveň vyššie a už bude možné nájsť Možnosti pre vývojárov (Developer Options).

Developer Options


Vytvoriť hlásenie o chybách (Make bug report / Take bug report) - zozbiera všetky log súbory v zariadení, pekne ich zabalí a pripraví na odoslanie. Odoslať si to môžeme buď na email, do cloudového uložiska, alebo inde. Chvíľu potrvá, než sa zozbierajú všetky údaje v zariadení a pripravia, trvá to od cca. 1 minúty do 2 minút. Keď Android zariadenie pripraví report, upozorní nás cez notifikáciu.

Výber runtime prostredia (Select runtime) - v tomto prípade máme možnosť výberu behového prostredia pre aplikácie. Buď to bude dalvik virtual machine, čo je najpoužívanejšie, alebo to bude android runtime (ART). Táto voľba je zatiaľ experimentálna a je dostupná hlavne na android verziách 4.4. Vo vyšších verziách bola znova odstránená. Google uviedlo že ART by malo byť náhradou za Dalvik prostredie.

Heslo záloh v počítači (Desktop backup password) - pomocu ADB je možné zálohovať a obnovovať súbory ako aplikácie, dáta súvisiace s aplikáciou do počítača a z počítača. Touto možnosťou je možné ochrániť zálohy heslom. Bez hesla nebude možné obnoviť zálohy

Nevypínať obrazovku (Stay awake) - táto možnosť zapríčiní to, že mobil nebude vypínať obrazovku počas nabíjania (či už cez USB port na počítači alebo elektrickú zásuvku je jedno, proste bude zapnutá). Toto je skvelé pre vývojara, ale zlé pre užívateľa na vypálenie si obrazu na obrazovku

Povoliť sledovanie Bluetooth HCI (Enable Bluetooth HCI snoop log) - pre potreby analýzy je občas nutné zachytávať bluetooth HCI(host controller interface) pakety. Povolením tejto možnosti tieto pakety uloží do súboru (/sdcard/btsnoop_hci.log). Takýto súbor je možné neskôr analyzovať pomocou programu ako je wireshark.

Chrániť kartu SD (Protect SD card) - povolením tejto možnosti vynutíme ochranu, že aplikácie nebudú môcť čítať externe úložisko pokiaľ nebudú mať permission READ_EXTERNAL_STORAGE v manifeste. Táto voľba platí pre staršie zariadenia ako Android 4.3 až Android 4.1. Tie aplikácie, ktoré proste nemajú túto permission proste havarujú na výnimke SecurityException.

Štatistiky procesov (Process Stats) - cez túto položku sa dotaneme k ďaľšej sekcii developer options, konkrétne štatistiky procesov bežiacích v zariadení. Po tapnutí na určitý proces sa zobrazí obrazovka, kde vidieť podrobné štatistiky súvisiace s procesom. Je možné sledovať ako užívateľské procesy tak aj systémove.

Ladenie USB (USB debugging) - toto treba mať zapnuté počas vývoja. Umožňuje komunikáciu medzi zariadením a počítačom cez USB port. Toto je najdôležitejšia položka pre vývojára. Okrem komunikácie je aj možné posielať ADB príkazy do zariadenia.

Odvolanie autorizácií na ladenie USB (Revoke USB debugging authorizations) -  po prvý krát, keď pripojíme zariadenie k počítaču a je povolené USB ladenie, tak si vypýta najprv, aby sme autorizovali počítač na obrazovke zariadenia (povolili počítač v zariadení). Autorizovaním počítača si v zariadení vytvorí kľúčový pár alebo otlačok počítača a budeme môcť používať USB ladenie. Ak chceme znova aby sa počítače autorizovali v zariadení, tak ako prvý krát, treba  použiť túto možnosť.

Skratka hlásenia o chybe (Include bug reports in power menu / Bug report shortcut) -  vloží možnosť zozbieraťhlásenie o chybách a odoslať ich už v cez ponuku vypnutia zariadenia (teda cez tlačítko power buttonu)

Povoliť simulované polohy (Allow moc locations) - pomocou tohto je možné manuálne nastaviť lokalizačné informácie. Na nastavenie falošnej lokalizácie je potrebné aplikáciu. Ale pred použitím aplikácie je nutné túto položku povoliť.

Vybrať aplikáciu na ladenie (Select app to be debugged / Select debug app) - máme možnosť zvoliť aplikáciu na ladenie a má to dva efekty, a to zabraňuje to vo vyvolaní chyby, ak sa zdržíte dlho v breakpointe počas ladenia a povolí ďalšiu ponuku Čakať na ladiaci nástroj.

Čakať na ladiaci nástroj (Wait for debugger) - Táto položka je zablokovaná do doby, než si zvolíte aplikáciu na ladenie pomocou hore uvedeného nastavenia. Pozdružuje štart zvolenej aplikácie do vtedy, než sa k nej pripojí ladiaci nástroj (debugger).

Overovať aplikácie z USB (Verify app over USB / Verify apps via USB) - umožňuje overovať aplikácie inštalované cez USB pomocu Google serverov. To znamená, že sa overuje všetok kód, ktorý sa posiela cez USB. Android posiela všetko na Google servere a overuje sa, či aplikácia neobsahuje nejaký známy malware.

Certifikácia bezdrôtového displeja (Wireless display certification / Authorize wireless display devices) - táto položka je dobrá pre tých, čo vlastnia televízor s technológiou Miracast-ready. V takom prípade si môžu premietať obsah displeja zariadenia na televíziu. Povolenie takéhoto premietanie je nutné povoliť túto možnosť.

Povoliť prihlasovanie WLAN Verbose (Enable Wi-Fi Verbose Logging) - táto možnosť povolí zobraziť informácie o wi-fi sieti vo wifi screen pickery a dovolí vytvoriť wpa_supplicant log, kde bude ukladať informácie o wifi.

Agresivne odovzdávať WLAN na mobilnú sieť (Aggressive Wi-Fi to Cellular handover) - ak je Wi-Fi signál slabý, tak táto možnosť dovolí rýchlo prepnúť na mobilné dáta.


Vždy povoliť funkciu WLAN Roam Scans (Always allow Wi-Fi Roam Scans) - umožňuje migrovať na silnejšiu Wi-Fi sieť, ak sa nachádza v dosahu. To znamená, že ak som pripojený na Wi-Fi so slabším signálom a v dosahu sa nachádza sieť so silnejším dosahom, Android zariadenie by malo vedieť sa prepnúť na túto silnejšiu sieť.

Veľkosť vyrovnávacej pamäte denníka (Logger buffer sizes) - dovoluje zmeniť veľkosť bufferu pre logy. Možné veľkosti sú 64K, 256K, 1M, 4M a 16M.

Zobrazovať dotyky (Show touches) - zobrazí vizualizáciu, keď zariadenie zaregistruje dotyk na obrazovke v bode dotyku.

Umiestnenie ukazovateľa (Pointer location) - táto možnosť umiestní na vrchnú časť obrazovky lištu, kde bude zobrazovať súradnice dotyku a zanechá čiaru na mieste, ako išiel dotyk po obrazovke. Jednotlivé údaje, sú následujúce: P - počet dotykov, čo zariadenie dokázalo zaregistrovať, a maximálny počet z predošlého dotyku, dX alebo X, dY alebo Y - sú súradnice dotyku v osi X a Y a rozdiel dX a dY od začatia dotyku a jeho ukončenia, ak je viacej  dotykov, ukazuje súradnice len prvého, Xv a Yv - sú zase rýchlostné vektory, ktoré zobrazujú len rozdiel v smere X a Y, Prs - zobrazujú tlak vyvíjaní na displej, je to len orientačná hodnota, keďže kapacitné displeje nedokážu snímať tlak a nakoniec je tu Size - veľkosť bodu dotyku.

Zobrazovať obnovenia obsahu (Show surface updates) - pri zmene obsahu obrazovky obrazovka preblikne. Neodporúčam pre epileptikov.

Zobraziť ohraničenia (Show layout bounds) - zobrazí ohraničenia všetkých prvkov na obrazovke.

Rozloženie sprava doľava (Force RTL Layout direction) - vypnú orientáciu obrazovky z prava do ľava.

Mierka animácie okna (Window animation scale) - umožňuje zmeniť rýchlosť animácií okien. Čím nižšie číslo, tým rýchlejšia animácia.

Mierka animácie premeny (Transition animation scale) - ako v predchádzajúcom mení rýchlosť animácie.

Mierka dĺžky animácie (Animator duration scale) - mení samotnú rýchloť zvyšných animácií.

Simulovať sekundárne displeje (Simulate secondary displays) - umožňuje simulovať iné rozlíšenia obrazoviek. Osobne mi to, ale nefungovalo najlepšie.

Vykreslovať pomocou GPU (Force GPU rendering) - núti vykreslovať 2D grafiku pomocou GPU v aplikáciach.

Zobraziť obnovenia s GPU (Show GPU view updates) - všetky view-y, ktoré vykresľuje GPU, budú mať červený rámček okolo seba po zmene obsahu.

Zobraziť akutalizácie HW vrstiev (Show hardware layers updates) - prebliknu prvky na zeleno, keď budú hardwerovo aktualizované.

Ladenie prekresľovanie GPU (Debug GPU overdraw) - zobrazí pomocou farieb to, ako často sa musia prvky na obrazovke prekresľovať. Použité sú tieto farby: modrá - ak sa iba raz prekreslí prvok, zelená - ak sa prekreslí dvakrát prvok, ružová - ak sa prvok prekreslí trikrát a červená ak sa prvok prekreslí štyrikrát a viac krát. (Viac info viď. Debug GPU Overdraw Walkthrough. )

Ladenie operácií neobdĺžnikových klipov (Debug non- rectangular clip operations) -

Vynútiť 4x MSAA (Force 4x MSAA) - vynúti multi vzorkovú anti-aliasing technológiu. Krajšie vykresľovanie, ale na úkor výkonu.

Zakázať hardvérové prekrytia (Disable HW overlays) - skracuje čas spracovania aplikácií, ktoré niečo zobrazujú na displeji. Bez toho aplikácia používa zdieľanú video pamäť a musí stále kontrolovať kolízie.

Simulácia farebného priestoru (Simulate color space) - pomáha vývojárom vidieť, ako vyzerá aplikácia pre farboslepých užívateľov.

Použiť AwesomePlayer (zastarené)(Use AwesomePlayer (deprecated)) - rozdiel medzi NuPlayerom a AwesomePlayerom je hlavne v načítaní online videa. NuPlayer načítava online videa rýchlejšie. Keďže vo verzii Android 5 je toto nová verzia a nie je ešte vyladená, tak sa dá prepnúť na staršiu verziu, ale touto možnosťou. V neskorších verziách môže táto voľba úplne zmiznúť.

Vypnutie smerovania zvuku do USB (Disable USB audio routing) - nebude posielať audio výstup na USB port, ak je pripojené audio zariadenie v USB porte.

Prísny režim bol povolený (Strict mode enabled) - pri povolenej možnosti bude obrazovka blikať, ak aplikácia bude vykonávať dlhotrvajúcu operáciu na hlavnom vlákne

Zobraziť využitie CPU (Show CPU usage) - v pravom hornom rohu obrazovky bude zobrazovať informácie o využití CPU

Profil vykreslovania GPU (Profile GPU rendering) - spraví grafickú vizualízáciu vykresľovania GPU v ľavom dolnom rohu, alebo môžeme zapísať do súboru

Trasovanie OpenGL (Enable OpenGL traces) - povolí sledovanie OpenGL chýb a zapíše ich do log súboru

Neuchovávať aktivity (Don't keep activities) - ukončí všetky aktivity po odídení z hlavného view. Predlžuje výdrž batérie, ale zato dlhšie sa zapína aplikácia.

Limit procesov na pozadí (Background process limit) - môžeme ovplyvniť počet súčasne bežiacich procesov na pozadí.

Zobrazovať všetky ANR (Show all ANRs) - zobrazí dialóg Aplikácia neraguje pre všetky aplikácie a aj tie, ktoré bežia na pozadí.


Snažil som sa zhrnúť všetky možnosti, ktoré sa nachádzali v Developer options naprieč viacerými verziami Androidu. Nedostal som sa akurát k verzii Android 6 a 7, keďže ešte nevlastním žiadne zariadenie, ale to sa zmení čoskoro. Ak je niečo, čo som nespomenul k nastaveniu alebo vynechal nejaké nastavenie, budem rád za pripomienky. Jednotlivé nastavenia sú v samotnej obrazovke oddelené cez hlavičku ešte do kategórií ako Debugging, Input, Drawing, Hardware-accelerated rendering, Monitoring, Apps. Doplním, že systém Android je tak populárny, že ho viacerí výrobcovia HW používajú vo svojich produktoch v rôznych variantách, spomeniem Amazon a ich systém Fire OS. Ten má veľa spoločného s Android a aj Developer Options nastavenia. Takže čo platí pre Android, platí aj pre Fire OS. Pri písaní článku som vychádzal z dokumentácie, osobných skúseností a z týchto článkov:

All about your phone's developer options

Android Developer Options: enable, disable and use Read more

V ďalšom článku pridám Developer Options pre Android Wear Motorola Moto 360.

utorok 27. septembra 2016

Android - Product Flavors

Od nástupu Android Studia bol predstavený aj nový buildovací systém Gradle. Tento systém je open source, flexibilný, postavený na groovy jazyku, v mnohom uľahčuje prácu vývojárovi. 
Ako android vývojár som sa stretol s tým, že aplikácia mala byť publikovaná na dva odlišné obchody s použitím mierne odlišných funkcií špecifických pre daný obchod. Typické funkcie špecifické pre dané obchody bývajú nákupy v aplikácii alebo prostredníctvom reklamy. Tých obchodov, kde môžeme publikovať aplikácie je viacero, spomeniem ich zopár: 
  • Google play - najznámejší, keďže sa jedná o Android systém. 
  • Amazon App Store - Amazon vytvoril vlastnú variantu Android Systému pod názvom Fire OS. 
  • Samsung Galaxy Apps - obchod od Samsungu, čo viac k tomu dodať. 
S publikovaným aplikácie na dva alebo viacej obchodov nie je problém. Problém nastáva pri tom, keby sme chceli použiť v aplikácii špecifické funkcie pre daný store ako nákupy v aplikácií. Napr. Amazon nepodporuje Google Play Services v ich systéme Fire OS (podporuje In-app Purchases), čo znamená, že nevieme robiť nákupy v Google obchode (ten má zase In-app Billing). Tento problém sa dá riešiť viacerými spôsobmi. Jeden spôsob je ten, že budem mať dva odlišné projekty v Android Studiu jednej aplikácie, väčšinu kódu budú mať oba projekty identickú, budú sa odlišovať len v implementáciach nákupov. Ak nájdem chybu v kóde, ktorý je rovnaký pre oba projekty, tak to znamená aj dve rovnaké opravy kódu v dvoch projektoch. Tiež prepínanie sa medzi projektami počas vývoja nie je najrýchlejšie.

Druhý spôsob bude taký, že budem mať jeden projekt a nakonfigurujem v buildovacom systéme gradle product flavors. Tento spôsob je elegantnejší, jeden kód, ktorý je rovnaký(zdielaný) pre obe verzie aplikácie, bude len raz a pridáme implementácie funkcií pre konkrétne obchody oddelene od zdieľaného kódu. Bližšie o build flavors sa dá dočítať na vývojarských stránkach Android: Product Flavors and Variants. Vysvetlím použitie druhého spôsobu na príklade. Majme projekt, ktorý má následujúcu štruktúru, viď. následujúci obrázok:

Android Studio - štruktúra projektu

Začneme tým že pridáme niekoľko riadkov do súboru build.gradle, ktorý sa nachádza v aplikačnom module (app).

productFlavors{
         google{
            versionCode 1
            versionName '1.1'
         }
          amazon{
            versionCode 2
            versionName '1.2'
          }
}


Po vložení hore uvedených riadkov a zosynchronizovaní build.gradle nám vytvorí niekoľko variant a to amazonDebug, amazonRelease, googleDebug, googleRelease, ako vidieť na obrázku nižšie.

Android Studio - Build Variants
Pred synchronizáciuo sme mali len dve build varianty a to Debug a Release. Keby sme pridali ďalšiu product flavors, tak Android Studio nám vytvorí 6 build varianta, ktorá bude mať vypadať následujúco:
<meno>Debug 
<meno>Release

V Android Studiu sa vieme teraz prepínať medzi build variantami. Momentálne máme len build varianty vytvorené, keď chceme ešte doplniť kódy špecifické pre každú variantu potrebujeme vytvoriť adresárovú štrukúru zdrojových kódov v Android Studiu. Štruktúra adresárov teraz bude vypadať následujúco:

Android Studio - Štruktúra projektov po pridaní product flavors

Túto štruktúro nám Android Studiu nevytvorí, tú si musíme vytvoriť sami. Štruktúra pre zdrojové kódy je podľa následujúceho vzorca:

src\<productFlavors-name>\java\<package>\SpecifickaImplementaciaPodlaFlavoru.java

Pre Resources je štruktúra jednoduchšia:

src\res\layout\LayoutSpecifickyPreProductFlavor.xml

V Adresáry src\main sú umiestnené všetky zdrojové kódy, ktoré nie sú špecifické pre určitú product flavor. Ako príkladom ukážem aplikáciu, ktorá bude robiť dve veci, záleži od jej product flavor. Amazon flavor bude robiť rozdiel dvoch čísel, bude mať aj rozdielne pozadie activity oproti google flavor. Zatiaľ čo google flavor bude dve čísla spočítavať. V adresári src\main je trieda Calculating.java, ktorá je spoločná pre obe flavors, jej zdrojovy kód je následujúci:

package test.vuforia.goodrequest.com.gradletest;

public class Calculating {

     public static int Add(int number1, int number2) {
         return number1 + number2;
     }
     public static int Substraction(int number1, int number2) {
         return number1 - number2;
     }
}

Layout pre google flavor je následujúci:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/activity_main"
android:layout_width="match_parent"
android:layout_height="match_parent" 
android:orientation="vertical" 
android:background="@color/black">

<TextView android:layout_width="wrap_content" 
android:layout_height="wrap_content" 
android:text="Cislo 1" 
android:textColor="@color/white"/> 

<EditText android:id="@+id/number1"
 android:layout_width="match_parent"
 android:layout_height="wrap_content" 
 android:background="@color/white" 
 android:inputType="number"/>

<TextView android:layout_width="wrap_content"
 android:layout_height="wrap_content"
 android:textColor="@color/white" 
 android:text="Cislo 2"/>

 <EditText android:id="@+id/number2" 
 android:layout_width="match_parent" 
 android:layout_height="wrap_content"
 android:background="@color/white"
 android:inputType="number"/>

 <Button android:id="@+id/sucet"
 android:layout_height="wrap_content"
 android:layout_width="wrap_content" 
 android:text="Sucet" /> 

<TextView android:id="@+id/vysledok"
 android:layout_width="wrap_content"
 android:layout_height="wrap_content"
 android:textColor="@color/white"
 android:textStyle="bold"/>

</LinearLayout>

Layout pre Amazon flavor je rovnaká, rozdiel je len v použitých farbách pozadia LinearLayoutu a Button má iný textový popisok a id. Pod popiskom myslím android:text attribut. Trieda MainActivity.java má následujúci kód:

package test.vuforia.goodrequest.com.gradletest;

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;

public class MainActivity extends AppCompatActivity {
private Button sucet;
private EditText cislo1, cislo2;
private TextView vysledok;
@Override
protected void onCreate(Bundle savedInstanceState) {
      super.onCreate(savedInstanceState);
      setContentView(R.layout.activity_main);
      cislo1 = (EditText) findViewById(R.id.number1);
      cislo2 = (EditText) findViewById(R.id.number2);
      vysledok = (TextView) findViewById(R.id.vysledok);
      sucet = (Button) findViewById(R.id.sucet);
      sucet.setOnClickListener(new View.OnClickListener() {
          @Override
          public void onClick(View v) {
               if ((cislo1.getText().length() != 0) && (cislo2.getText().length() != 0)) {
                     int scitanec1 = Integer.valueOf(cislo1.getText().toString());
                     int scitanec2 = Integer.valueOf(cislo2.getText().toString());
                     vysledok.setText("" + Calculating.Add(scitanec1, scitanec2));
                }
           }
      });
}
}


V podstate aj amazon flavor je velmi podobný, odlišuje sa len v implementácii OnClick listeneru buttonu: 

rozdiel.setOnClickListener(new View.OnClickListener() {
     @Override 
      public void onClick(View v) {
            if ((cislo1.getText().length() != 0) && (cislo2.getText().length() !=0)){
                  int mensenec = Integer.valueOf(cislo1.getText().toString());
                  int mensitel = Integer.valueOf(cislo2.getText().toString());
                  vysledok.setText("" + Calculating.Substraction(mensenec,mensitel));
           }
     }
});

Takýmto flexibilným spôsobom vieme vytvoriť viacero verzií jednej aplikácie rozlišujúcej sa vo vzhľade alebo vo funkcii. Nepotrebujeme k tomu žiadne dva projekty, stačí nám jeden. Pre úplnosť uvádzam výpis build.gradle súboru nachádzajúceho sa v app module: 

apply plugin: 'com.android.application'

android {
    compileSdkVersion 24
    buildToolsVersion "24.0.2"
    defaultConfig {
        applicationId "test.vuforia.goodrequest.com.gradletest"
        minSdkVersion 18
        targetSdkVersion 24
        versionCode 1
        versionName "1.0"
        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }

    productFlavors{
        google{
            versionCode 1
            versionName '1.1'
        }
        amazon{
            versionCode 2
            versionName '1.2'
        }
    }
}

dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar'])
    compile 'com.android.support:appcompat-v7:24.2.1'
}

Text je publikovaný aj na blogu som písal aj pre spoločnosť GoodRequest s.r.o., kde som v dobe písania pôsobil.