V průběhu přípravy recenze na XE5 jsem narazil na nepříjemnou chybu IDE, která mě připravila nepříjemnou hodinku. Měl jsem odladěnou appku a přišel čas, abych jí zapublikoval na Google Play. Vše se podařilo, ale po stažení appky přes Play jsem zjistil že nemá práva přístupu na Internet (tedy lépe řečeno na TCP/IP). Jo aháá, nejsou nastavena práva pro aplikaci… jenže jsou. Dokonce právo Internet je jedno ze standardně povolených práv, když založíte prázdný projekt.
Takže co jsem zjistil. Práva (a ostatní důležité informace) pro sestavování APK jsou definovány v manifestu - soubor AndroidManifest.xml ve složce Android-Debug/Release v projektu. Pokud je nastaveno v Target Platforms-Android-Configuration-Debug (pozor, neplést s Build Configuration-Debug/Release), vypadá část která v manifestu definuje soubor přistupových práv takhle:
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.CALL_PHONE" />
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.READ_CALENDAR" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission android:name="android.permission.WRITE_CALENDAR" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
Appka funguje normálne. Pokud ale přepnete na Application Store a provedete znovu Build, vypadá stejná část takhle:
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.CALL_PHONE" />
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.READ_CALENDAR" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission android:name="android.permission.WRITE_CALENDAR" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
Že chybí INTERNET? Ano chybí a appka opravdu nemá přístup na Internet (tedy lépe řečeno obecně na síť). Teenager by na mém místě pravděpodobně prohlásil WTF! Já jsem se spokojil s konstatováním že je chyba v IDE a začal hledat nějaké řešení (a ano, zkontroloval jsem, že v nastavení projektu v IDE jsou opravdu pro všechny varianty práva nastavená stejně). Modifikovat přímo soubor AndroidManifest.xml nemá význam, sestavuje se vždy znova. Naštěstí mě Radek Červinka se kterým jsem to konzultoval navedl na template manifestu. Je to soubor AndroidManifestTemplate.xml v hlavní složce projektu. Část která nás zajímá vypadá takhle:
<!-- This is the platform API where NativeActivity was introduced. -->
<uses-sdk android:minSdkVersion="%minSdkVersion%" />
<%uses-permission%>
<application android:persistent="%persistent%"
android:restoreAnyVersion="%restoreAnyVersion%"
Vyznačený metatag <%uses-permission%> se zcela zřejmě nahrazuje seznamem přístupových práv. Takže jsem ho upravil takhle:
<!-- This is the platform API where NativeActivity was introduced. -->
<uses-sdk android:minSdkVersion="%minSdkVersion%" />
<uses-permission android:name="android.permission.INTERNET" />
<%uses-permission%>
<application android:persistent="%persistent%"
android:restoreAnyVersion="%restoreAnyVersion%"
Jednoduše jsem přidal chybějící řádku s přidělením práv INTERNET. V debug režimu je pak ve výsledku tato řádka duplikovaná ale zřejmě to ničemu nevadí. Appka začala v konfiguraci Application Store fungovat jak při lokální distribuci, tak přes Play.
Ještě jsem chvíli hledal jestli někde nenajdu předlohu AndroidManifest.template.xml aby nebylo nutné jí měnit v každém novém projektu, ale na první výstřel jsem to nenašel. Jestli někdo odhalíte jak na to, podělte se. Beztak to považuji za dočasnou věc s životností do SP1 (nebo jiného nejbližšího upgrade).
Co mě ale na celé kauze překvapilo nejvíc, že na to někdo nepřišel během testování. To jsem první, kdo se snažil umístit appku na Play, která chce přístup k Internetu?!
Daniel Jenne, Praha, říjen 2013
Pozn editora: aspoň že má člověk možnost do toho sáhnout, když už je tam chyba. Jinak obecně o nastavování permission delphi.org/2013/10/delphi-xe5-android-uses-permissions/.