Требования
Headless API позволяет управлять HideMyAndroid полностью через ADB или любой инструмент автоматизации — без использования интерфейса приложения. Это функция уровня Premium.
- Аккаунт Premium — Headless API доступен только для Premium-пользователей.
- Версия приложения 1.2.8 или новее. Всё, что добавлено позже, — это дополнительные поля или методы, поэтому 1.2.8 по-прежнему работает, но новые возможности требуют более свежей сборки:
hook_spoof_uptime— 1.3.4+,geoиprofile.duplicate— 1.4.5+, а вся группа резервного копирования / восстановления — 1.5.3+. Старая сборка игнорирует незнакомое ей поле и всё равно отвечаетok=true, но незнакомый метод заявляет о себе громче: вызов группы резервного копирования / восстановления на сборке старше 1.5.3 возвращаетBAD_REQUESTсerror_message«Unknown method: …». Если настройка будто бы ничего не делает, проверьте текущуюversionчерез status — пакетный релиз сообщает её честно, а самостоятельно собранная сборка, сделанная до повышения номера версии, может нести функцию и при этом сообщать старый номер. - Root + LSPosed — стандартная конфигурация, необходимая для работы HideMyAndroid. Смотрите руководство по установке.
- ADB, подключённый к устройству (
adb devicesдолжно показывать его в списке). - Интернет на устройстве — требуется только при включении прокси (соединение проверяется в реальном времени).
⚠️ Разрешение VPN нужно только для профилей с прокси. Headless не может вызвать системный диалог согласия на VPN, поэтому выдайте его один раз на экране Headless API в приложении. Без него активация профиля с прокси всё равно активирует профиль, но прокси не подключится, и вызов вернёт
INTERNALименно с таким сообщением.
Аутентификация
Откройте Настройки → Разработчику → Headless API в приложении и включите параметр Включить. Ключ будет сгенерирован автоматически — нажмите Скопировать. Каждый запрос передаёт этот ключ в параметре token.
Держите ключ в тайне — любой, у кого есть ключ и доступ через ADB, сможет управлять вашими профилями. Повторная генерация создаёт новый ключ (старый перестаёт работать); выход из аккаунта удаляет его.
В данном справочнике замените <your_access_token> своим ключом, а <profile_id> — идентификатором, возвращённым командой profile.create.
Отправка запросов
Два транспорта — выбор зависит от того, содержит ли значение двоеточие :
| Транспорт | Использовать для | Команда |
|---|---|---|
content call | Чтение и значения без : (name, gmails, имена пакетов) | adb shell content call |
am broadcast | JSON-объекты (hookFlags, proxy, deviceMock, sim) — они содержат : | adb shell am broadcast |
content call разбивает каждый параметр --extra по двоеточию, поэтому не может передавать JSON — именно поэтому JSON-значения отправляются через broadcast.
Broadcast-форма есть всего у трёх методов: HEADLESS_UPDATE (profile.update), HEADLESS_SET_ACTIVE и HEADLESS_DEACTIVATE. Остальные пятнадцать — status, все операции чтения, profile.create, profile.duplicate, profile.delete, вызовы для целевых приложений и вся группа резервного копирования / восстановления — работают только через content call. Никакого HEADLESS_CREATE — как и HEADLESS_BACKUP — искать не нужно.
Broadcast принимает не только JSON. HEADLESS_UPDATE передаёт ровно семь extra-параметров — name, hookFlags, proxy, geo, deviceMock, sim, gmails — поэтому name и gmails проходят по любому из двух транспортов. Таблица выше говорит о том, что удобнее, а не о том, что возможно. Любой extra, которого нет в этом списке из семи, отбрасывается без ошибки.
Ответы. Успех обозначается ok=true (content call) или result=0 (broadcast); при ошибке добавляются поля error_code и error_message. Смотрите раздел Коды ошибок. Каждый метод также принимает параметр token. Нажмите на любую операцию ниже, чтобы раскрыть её параметры, запрос и ответ.
Статус
READ status Проверить готовность API content call
Parameters
No parameters.
Request
adb shell content call --uri content://com.wowsoftware.hidemyandroid.headless --method status --extra token:s:<your_access_token> Response ok=true
Bundle[{data={"premium":true,"featureEnabled":true,"freshnessOk":true,"activeProfileId":"a1b2c3d4-...","version":"1.5.3"}, ok=true}] Поля: premium, featureEnabled, freshnessOk, activeProfileId (или null), version. freshnessOk равно true, если приложение прошло онлайн-проверку лицензии за последние 24 часа. Сама проверка выполняется офлайн — headless-запрос никогда не обращается к сети, он только читает сохранённый результат, и premium тоже читается офлайн. Открывайте приложение хотя бы раз в сутки, чтобы freshnessOk оставалось true.
💡
status— единственный метод, который продолжает отвечать при истёкшей или несвежей лицензии: все остальные вызовы вернутLICENSE_EXPIREDилиLICENSE_STALEи больше ничего. Именно так и различают эти два случая, когда запрос отклонён: посмотритеpremium, чтобы понять, действительно ли закончился Premium, иfreshnessOk, чтобы понять, достаточно ли просто один раз открыть приложение. При этомstatusпо-прежнему закрыт проверкамиFEATURE_DISABLEDиUNAUTHORIZED, так что выключенный API или неверный токен здесь выглядят так же, как везде.
Профили
READ profile.list Получить список всех профилей content call
Parameters
No parameters.
Request
adb shell content call --uri content://com.wowsoftware.hidemyandroid.headless --method profile.list --extra token:s:<your_access_token> Response ok=true
Bundle[{data=[{"id":"a1b2...","name":"Demo","isActive":true,"createdAt":1717000000000,"updatedAt":1717000500000}], ok=true}] READ profile.get Получить полные данные одного профиля content call
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
id | string | required | Идентификатор профиля. |
Request
adb shell content call --uri content://com.wowsoftware.hidemyandroid.headless --method profile.get --extra token:s:<your_access_token> --extra id:s:<profile_id> Response ok=true
Bundle[{data={"id":"a1b2...","name":"Demo","isActive":false,"hookFlags":{"hook_wifi":true,...},"proxy":{"enabled":false,...},"geo":{"source":"PROXY",...},"deviceMock":{"enabled":false,...},"sim":{"enabled":false,"simCards":[]},"gmails":[],"targetApps":["com.whatsapp"]}, ok=true}] CREATE profile.create Создать профиль (возвращает его идентификатор) content call
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
name | string | required | Название профиля. |
Request
adb shell content call --uri content://com.wowsoftware.hidemyandroid.headless --method profile.create --extra token:s:<your_access_token> --extra name:s:Demo Response ok=true
Bundle[{data={"id":"a1b2c3d4-..."}, ok=true}] Скопируйте этот идентификатор как <profile_id> для последующих вызовов.
CREATE profile.duplicate Клонировать профиль с новой личностью content call
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
id | string | required | Идентификатор профиля, который копируем. |
Request
adb shell content call --uri content://com.wowsoftware.hidemyandroid.headless --method profile.duplicate --extra token:s:<your_access_token> --extra id:s:<profile_id> Response ok=true
Bundle[{data={"id":"e5f6a7b8-...","name":"Brave Falcon 42"}, ok=true}] Возвращаются и новый идентификатор, и сгенерированное имя — profile.create отдаёт только id, так что не ждите, что эти два ответа совпадут.
⚠️ Имя генерируется автоматически и не может быть задано в самом вызове. Если нужно своё, сразу после переименуйте копию через profile.update.
Что переносится в копию
Клонирует профиль так же, как пункт Дублировать в приложении — требуется приложение 1.4.5+. Настройки переносятся, но каждое идентифицирующее значение генерируется заново, поэтому у копии собственный отпечаток, а не близнец оригинала. Broadcast-формы нет: широковещательный вызов «отправил и забыл» не смог бы вернуть вам новый идентификатор, ради которого всё и затевается.
| Что | В копии |
|---|---|
Целевые приложения, hookFlags, proxy (вместе с проверенной геолокацией), geo, скрытые пакеты | Переносятся без изменений |
| Каждый идентификатор устройства — как на уровне профиля, так и отдельно для каждого приложения в профиле | Выпускаются заново, поэтому у копии собственный отпечаток, а не близнец оригинала |
deviceMock (если включён) | Переключается на другой шаблон устройства |
sim | Та же страна, новые номера |
| Пакеты резервных копий | Не копируются — резервные копии привязаны к ключу {package}-{profileId}, поэтому копия не владеет ни одной и начинает с нуля |
| Виртуальные аккаунты Gmail | Один новый адрес, если у исходного профиля был включён hook_virtual_accounts; иначе пустой список |
| Имя | Генерируется и гарантированно уникально, в виде Brave Falcon 42 — выбрать его нельзя, поэтому оно и возвращается вам |
| Состояние активности | Всегда isActive: false — дублирование никогда не активирует профиль |
Чтобы получить собственное имя, сначала продублируйте, а затем переименуйте вторым вызовом:
# 1. duplicate — the new id and its generated name come back together
adb shell content call --uri content://com.wowsoftware.hidemyandroid.headless --method profile.duplicate --extra token:s:<your_access_token> --extra id:s:<source_profile_id>
# 2. rename the copy — profile.duplicate never takes a name of your own
adb shell content call --uri content://com.wowsoftware.hidemyandroid.headless --method profile.update --extra token:s:<your_access_token> --extra id:s:<new_profile_id> --extra name:s:"My Profile" UPDATE profile.update Изменить настройки профиля content call / broadcast
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
id | string | required | Идентификатор профиля. |
name | string | optional | Новое название профиля (content call). |
gmails | string[] | optional | Виртуальные аккаунты @gmail.com (content call). |
hookFlags | object | optional | Переключатели спуфинга вкл/выкл (broadcast). |
proxy | object | optional | Конфигурация прокси (broadcast). |
geo | object | optional | Источник геолокации — прокси или собственный (broadcast). Требуется приложение 1.4.5+. |
deviceMock | object | optional | Подмена модели устройства (broadcast). |
sim | object | optional | Подмена SIM / оператора (broadcast). |
Request
content call — обычные значения
adb shell content call --uri content://com.wowsoftware.hidemyandroid.headless --method profile.update --extra token:s:<your_access_token> --extra id:s:<profile_id> --extra name:s:"My Profile" broadcast — JSON-конфигурации
adb shell am broadcast -a com.wowsoftware.hidemyandroid.HEADLESS_UPDATE -p com.wowsoftware.hidemyandroid -e token <your_access_token> -e id <profile_id> -e hookFlags '{"hook_wifi":false,"hook_nearby_bluetooth":false}' Response ok=true
Оба варианта возвращают полный обновлённый профиль. Все JSON-поля описаны в разделе «Конфигурация».
⚠️ hookFlags заменяет весь набор — любой флаг, который вы не укажете, вернётся к своему значению по умолчанию: ВКЛ для всех флагов, кроме hook_spoof_uptime, у которого это ВЫКЛ. То есть обновление без hook_spoof_uptime молча выключает его обратно. Чтобы изменить несколько флагов и сохранить остальные, сначала выполните profile.get, отредактируйте полную карту, затем отправьте её обратно целиком.
DELETE profile.delete Удалить профиль без возможности восстановления content call
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
id | string | required | Идентификатор профиля. |
Request
adb shell content call --uri content://com.wowsoftware.hidemyandroid.headless --method profile.delete --extra token:s:<your_access_token> --extra id:s:<profile_id> Response ok=true
Bundle[{data={}, ok=true}] ⚠️ Удаление профиля также удаляет его резервные копии данных приложений в /sdcard/HideMyAndroid_Backups/ — если они нужны, сначала скопируйте их с устройства. А начиная с 1.5.3, пока задача резервного копирования / восстановления ещё удерживает слот, profile.delete отвечает BUSY — даже для уже отменённой задачи; повторяйте вызов, пока BUSY не прекратится.
Активация
Профиль начинает подменять данные только после активации, и активным всегда бывает лишь один профиль. profile.setActive переключает активный профиль — тот, что был активен до этого, деактивируется за вас, поэтому вызывать profile.deactivate заранее не нужно.
⚠️ Активация стирает данные целевых приложений.
profile.setActiveне просто перезапускает их: он принудительно останавливает каждое целевое приложение и стирает его данные, чтобы оно поднялось чистым и действительно приняло новую личность. Это сделано намеренно — но это значит, что всё, что было внутри этих приложений, пропадёт, включая выполненные входы в аккаунты, В приложении это же действие сначала просит подтверждения и напоминает про функцию резервного копирования; headless-вызов не показывает никакого диалога и выполняется сразу, так что это предупреждение — единственное, которое вы получите. В headless-режиме страховкой служитbackup.start(1.5.3+) перед переключением. А начиная с 1.5.3, пока задача резервного копирования / восстановления ещё удерживает слот,profile.setActiveиprofile.deactivateотвечаютBUSY— даже для уже отменённой задачи; повторяйте вызов, покаBUSYне прекратится.
ACTION profile.setActive Активировать профиль — начать спуфинг content call / broadcast
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
id | string | required | Идентификатор профиля. В broadcast принимается как id, так и profile_id. |
Request
content call — рекомендуется
adb shell content call --uri content://com.wowsoftware.hidemyandroid.headless --method profile.setActive --extra token:s:<your_access_token> --extra id:s:<profile_id> broadcast — для автоматизации
adb shell am broadcast -a com.wowsoftware.hidemyandroid.HEADLESS_SET_ACTIVE -p com.wowsoftware.hidemyandroid -e token <your_access_token> -e id <profile_id> Response ok=true
Bundle[{data={"id":"a1b2...","isActive":true}, ok=true}] ACTION profile.deactivate Деактивировать активный профиль — остановить спуфинг content call / broadcast
Parameters
No parameters.
Request
content call — рекомендуется
adb shell content call --uri content://com.wowsoftware.hidemyandroid.headless --method profile.deactivate --extra token:s:<your_access_token> broadcast — для автоматизации
adb shell am broadcast -a com.wowsoftware.hidemyandroid.HEADLESS_DEACTIVATE -p com.wowsoftware.hidemyandroid -e token <your_access_token> Response ok=true
Bundle[{data={}, ok=true}] Идентификатор не нужен — деактивируется любой активный в данный момент профиль.
content call — предпочтительная форма: он синхронный и печатает возвращённый Bundle. Широковещательные HEADLESS_SET_ACTIVE и HEADLESS_DEACTIVATE делают ту же работу для инструментов автоматизации вроде Tasker. Они отвечают как ordered broadcast, который всегда несёт данные обратно: при успехе am broadcast печатает result=0 и JSON результата в data="…", при ошибке — result=1 и data="{"error_code":…,"error_message":…}". То есть это не совсем «отправил и забыл»: разберите data= — и получите тот же ответ, что дал бы content call. HEADLESS_SET_ACTIVE принимает идентификатор профиля и как -e id, и как -e profile_id; HEADLESS_DEACTIVATE вообще не требует идентификатора. Как всегда, добавляйте -p com.wowsoftware.hidemyandroid.
Целевые приложения
Целевые приложения — это приложения, для которых профиль выполняет спуфинг.
READ profile.getApps Получить список целевых приложений профиля content call
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
id | string | required | Идентификатор профиля. |
Request
adb shell content call --uri content://com.wowsoftware.hidemyandroid.headless --method profile.getApps --extra token:s:<your_access_token> --extra id:s:<profile_id> Response ok=true
Bundle[{data=[{"packageName":"com.whatsapp"}], ok=true}] CREATE profile.addApp Добавить целевое приложение в профиль content call
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
id | string | required | Идентификатор профиля. |
packageName | string | required | Имя пакета приложения. |
Request
adb shell content call --uri content://com.wowsoftware.hidemyandroid.headless --method profile.addApp --extra token:s:<your_access_token> --extra id:s:<profile_id> --extra packageName:s:com.whatsapp Response ok=true · updated app list
Bundle[{data=[{"packageName":"com.whatsapp"}], ok=true}] ⚠️ Повторное добавление того же пакета возвращает BAD_REQUEST.
DELETE profile.removeApp Удалить целевое приложение из профиля content call
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
id | string | required | Идентификатор профиля. |
packageName | string | required | Приложение для удаления. |
Request
adb shell content call --uri content://com.wowsoftware.hidemyandroid.headless --method profile.removeApp --extra token:s:<your_access_token> --extra id:s:<profile_id> --extra packageName:s:com.whatsapp Response ok=true · updated app list
Bundle[{data=[], ok=true}] ⚠️ Удаление пакета, которого нет в профиле, всё равно завершается успехом и ничего не меняет — это не ошибка. Это намеренно отличается от addApp, где добавление дубликата возвращает BAD_REQUEST.
Резервное копирование и восстановление
Новинка 1.5.3: эта группа копирует данные приложений профиля в архивы на устройстве и позже возвращает их обратно — та же работа, что и Manage Backups в приложении, только без интерфейса. Все шесть методов работают только через content call (broadcast-формы нет), а оба вызова *.start асинхронны: они сразу возвращают jobId и продолжают работать в фоне — опрашивайте backup.job, чтобы следить за ходом. Резервное копирование даже одного приложения может занять несколько минут.
⚠️ Одна задача за раз. Второй
*.start, пока выполняется первая, возвращаетBUSY, аjobIdработающей задачи — вerror_message. Кроме того, оба вызова*.startтребуют, чтобы нужный профиль был активен, — иначеREQUIRES_ACTIVE_PROFILE, и флага для обхода не существует. Остальные четыре метода работают с любым профилем. И, как везде в headless API, никто не просит подтверждения — каждый вызов выполняется сразу.
ACTION backup.start Запустить задачу резервного копирования для активного профиля content call
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
id | string | required | Идентификатор профиля — это должен быть текущий активный профиль. |
packages | string | optional | Имена пакетов для резервного копирования, через запятую (без пробелов). Опустите параметр, чтобы скопировать все целевые приложения профиля. Каждый пакет должен принадлежать профилю. |
Request
content call — все целевые приложения
adb shell content call --uri content://com.wowsoftware.hidemyandroid.headless --method backup.start --extra token:s:<your_access_token> --extra id:s:<profile_id> content call — только выбранные пакеты
adb shell content call --uri content://com.wowsoftware.hidemyandroid.headless --method backup.start --extra token:s:<your_access_token> --extra id:s:<profile_id> --extra packages:s:com.twitter.android,com.facebook.katana Response ok=true · job accepted
Bundle[{data={"jobId":"f0e1d2c3-...","type":"backup","total":2,"packages":["com.twitter.android","com.facebook.katana"],"foregroundHeld":true}, ok=true}] Вызов возвращается в момент принятия задачи — он не ждёт завершения копирования. total — сколько приложений обработает задача; опрашивайте backup.job, чтобы следить за ходом. О том, что foregroundHeld обещает (и чего не обещает), читайте в примечаниях ниже.
⚠️ Резервное копирование никогда не останавливает приложение принудительно и не стирает его данные. Чтобы прочитать согласованный снимок, оно ненадолго приостанавливает приложение (SIGSTOP) на время архивирования каждого компонента, а затем возобновляет его (SIGCONT) — приложение продолжает работать и ничего не теряет. Копирование пакета, у которого уже есть резервная копия, заменяет старый архив: одна резервная копия на приложение в каждом профиле, без истории.
ACTION restore.start Восстановить данные приложений из резервной копии в активный профиль content call
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
id | string | required | Идентификатор профиля — это должен быть текущий активный профиль. Резервная копия восстанавливается только в тот профиль, который её создал. |
packages | string | optional | Имена пакетов для восстановления, через запятую (без пробелов). Опустите параметр, чтобы восстановить все приложения, у которых есть резервная копия в этом профиле, — приложения без неё молча пропускаются. Назовите пакеты явно — и вызов падает при первой же проблеме: одна отсутствующая резервная копия проваливает весь вызов с NO_BACKUP, и ничего не восстанавливается. |
Request
adb shell content call --uri content://com.wowsoftware.hidemyandroid.headless --method restore.start --extra token:s:<your_access_token> --extra id:s:<profile_id> Response ok=true · job accepted
Bundle[{data={"jobId":"09a8b7c6-...","type":"restore","total":1,"packages":["com.twitter.android"],"foregroundHeld":true}, ok=true}] Та же модель задач, что и у backup.start: ответ приходит сразу, а поле type содержит "restore". Опрашивайте backup.job, чтобы следить за ходом; отдельного restore.job не существует.
⚠️ Восстановление принудительно останавливает целевое приложение (am force-stop) и не перезапускает его, а затем распаковывает архив поверх /data/data/<pkg> без предварительной очистки каталога — файлы, созданные приложением после копирования, переживают его. А резервные копии привязаны к ключу пакет + профиль — именно поэтому восстановления между профилями не существует: перелить резервную копию одного профиля в другой нельзя.
READ backup.job Опросить ход и результаты задачи content call
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
jobId | string | optional | Задача, которую нужно посмотреть. Опустите параметр, чтобы прочитать самую последнюю задачу. |
Request
content call — конкретная задача
adb shell content call --uri content://com.wowsoftware.hidemyandroid.headless --method backup.job --extra token:s:<your_access_token> --extra jobId:s:<job_id> content call — последняя задача (без jobId)
adb shell content call --uri content://com.wowsoftware.hidemyandroid.headless --method backup.job --extra token:s:<your_access_token> Response ok=true
# while it runs
Bundle[{data={"jobId":"f0e1d2c3-...","type":"backup","profileId":"a1b2...","state":"RUNNING","total":2,"done":0,"ok":0,"failed":0,"currentPackage":"com.twitter.android","currentComponent":"Internal Data","progress":0.31,"results":[],"error":null,"foregroundHeld":true,"startedAt":1712345678901,"finishedAt":null}, ok=true}]
# when it finishes — note: DONE even though one app failed
Bundle[{data={"jobId":"f0e1d2c3-...","type":"backup","profileId":"a1b2...","state":"DONE","total":2,"done":2,"ok":1,"failed":1,"currentPackage":null,"currentComponent":null,"progress":1.0,"results":[{"packageName":"com.twitter.android","ok":true,"error":null},{"packageName":"com.facebook.katana","ok":false,"error":"tar exited 2"}],"error":null,"foregroundHeld":true,"startedAt":1712345678901,"finishedAt":1712345699999}, ok=true}] Один метод обслуживает оба типа задач — type содержит "backup" или "restore". state — это RUNNING, DONE, FAILED или CANCELLED; progress идёт от 0 до 1 по всей задаче; startedAt / finishedAt — миллисекунды эпохи, и finishedAt остаётся null, пока задача выполняется. DONE означает, что задача дошла до конца, — а не что каждое приложение обработано успешно, — поэтому всегда читайте failed и results[] (по одному {packageName, ok, error} на приложение). currentComponent — человекочитаемое название этапа ("Internal Data", "Device Encrypted Data", "External Data", "Media", "OBB", "Permissions", "SSAID") — намеренно не те же строки, что components[] в backup.list. Работает с любым профилем. Хранятся только пять последних задач — неизвестный или более старый jobId возвращает NOT_FOUND, как и опрос до того, как хоть одна задача вообще выполнялась.
ACTION backup.cancel Отменить выполняющуюся задачу content call
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
jobId | string | optional | Задача, которую нужно отменить. Опустите параметр, чтобы отменить самую последнюю задачу. |
Request
adb shell content call --uri content://com.wowsoftware.hidemyandroid.headless --method backup.cancel --extra token:s:<your_access_token> --extra jobId:s:<job_id> Response ok=true · job snapshot
Возвращает снимок задачи после отмены — той же формы, что возвращает backup.job.
⚠️ Отмена посреди приложения оставляет его архив записанным наполовину: приложение не попадает в список резервных копий, а оставшиеся файлы находятся в неопределённом состоянии. Не восстанавливайтесь из него — удалите пакет через backup.delete и скопируйте заново. А снимок переключается в CANCELLED (с заполненным finishedAt) сразу, но root-процесс tar в основе нельзя прервать посреди файла, и он продолжает работать — поэтому задача может всё ещё удерживать слот, когда CANCELLED уже отображается (см. примечания ниже).
READ backup.list Получить список сохранённых резервных копий профиля content call
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
id | string | required | Идентификатор профиля — любой профиль, не только активный. |
Request
adb shell content call --uri content://com.wowsoftware.hidemyandroid.headless --method backup.list --extra token:s:<your_access_token> --extra id:s:<profile_id> Response ok=true
Bundle[{data=[{"packageName":"com.twitter.android","appName":"X","timestamp":1712345678901,"totalSize":12345678,"components":["INTERNAL_DATA","EXTERNAL_DATA","OBB"]}], ok=true}] По одной записи на каждое скопированное приложение. appName — отображаемое имя, зафиксированное в момент копирования (читается из metadata.json архива, а не выводится из пакета). timestamp — миллисекунды эпохи, totalSize — байты, а components[] использует имена перечисления: INTERNAL_DATA, DEVICE_ENCRYPTED, EXTERNAL_DATA, MEDIA, OBB, PERMISSIONS, SSAID.
DELETE backup.delete Удалить резервную копию одного приложения из профиля content call
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
id | string | required | Идентификатор профиля. |
packageName | string | required | Приложение, чью резервную копию нужно удалить. |
Request
adb shell content call --uri content://com.wowsoftware.hidemyandroid.headless --method backup.delete --extra token:s:<your_access_token> --extra id:s:<profile_id> --extra packageName:s:com.twitter.android Response ok=true
Bundle[{data={}, ok=true}] Синхронный вызов — задача не создаётся; папка резервной копии удаляется сразу. Удаление резервной копии, которой нет, — не ошибка: вызов идемпотентен и всё равно возвращает ok=true с data={}. NOT_FOUND означает только то, что идентификатор профиля не существует; некорректный packageName возвращает BAD_REQUEST.
Как ведут себя задачи
DONEне означает, что каждое приложение обработано успешно. Это значит лишь, что задача дошла до конца. Приложение может завершиться с ошибкой, а задача всё равно закончится какDONE— читайтеfailedиresults[], всегда.- Активация теперь ждёт задачи. Пока задача удерживает слот,
profile.setActive,profile.deactivateиprofile.deleteотвечаютBUSY— даже для задачи, которую вы уже отменили, потому что root-процессtarв основе нельзя остановить посреди файла, а слот не отражается ни в одном поле снимка. Задача, завершившаяся естественным образом вDONEилиFAILED, освобождает слот почти сразу; после отмены не считайтеCANCELLEDпризнаком «слот свободен» — просто повторяйте вызов, покаBUSYне прекратится. foregroundHeld— это наблюдение, а не обещание. Оно сообщает, прикрывает ли задачу foreground-сервис от завершения со стороны ОС. На API 36 замерено значениеtrue, но дажеtrueозначает лишь, что запуск сервиса был принят, — последующий шаг повышения на некоторых устройствах всё равно может молча провалиться. Для долгих задач лучше не давать устройству засыпать, чем полагаться на это поле.- Где хранятся резервные копии.
/sdcard/HideMyAndroid_Backups/<packageName>-<profileId>/— по одной папке на приложение в каждом профиле, внутри — архивы.tar.gz(data.tar.gz,data_ext.tar.gz,media.tar.gz, …) плюсmetadata.json, записанные root-процессомtar. Именно ключ{package}-{profileId}делает восстановление возможным только в свой профиль. Резервные копии, сделанные headless-вызовом, видны и на экране Manage Backups в приложении.
Конфигурация
Это значения, которые передаются через profile.update. Значения по умолчанию при создании профиля:
| Настройка | По умолчанию | Чтобы использовать… |
|---|---|---|
| hookFlags (all 21) | ✅ ON — кроме hook_spoof_uptime ❌ OFF | Уже включено. Отправьте false только для тех флагов, которые нужно отключить, — и true для hook_spoof_uptime, единственного флага, выключенного изначально. |
| proxy | ❌ OFF | Включите "enabled":true |
| geo | PROXY | Отправьте "source":"CUSTOM" с координатами, countryCode и timezone, чтобы задать местоположение без прокси |
| deviceMock | ❌ OFF | Включите "enabled":true |
| sim | ❌ OFF | Включите "enabled":true |
| gmails | empty | Отправьте адреса (виртуальные аккаунты включены по умолчанию) |
⚠️ Конфигурация с
enabled:falseсохраняется, но не применяется — значения сохранены, чтобы вы могли включить их позже, но спуфинг не выполняется, пока не установленоenabled:true. Исключение —geo: у него нет переключателяenabled. Флагиhook_geo_*срабатывают всякий раз, когдаgeoдаёт пригодное местоположение — либо изsource: CUSTOM, либо от прокси сenabled:true, прошедшего проверку в реальном времени.
hookFlags
По умолчанию: ВКЛ для всех флагов, кроме hook_spoof_uptime, который ВЫКЛ. Карта вида "flag": true|false. При обновлении весь набор заменяется, но только тот набор, который вы действительно отправили: обновление без extra-параметра hookFlags не трогает флаги вообще. Внутри отправленного набора каждый пропущенный флаг возвращается к своему значению по умолчанию, поэтому остальные 20 снова становятся ВКЛ, а hook_spoof_uptime снова ВЫКЛ, даже если вы его включали. Чтобы изменить несколько флагов и сохранить остальные, сначала выполните profile.get, отредактируйте полную карту, затем отправьте её обратно целиком.
| Флаг | Что делает |
|---|---|
hook_hide_dev_opts | Скрывает параметры разработчика |
hook_hide_vpn | Скрывает VPN |
hook_hide_airplane_mode | Скрывает режим полёта |
hook_hide_proxy | Скрывает системную настройку прокси |
hook_hide_root | Скрывает root |
hook_hide_lsposed | Скрывает LSPosed |
hook_spoof_installer | Подменяет источник установки |
hook_package_info | Подменяет информацию о пакете / подписи |
hook_lan_scan_block | Блокирует сканирование локальной сети |
hook_identifiers_partly | Подменяет базовые идентификаторы устройства |
hook_identifiers_fully | Подменяет полный набор идентификаторов устройства — включает всё, что покрывает hook_identifiers_partly |
hook_wifi | Подменяет данные подключённой сети Wi-Fi |
hook_nearby_wifi | Подменяет результаты сканирования ближайших сетей Wi-Fi |
hook_nearby_bluetooth | Подменяет список ближайших устройств Bluetooth |
hook_realistic_sensor | Использует реалистичные данные сенсоров |
hook_sensor_accelerometer | Подменяет акселерометр (требует hook_realistic_sensor) |
hook_spoof_uptime | Подменяет время работы устройства — устройство выглядит так, будто работает дольше. Premium, экспериментальный. По умолчанию ВЫКЛ — единственный такой флаг. Требуется приложение 1.3.4+. |
hook_virtual_accounts | Включает виртуальные аккаунты Google (gmails требует, чтобы это было ВКЛ) |
hook_geo_gps | Подменяет GPS-координаты (требуется geo — от прокси или собственный) |
hook_geo_locale | Подменяет язык/регион (требуется geo — от прокси или собственный) |
hook_geo_timezone | Подменяет часовой пояс (требуется geo — от прокси или собственный) |
proxy
По умолчанию: ВЫКЛ. При enabled:true приложение устанавливает реальное соединение через прокси, получает его геолокацию и заполняет countryCode/lat/lon/timezone. Проверка в реальном времени занимает до ~8 с; прокси, не прошедший проверку, возвращает PROXY_INVALID и не сохраняется. Эти четыре поля — выходные: приложение записывает их само, поэтому всё, что вы в них отправите, будет перезаписано. Чтобы задать местоположение вручную, используйте geo с source: CUSTOM — для этого прокси не нужен вовсе. profile.get возвращает прокси вместе с этими четырьмя полями, но никогда не отдаёт username и password.
| Поле | Тип | По умолчанию | Значение / ограничения |
|---|---|---|---|
host | string | "" | IP-адрес или имя хоста прокси |
port | int | 0 | Порт — 1–65535, проверяется только при включении прокси |
protocol | string | HTTP | HTTP, SOCKS4 или SOCKS5 |
username | string | "" | Аутентификация (необязательно) — никогда не возвращается в profile.get |
password | string | "" | Аутентификация (необязательно) — никогда не возвращается в profile.get |
countryCode | string | "" | Выходное — 2 буквы страны, заполняется по результатам проверки |
lat | double | 0 | Выходное — заполняется по результатам проверки |
lon | double | 0 | Выходное — заполняется по результатам проверки |
timezone | string | "" | Выходное — имя IANA, заполняется по результатам проверки |
adb shell am broadcast -a com.wowsoftware.hidemyandroid.HEADLESS_UPDATE -p com.wowsoftware.hidemyandroid -e token <your_access_token> -e id <profile_id> -e proxy '{"enabled":true,"host":"10.0.0.1","port":1080,"protocol":"SOCKS5"}' geo
По умолчанию: {"source":"PROXY"}. Требуется приложение 1.4.5+. Отсюда профиль берёт своё местоположение, и источника два — выберите один через source. PROXY использует местоположение, считанное во время проверки прокси в реальном времени. CUSTOM позволяет задать координаты, часовой пояс и регион самостоятельно, вообще без прокси — можно поместить профиль в Токио, а трафик пустить куда угодно или никуда. Три флага hook_geo_* затем включают каждую часть по отдельности: GPS, регион + язык и часовой пояс.
⚠️ Обратите внимание на имена полей: в geo это latitude/longitude, а в proxy выше — короткие lat/lon. Это два разных объекта, а не синонимы: короткие имена внутри geo просто игнорируются.
| Поле | Тип | По умолчанию | Значение / ограничения |
|---|---|---|---|
source | string | PROXY | Обязательное. Ровно PROXY или CUSTOM — пропуск или опечатка возвращают BAD_REQUEST, значение никогда не трактуется молча как PROXY |
latitude | double | 0 | Обязательное для CUSTOM — от -90 до 90; 0/0 считается незаданным |
longitude | double | 0 | Обязательное для CUSTOM — от -180 до 180; 0/0 считается незаданным |
countryCode | string | "" | Обязательное для CUSTOM — 2 буквы, например JP. На входе регистр не важен, на выходе всегда в верхнем регистре |
timezone | string | "" | Обязательное для CUSTOM — имя IANA, например Asia/Tokyo. Проверяется только на непустоту — см. предупреждение ниже |
language | string | "" | Необязательное — 2 буквы по ISO 639-1, например ja, а не полный тег вида ja-JP. Если оставить пустым, выводится из countryCode; хранится всегда в нижнем регистре. Задать явно может только CUSTOM, на пути PROXY значение всегда выводится автоматически |
⚠️
source: CUSTOMдолжен приходить полным: пара координат, отличная от0/0и попадающая в диапазон, двухбуквенныйcountryCodeиtimezone. Пропустите хоть одно — и запрос вернётBAD_REQUEST: отката к прокси не будет. Приложение никогда не выполняет геокодирование и не выходит в сеть, чтобы заполнить эти поля за вас. Если ни один источник не окажется пригодным, ни один геохук не загрузится и наружу проступит реальное местоположение.
🛑
timezone— единственное поле, которое на самом деле не проверяется. Оно тестируется только на непустоту и никогда не сверяется с базой IANA. Опечатка вродеAsia/Tokyooбудет принята, вернётok=true, в неизменном виде вернётся изprofile.get— а на устройстве молча превратится в GMT. Нигде об ошибке не сообщат, поэтому копируйте имя точно. С координатами всё наоборот: они действительно проверяются по диапазону, и неверное значение громко падает сBAD_REQUEST.
CUSTOM — задать местоположение вручную, прокси не нужен
adb shell am broadcast -a com.wowsoftware.hidemyandroid.HEADLESS_UPDATE -p com.wowsoftware.hidemyandroid -e token <your_access_token> -e id <profile_id> -e geo '{"source":"CUSTOM","latitude":35.6812,"longitude":139.7671,"countryCode":"JP","timezone":"Asia/Tokyo","language":"ja"}' PROXY — брать местоположение у прокси (по умолчанию)
adb shell am broadcast -a com.wowsoftware.hidemyandroid.HEADLESS_UPDATE -p com.wowsoftware.hidemyandroid -e token <your_access_token> -e id <profile_id> -e geo '{"source":"PROXY"}' deviceMock
По умолчанию: ВЫКЛ. Имитирует другую модель устройства. Установите "enabled":true и укажите любые из перечисленных полей — все строки необязательны (по умолчанию пустые), каждое соответствует свойству Android Build:
| Поле | Соответствует | Пример |
|---|---|---|
manufacturer | Build.MANUFACTURER | Samsung |
brand | Build.BRAND | samsung |
model | Build.MODEL | SM-S918B |
device | Build.DEVICE (кодовое имя) | dm3q |
product | Build.PRODUCT | dm3qxxx |
board | Build.BOARD | kalama |
hardware | Build.HARDWARE | qcom |
buildId | Build.ID | UP1A.231005.007 |
buildIncremental | Build.VERSION.INCREMENTAL | S918BXXU3CWK9 |
buildType | Build.TYPE | user |
buildTags | Build.TAGS | release-keys |
buildFingerprint | Build.FINGERPRINT | samsung/dm3qxxx/dm3q:14/UP1A.231005.007/S918BXXU3CWK9:user/release-keys |
deviceName | Отображаемое имя устройства | Galaxy S23 Ultra |
adb shell am broadcast -a com.wowsoftware.hidemyandroid.HEADLESS_UPDATE -p com.wowsoftware.hidemyandroid -e token <your_access_token> -e id <profile_id> -e deviceMock '{"enabled":true,"manufacturer":"Samsung","brand":"samsung","model":"SM-S918B","device":"dm3q","product":"dm3qxxx","board":"kalama","hardware":"qcom","buildId":"UP1A.231005.007","buildIncremental":"S918BXXU3CWK9","buildType":"user","buildTags":"release-keys","buildFingerprint":"samsung/dm3qxxx/dm3q:14/UP1A.231005.007/S918BXXU3CWK9:user/release-keys","deviceName":"Galaxy S23 Ultra"}' sim
По умолчанию: ВЫКЛ. Подменяет SIM-карту/оператора. Установите "enabled":true и укажите до двух карт в поле simCards. Список всегда нормализуется ровно до двух карт: третья молча отбрасывается — запрос всё равно вернёт ok=true, — а одна карта дополняется пустой второй, поэтому profile.get всегда возвращает две. Каждая карта:
| Поле | Тип | По умолчанию | Значение / ограничения |
|---|---|---|---|
slotIndex | int | 0 | Слот SIM — назначается по позиции карты в массиве (0, затем 1); отправленное вами значение игнорируется |
carrierName | string | "" | Название оператора (например AT&T) |
countryIso | string | "" | Код страны ISO (например us) — хранится в нижнем регистре. Обратите внимание: это противоположно geo.countryCode, который хранится в верхнем регистре |
mcc | string | "" | Код мобильной страны — MCC (например 310) |
mnc | string | "" | Код мобильной сети — MNC (например 410) |
operatorCode | string | "" | Код оператора = mcc + mnc (например 310410) |
phoneNumber | string | "" | Номер телефона |
iccid | string | "" | Серийный номер SIM (ICCID) |
imsi | string | "" | IMSI |
networkType | string | "" | Тип сети — смотрите допустимые значения ниже; нераспознанное значение игнорируется молча |
networkType обрезается по краям и сравнивается без учёта регистра, а у каждого поколения сети есть несколько допустимых написаний:
| Значение | Также принимается | Поколение сети |
|---|---|---|
NR 5G | NR, 5G | 5G |
LTE | 4G | 4G |
WCDMA | UMTS, 3G | 3G |
GSM | 2G | 2G |
⚠️ Всё, чего нет в этой таблице, молча отключает подмену типа сети для этой карты — ни ошибки, ни
BAD_REQUEST: значение просто сохраняется и никогда не используется. Обратите внимание, что вNR 5Gесть пробел:NR5Gне распознаётся и попадает ровно в эту тихую яму.
adb shell am broadcast -a com.wowsoftware.hidemyandroid.HEADLESS_UPDATE -p com.wowsoftware.hidemyandroid -e token <your_access_token> -e id <profile_id> -e sim '{"enabled":true,"simCards":[{"slotIndex":0,"carrierName":"AT&T","countryIso":"us","mcc":"310","mnc":"410","operatorCode":"310410","networkType":"LTE"},{"slotIndex":1,"carrierName":"T-Mobile","countryIso":"us","mcc":"310","mnc":"260","operatorCode":"310260","networkType":"NR 5G"}]}' gmails
По умолчанию: пусто. Список виртуальных аккаунтов Google — принимаются только адреса @gmail.com. Список полностью заменяет предыдущий; [] очищает его. Внутри нет символа :, поэтому подходит content call:
adb shell content call --uri content://com.wowsoftware.hidemyandroid.headless --method profile.update --extra token:s:<your_access_token> --extra id:s:<profile_id> --extra 'gmails:s:["alice@gmail.com","bob@gmail.com"]' Полный пример
Полная настройка с нуля:
# 1. create a profile — copy the returned id into <profile_id> below
adb shell content call --uri content://com.wowsoftware.hidemyandroid.headless --method profile.create --extra token:s:<your_access_token> --extra name:s:Demo
# 2. add a target app
adb shell content call --uri content://com.wowsoftware.hidemyandroid.headless --method profile.addApp --extra token:s:<your_access_token> --extra id:s:<profile_id> --extra packageName:s:com.whatsapp
# 3. add the virtual Gmail accounts
adb shell content call --uri content://com.wowsoftware.hidemyandroid.headless --method profile.update --extra token:s:<your_access_token> --extra id:s:<profile_id> --extra 'gmails:s:["alice@gmail.com","bob@gmail.com"]'
# 4. enable + set the device mock
adb shell am broadcast -a com.wowsoftware.hidemyandroid.HEADLESS_UPDATE -p com.wowsoftware.hidemyandroid -e token <your_access_token> -e id <profile_id> -e deviceMock '{"enabled":true,"manufacturer":"Samsung","brand":"samsung","model":"SM-S918B","device":"dm3q","product":"dm3qxxx","board":"kalama","hardware":"qcom","buildId":"UP1A.231005.007","buildIncremental":"S918BXXU3CWK9","buildType":"user","buildTags":"release-keys","buildFingerprint":"samsung/dm3qxxx/dm3q:14/UP1A.231005.007/S918BXXU3CWK9:user/release-keys","deviceName":"Galaxy S23 Ultra"}'
# 5. enable + set the SIM mock (two cards, full fields)
adb shell am broadcast -a com.wowsoftware.hidemyandroid.HEADLESS_UPDATE -p com.wowsoftware.hidemyandroid -e token <your_access_token> -e id <profile_id> -e sim '{"enabled":true,"simCards":[{"slotIndex":0,"carrierName":"AT&T","countryIso":"us","mcc":"310","mnc":"410","operatorCode":"310410","networkType":"LTE","phoneNumber":"+12025550123","iccid":"8901410123456789012","imsi":"310410123456789"},{"slotIndex":1,"carrierName":"T-Mobile","countryIso":"us","mcc":"310","mnc":"260","operatorCode":"310260","networkType":"NR 5G","phoneNumber":"+12025550456","iccid":"8901260987654321098","imsi":"310260987654321"}]}'
# 6. enable + set the proxy (tested live, ~8s)
adb shell am broadcast -a com.wowsoftware.hidemyandroid.HEADLESS_UPDATE -p com.wowsoftware.hidemyandroid -e token <your_access_token> -e id <profile_id> -e proxy '{"enabled":true,"host":"10.0.0.1","port":1080,"protocol":"SOCKS5"}'
# 7. pick where the location comes from — geo has two sources, choose ONE
# A) from the proxy you just set. This is the default, so the line is optional:
adb shell am broadcast -a com.wowsoftware.hidemyandroid.HEADLESS_UPDATE -p com.wowsoftware.hidemyandroid -e token <your_access_token> -e id <profile_id> -e geo '{"source":"PROXY"}'
# B) or set it yourself — this needs no proxy at all. Use B *instead of* A, not after it:
# adb shell am broadcast -a com.wowsoftware.hidemyandroid.HEADLESS_UPDATE -p com.wowsoftware.hidemyandroid -e token <your_access_token> -e id <profile_id> -e geo '{"source":"CUSTOM","latitude":35.6812,"longitude":139.7671,"countryCode":"JP","timezone":"Asia/Tokyo","language":"ja"}'
# geo and proxy are independent: setting one never rewrites the other, and only
# geo.source decides which one feeds the hooks. So CUSTOM together with a proxy in
# a different country means your IP says one place while your GPS says another.
# 8. activate (restarts the target app and clears its data)
adb shell content call --uri content://com.wowsoftware.hidemyandroid.headless --method profile.setActive --extra token:s:<your_access_token> --extra id:s:<profile_id>
# 9. verify
adb shell content call --uri content://com.wowsoftware.hidemyandroid.headless --method profile.get --extra token:s:<your_access_token> --extra id:s:<profile_id> Коды ошибок
При ошибке возвращается ok=false с одним из следующих значений error_code (broadcast возвращает result=1):
| Код | Значение | Решение |
|---|---|---|
UNAUTHORIZED | Токен отсутствует или неверен | Используйте текущий ключ; при необходимости перегенерируйте его |
FEATURE_DISABLED | Headless API отключён | Включите в Настройки → Разработчику → Headless API |
BAD_REQUEST | Неверный параметр или JSON | Проверьте обязательные поля, корректность JSON, только gmail-адреса, отсутствие дублирующихся приложений, принадлежность пакетов профилю |
NOT_FOUND | Такого профиля, задачи или резервной копии не существует | Проверьте идентификатор с помощью profile.list, backup.job или backup.list |
BUSY | Задача резервного копирования / восстановления ещё удерживает слот | error_message называет jobId работающей задачи — дождитесь её завершения, затем повторите; после отмены слот может пережить состояние CANCELLED, поэтому повторяйте, пока BUSY не прекратится. Также возвращается из profile.setActive / deactivate / delete, пока задача удерживает слот |
REQUIRES_ACTIVE_PROFILE | backup.start / restore.start для профиля, который не активен | Сначала выполните profile.setActive — флага для обхода не существует |
NO_BACKUP | restore.start не нашёл резервную копию для запрошенного приложения (или у профиля их нет вовсе) | Проверьте backup.list; сначала выполните backup.start |
PROXY_INVALID | Прокси не прошёл проверку в реальном времени | Проверьте хост/порт/протокол/аутентификацию и наличие интернета на устройстве; данные не сохранены |
LICENSE_EXPIRED | Срок действия Premium истёк | Обновите подписку Premium |
LICENSE_STALE | Лицензия давно не проверялась онлайн | Откройте приложение один раз для повторной проверки (не реже одного раза в 24 ч при непрерывном использовании) |
INTERNAL | Внутренняя ошибка (I/O или root) | Повторите попытку; убедитесь, что root/LSPosed работают корректно |
Советы & устранение неполадок
- Broadcast не даёт результата? Убедитесь, что вы включили параметр
-p com.wowsoftware.hidemyandroid— Android блокирует broadcast без него. - Значение обрезается после символа
:? В этом значении есть двоеточие, поэтомуcontent callобрезает его. Отправьте его через broadcastHEADLESS_UPDATE. - JSON broadcast не применяется (часто на Windows)? При передаче через оболочку рабочего стола в оболочку устройства кавычки в JSON команды
am broadcast(hookFlags,proxy,deviceMock,sim) легко теряются, иamнеправильно интерпретирует значение (оно может отображаться как URI видаdat=…), и ничего не меняется. Надёжное решение — не передавать JSON через командную строку: поместите весь рабочий процесс в файл.sh(одинарные кавычки сохраняют JSON нетронутым), затем загрузите его на устройство и запустите там. Скрипт выполняется на устройстве, поэтому он может захватить идентификатор нового профиля и использовать его далее:bashзатем загрузите его на устройство и запустите:# setup.sh — the full example as one runnable script (runs on the device) URI=content://com.wowsoftware.hidemyandroid.headless PKG=com.wowsoftware.hidemyandroid K=<your_access_token> # 1. create a profile and capture its id ID=$(content call --uri $URI --method profile.create --extra token:s:$K --extra name:s:Demo | grep -o '"id":"[^"]*"' | head -n1 | sed 's/.*"id":"//;s/"//') echo "profile id: $ID" # 2. add a target app content call --uri $URI --method profile.addApp --extra token:s:$K --extra id:s:$ID --extra packageName:s:com.facebook.katana # 3. add the virtual Gmail accounts content call --uri $URI --method profile.update --extra token:s:$K --extra id:s:$ID --extra 'gmails:s:["alice@gmail.com","bob@gmail.com"]' # 4. enable + set the device mock am broadcast -a $PKG.HEADLESS_UPDATE -p $PKG -e token $K -e id $ID -e deviceMock '{"enabled":true,"manufacturer":"Samsung","brand":"samsung","model":"SM-S918B","device":"dm3q","product":"dm3qxxx","board":"kalama","hardware":"qcom","buildId":"UP1A.231005.007","buildIncremental":"S918BXXU3CWK9","buildType":"user","buildTags":"release-keys","buildFingerprint":"samsung/dm3qxxx/dm3q:14/UP1A.231005.007/S918BXXU3CWK9:user/release-keys","deviceName":"Galaxy S23 Ultra"}' # 5. enable + set the SIM mock (two cards) am broadcast -a $PKG.HEADLESS_UPDATE -p $PKG -e token $K -e id $ID -e sim '{"enabled":true,"simCards":[{"slotIndex":0,"carrierName":"AT&T","countryIso":"us","mcc":"310","mnc":"410","operatorCode":"310410","networkType":"LTE","phoneNumber":"+12025550123","iccid":"8901410123456789012","imsi":"310410123456789"},{"slotIndex":1,"carrierName":"T-Mobile","countryIso":"us","mcc":"310","mnc":"260","operatorCode":"310260","networkType":"NR 5G","phoneNumber":"+12025550456","iccid":"8901260987654321098","imsi":"310260987654321"}]}' # 6. enable + set the proxy (tested live, ~8s) am broadcast -a $PKG.HEADLESS_UPDATE -p $PKG -e token $K -e id $ID -e proxy '{"enabled":true,"host":"10.0.0.1","port":1080,"protocol":"SOCKS5"}' # 7. pick where the location comes from — geo has two sources, choose ONE # A) from the proxy you just set. This is the default, so the line is optional: am broadcast -a $PKG.HEADLESS_UPDATE -p $PKG -e token $K -e id $ID -e geo '{"source":"PROXY"}' # B) or set it yourself — this needs no proxy at all. Use B *instead of* A, not after it: # am broadcast -a $PKG.HEADLESS_UPDATE -p $PKG -e token $K -e id $ID -e geo '{"source":"CUSTOM","latitude":35.6812,"longitude":139.7671,"countryCode":"JP","timezone":"Asia/Tokyo","language":"ja"}' # geo and proxy are independent: setting one never rewrites the other, and only # geo.source decides which one feeds the hooks. So CUSTOM together with a proxy in # a different country means your IP says one place while your GPS says another. # 8. activate (restarts the target app and clears its data) content call --uri $URI --method profile.setActive --extra token:s:$K --extra id:s:$ID # 9. verify content call --uri $URI --method profile.get --extra token:s:$K --extra id:s:$IDbashОбычные командыadb push setup.sh /data/local/tmp/setup.sh adb shell sh /data/local/tmp/setup.shcontent call(без JSON) можно вводить напрямую без скрипта. В Git Bash добавляйте префиксMSYS_NO_PATHCONV=1к строкам сadb, чтобы путь на устройстве не преобразовывался. - Изменения не применились? Целевое приложение должно перезапуститься — активация профиля делает это автоматически и заодно стирает данные приложения, поэтому оно запускается с новой личностью и без всего, что было раньше.
PROXY_INVALIDдля надёжного прокси? Устройству нужен интернет для проверки, ограниченной ~8 с, поэтому медленный прокси может не успеть ответить.BUSYот задачи, которую вы уже отменили?backup.cancelсразу переводит задачу вCANCELLED(и заполняетfinishedAt), но запущенный еюtarнельзя прервать, и он продолжает работать, поэтому слот остаётся занятым.backup.jobпоказываетCANCELLED, пока слот всё ещё занят, и слот не отражается ни в одном поле — не считайтеCANCELLEDпризнаком «слот свободен»; просто повторяйтеprofile.setActive/deactivate/delete, пока они не перестанут возвращатьBUSY. (Задача, завершившаяся естественным образом вDONEилиFAILED, освобождает слот почти сразу.)