[Android] Подключение к ADB через Wi-Fi (через TCP)

ADB умеет подключаться к устройствам не только через USB, но и через TCP. Порой, это бывает весьма полезным.

1. Подключаем устройство через USB, а в консоль вводим команду adb tcpip 5555. В ответ будет выведена фраза «restarting in TCP mode port: 5555».
2. Отключаем устройство от USB, в консоль вводим команду adb connect <ip>:<port>, где <ip> — это адрес устройства, а <port>  в нашем случае — 5555. В ответ должна появится фраза «connected to 192.168.1.10:5555».

Во многих случаях достаточно выполнить лишь пункт 2 (т.е. бе предварительного подключения устройства по USB).

Проверяем, что устройство видно:

# adb devices
List of devices attached
192.168.1.10:5555 device

Соединение по TCP автоматически завершится в тот момент, когда вы подключите это устройство через USB. Также можно вручную указать ADB слушать только USB:

# adb usb

[iOS] Как программно обнаружить Jailbreak

Задумался вопросом — а каким образом некоторые iOS-приложения обнаруживают, что в системе произведен Jailbreak? Мало того, что некоторые приложения, вроде Skype просто показывают предупреждающее сообщение об этом, так некоторые вообще отказываются работать (к примеру, DirectTV). Почему отказываются? Думаю, тут все понятно — разработчики просто не хотят брать на себя бремя технической поддержки, ломая голову над тем, почему у пользователя глючно работает их вроде бы тщательно протестированная программа. Сам-то пользователь редко скажет, что у него сделан Jailbreak, а если и скажет, то разработчики вправе отказаться от предоставления в помощи, т.к. нет смысла поддерживать такие окружения, в которых любой сторонний мод может привести к нестабильному поведению не только отдельно взятого приложения, но и всей системы.

Вернемся же к вопросу — как обнаружить, что был Jailbreak? Обычно вместе с Jailbreak ставятся дополнительные утилиты и приложения, вроде таких как Cydia, MobileSubstrate и WinterBoard. Таким образом, с помощью несложного условия if — else можно в своем приложении написать участок кода, который будет детектить Jailbreak. Вот так и решается этот, на первый взгляд, сложный вопрос довольно примитивным методом.

[Android] Как узнать название пакета и activity из apk-приложения

Задача: узнать название пакета Android-приложения в формате apk и запускаемого активити.

Решение:

Способ 1

Можно взять и открыть AndroidManifest.xml, чтобы посмотреть нужные данные, к примеру, через команду cat:

cat <path_to_apk>

Пример вывода:

versionCode
minSdkVersiontargetSdkVersionnameprotectionLevel versionName
allowBackuphardwareAcceleratediconlabelthemescreenOrientation
launchMode
permissionvalueandroid*http://schemas.android.com/apk/res/
androidpackagmanifestcom.mobileshop2.uses-sdkuses-permissionandroid.
permission.INTERNETandroid.permission.WAKE_LOCK)android.permission.
ACCESS_COARSE_LOCATIONandroid.permission.VIBRATE)com.mobileshop.
permission.C2D_MESSAGE*com.google.android.c2dm.permission.RECEIVE
applicatioactivitycom.intent-filteractionandroid.intent.action.
MAIcategory android.intent.category.LAUNCHEreceiver'com.mobileshop.
GcmBroadcastReceiver'com.google.android.c2dm.permission.SEND&com.
google.android.c2dm.intent.RECEIVEservice#com.mobileshop.
GcmIntentService meta-dataserver_addresshttp://mobileshop.com/D

Большая часть содержимого файла AndroidManifest.xml является нечитабельной, т.к. сам файл является двоичным, а то, что поддается чтению, имеет не самый удобный формат для восприятия. Мы видим, что имя пакета имеет название com.mobileshop, но мы не видим название запускаемого активити.

Способ 2

Можно воспользоваться услугами утилиты AAPT (Android Asset Packaging Tool), которая представляет из себя  упаковщик для сборки приложения, библиотек и ресурсов в единый apk-файл. Утилита входит в состав Android SDK и располагается в моем случае в директории /Applications/AndroidSDK/build-tools/17.0.0/.

Чтобы узнать название пакета apk-приложения:

./aapt dump badging <path_to_apk> | grep "package"

Пример вывода:

package: name='com.mobileshop' versionCode='13' versionName='2.0'

Чтобы узнать название запускаемого активити apk-приложения:

./aapt dump badging /User/Desktop/HTC_Market_v2.0.apk | grep "launchable-activity"

Пример вывода:

launchable-activity: name='com.mobileshop.MainActivity' label='Mobile Shop' icon=''

Google Play — ошибка 923

Столкнулся с проблемой, что попытка установить/обновить приложения из Google Play заканчивалась ошибкой 923. Оказывается, причиной тому являлось, что в то время, когда приложение загружалось, устройство переходило в неактивный режим и связь с Wi-Fi обрывалась (т.к. у меня была задействована соответствующая опция). Хотя, на месте Google, я бы все выводил более информирующие сообщения об ошибках, а не тупо их коды.

Про покупку iPad Air #2

Идет вторая неделя, как я с новым iPad Air.

Как уже писал в предыдущей заметке, заказ оформил через официальный App Store. Доставка заняла где-то 1,5 недели. Курьер позвонили на прошлой недели в понедельник, сказал, что готов привести посылочку, однако в тот день я ее принять не мог, о чем и сообщил курьеру. Он сказал, что для переноса дня доставки нужно позвонить в их службу доставки и дал номер телефона. Оказалось, что это курьерская служба TNT, на сайте которой как раз написано, что они занимаются доставками товаров Apple. Позвонил, сказал, что готов принять посылку уже завтра, во вторник. Во вторник вновь звонок от курьера. И вот я уже с iPad Air.

Упаковка полностью цела, хотя на задней крышке планшета мне сделали гравировку. Т.е. по идее, они должны были достать планшет из упаковки, сделать гравировку, и лишь затем вновь его упаковать. Хотя, возможно, эта процедура немного отличается от той, которую я описал. Кстати, в сети читал комментарии, что после вскрытия упаковки оказывалось, что экран iPad’а весь заляпан, и на поверхности видны остатки клея. Но я, к счастью, избежал такой участи.

Про покупку iPad Air

Общие впечатления: планшет стал легче и меньше в размерах — очень непривычно. Скошенные края по периметру выглядят, по-моему, ужасно. Мало того, что это просто не красиво, так эти срезы настолько отшлифованы, что всегда блестят. Производительность — в браузере Chrome (Safari не пользуюсь) страницы стали открываться очень быстро по сравнению с тем, что происходило на iPad 3. Но! Самопроизвольные падения браузера никуда не делись — все также при попытке открыть еще одну вкладку приложение аварийно завершает свою работу. Грешу на 1 ГБ памяти в планшете. Камера — не знаю что не так, но снимки получаются слишком зашумленными, а для меня это весьма критично, т.к. я часто делаю фотографии через камеру на планшете. Нужно тестить дальше…

[iOS] Просмотр системных логов

Существует несколько способов просмотреть логи с iOS-устройства.

1. Через само устройство — в этом случае посмотреть можно лишь только краш-репорты (crashlog), но ведь это самое то для тестировщика! Идем в «Settings» -> «General» -> «About» -> «Diagnostic & Usage» -> «Diagnostic & Usage Data» и смотрим все доступные отчеты о падении приложений. Единственная проблема заключается в том, что здесь нет удобного средства для экспорта этих самых отчетов. Тем не менее, при крайней необходимости можно скопировать нужный участок лога через стандартную функцию копирования текста.

2. Через XCode — к сожалению, среда разработки XCode доступна исключительно для MacOS. По этой и многим другим причинам было бы неплохо, если тестировщики iOS-приложений имели в своем распоряжении хотя бы Mac mini. Для просмотра краш-репортов нужно подключить iOS-устройство к компьютеру, нажать кнопку «Use for Development», после чего в разделе «Device Logs» уже можно непосредственно просматривать логи и, что не маловажно, импортировать их!

Просмотр системных логов с iPhone и iPad

3. Через программу «iPhone Configuration Utility» — хотя основная функция этой утилиты заключается в настройки профилей для iOS-устройств, в ней имеется консоль, куда выводятся все логи с подключенного устройства. Незаменимая вещь для тестировщика. К тому же, утилита доступна и для Windows.

Просмотр системных логов с iPhone и iPad

4. Через синхронизацию iTunes — каждый раз, когда вы синхронизируете свое iOS-устройство с iTunes на компьютере, логи сохраняются в следующие директории:

Mac OS X:
~/Library/Logs/CrashReporter/MobileDevice/<DEVICE_NAME>

Windows XP
C:\Documents and Settings\<USERNAME>\Application Data\Apple Computer\Logs\CrashReporter\MobileDevice\<DEVICE_NAME>

Windows Vista or 7
C:\Users\<USERNAME>\AppData\Roaming\Apple Computer\Logs\CrashReporter\MobileDevice\<DEVICE_NAME>

[Android] Waiting for device

Иногда бывает, что adb видит сразу несколько устройств — к примеру, эмулятор и реальное устройство, подключенное к компьютеру, из-за чего выполнять команды становится невозможным (будет писаться waiting for device).

# adb devices
List of devices attached
emulator-5554 device
HT9TWA12709 device

Допустим, вам нужно работать с реальным устройством, но подключенный эмулятор вроде как не позволяет это сделать.

Есть два выхода:

1. Указывать ключ -d, если хотим использовать реальное устройство (подключенное через USB) или ключ -e, если хотим использовать эмулятор
2. Выполнить команду adb -e reboot bootloader, которая в данном уберет эмулятор из списка

[Android] Изменение host-файла

Задача: добавить в host-файл свою запись

Элегантное решение на примере эмулятора:

1. Запустить эмулятор: emulator -avd <EmulatorName> -partition-size 256

2. Выполнить команду adb shell

3. И последний этап: echo 127.0.0.1 NewHost >> /etc/hosts

Возможные проблемы из-за отсутствия Google Play services

Наша команда сейчас работает над одним Android-приложением. Дали мне его на тестирование. Пробую запустить на своем телефоне -> приложение сразу же аварийно завершает работу. В логах:

E/AndroidRuntime(5342): at com.htc.mobileshop.MainActivity.checkPlayServices(MainActivity.java:215)

Запускаю на другом устройстве -> ошибки нет, все стартует нормально. Так что же это может быть? Оказывается, не так давно я удалил со своего телефона системное приложение «Google Play services» за ненадобностью. И вот, как оказалось, что если не обрабатывать исключения, связанные с невозможностью обнаружить Play services, мы можем получить ситуацию, что наше приложение сразу же будет крашиться. А вот, к примеру, приложение Foursquare при своем запуске сразу же оповещает пользователя о том, что для дальнейшей работы с приложением необходимо установить «Google Play services».

[Android] Средства для анализа использования памяти

adb shell cat /proc/meminfo — покажет общую информацию по использованию памяти в системе. Наиболее важная и интересная информация содержится только в первых строчках вывода:

MemTotal: 419932 kB
MemFree: 11788 kB
Buffers: 3436 kB
Cached: 82272 kB
SwapCached: 14384 kB
...

MemTotal — это общий объем памяти, доступный для ядра и пользовательского пространства (зачастую меньше, чем фактический объем памяти устройства, так как некоторые количество памяти резервируется для радио, DMA буферов и т.д.).

MemFree — объем оперативной памяти, который не используется вообще.

Кеш оперативной памяти используется для кеша файловой системы и других подобных вещей. По-хорошему, системный кеш должнен иметь хотя бы 20 МБ (или около того) для того, чтобы избегать ситуации попадания в состояние подкачки.

adb shell dumpsys meminfo — также покажет информацию об используемой памяти в системе, но в более подробном виде (к примеру, по каждому запущенному Java-процессу):

C:\Users\ADmi>adb shell dumpsys meminfo
Applications Memory Usage (kB):
Uptime: 841043 Realtime: 841036

Total PSS by process:
    79059 kB: android.process.acore (pid 932)
    58356 kB: com.xxx (pid 6409)
    36592 kB: com.htc.launcher (pid 1062)
    36358 kB: system (pid 442)
    ...

Total PSS by OOM adjustment:
    36358 kB: System
               36358 kB: system (pid 442)
    58783 kB: Persistent
               27112 kB: com.android.systemui (pid 579)
               14913 kB: com.android.htcdialer (pid 729)
               11219 kB: com.android.phone (pid 715)
                5539 kB: com.android.nfc (pid 746)
    58356 kB: Foreground
               58356 kB: com.xxx (pid 6409)
    47710 kB: Visible
               ...

Total PSS by category:
   217584 kB: Dalvik
   148600 kB: Unknown
    50546 kB: .so mmap
    38764 kB: .apk mmap
    28005 kB: Other mmap
    13165 kB: .dex mmap
     1928 kB: Other dev
     1881 kB: Native
      696 kB: .ttf mmap
       40 kB: Cursor
       12 kB: Ashmem
       11 kB: .jar mmap

Total PSS: 501232 kB
      KSM: 0 kB saved from shared 0 kB
           0 kB unshared; 0 kB volatile

Зная PID или имя процесса можно вывести подробный отчет по нему:

adb shell dumpsys com.xxx — покажет:

C:\Users\ADmi>adb shell dumpsys meminfo com.xxx
Applications Memory Usage (kB):
Uptime: 939680 Realtime: 939674

** MEMINFO in pid 6409 [com.xxx] **
                             Shared  Private     Heap     Heap
                       Pss    Dirty    Dirty     Size    Alloc
                    ------   ------   ------   ------   ------
           Native       72      168       68    16516    16209
           Dalvik    48471     6512    48284    56867    47084
           Cursor        0        0        0
           Ashmem        2        4        0
        Other dev      268       52      264
         .so mmap     3087     6612     2508
        .jar mmap        0        0        0
        .apk mmap      149        0        0
        .ttf mmap      622        0        0
        .dex mmap      728        0        0
       Other mmap      956      636       92
          Unknown     3980     4328     3868
            TOTAL    58335    18312    55084    73383    63293

 Objects
           Views:      276     ViewRootImpl:        2
     AppContexts:        3       Activities:        2
          Assets:        4    AssetManagers:        4
   Local Binders:       13    Proxy Binders:       21
Death Recipients:        1
 OpenSSL Sockets:        1

 SQL
     MEMORY_USED:      112
PAGECACHE_OVERFLOW:       28      MALLOC_SIZE:       62

 DATABASES
      pgsz     dbsz   Lookaside(b)          cache  Dbname
         4       20             57       29/34/10  /data/data/com.xxx/databases/google_analytics_
v2.db
Uptime: 939889 Realtime now=939883