{"id":28564029,"url":"https://github.com/appium/io.appium.settings","last_synced_at":"2026-03-05T05:09:34.477Z","repository":{"id":17906407,"uuid":"20863984","full_name":"appium/io.appium.settings","owner":"appium","description":"App for dealing with Android settings","archived":false,"fork":false,"pushed_at":"2025-05-29T17:27:09.000Z","size":3839,"stargazers_count":144,"open_issues_count":4,"forks_count":63,"subscribers_count":16,"default_branch":"master","last_synced_at":"2025-05-31T15:12:19.972Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Java","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/appium.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null},"funding":{"open_collective":"appium"}},"created_at":"2014-06-15T19:57:34.000Z","updated_at":"2025-05-29T17:27:12.000Z","dependencies_parsed_at":"2024-01-09T19:46:14.251Z","dependency_job_id":"133f7da9-e6d3-4f66-a04f-f9624d718f7a","html_url":"https://github.com/appium/io.appium.settings","commit_stats":{"total_commits":237,"total_committers":29,"mean_commits":8.172413793103448,"dds":0.751054852320675,"last_synced_commit":"b58ed38884cde9949861137812f4f1f4fd5f52eb"},"previous_names":[],"tags_count":120,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/appium%2Fio.appium.settings","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/appium%2Fio.appium.settings/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/appium%2Fio.appium.settings/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/appium%2Fio.appium.settings/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/appium","download_url":"https://codeload.github.com/appium/io.appium.settings/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/appium%2Fio.appium.settings/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":259080989,"owners_count":22802404,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2025-06-10T13:09:22.721Z","updated_at":"2026-01-16T17:20:22.660Z","avatar_url":"https://github.com/appium.png","language":"Java","funding_links":["https://opencollective.com/appium"],"categories":[],"sub_categories":[],"readme":"# Settings\n\n[![NPM version](http://img.shields.io/npm/v/io.appium.settings.svg)](https://npmjs.org/package/io.appium.settings)\n[![Downloads](http://img.shields.io/npm/dm/io.appium.settings.svg)](https://npmjs.org/package/io.appium.settings)\n\n[![Release](https://github.com/appium/io.appium.settings/actions/workflows/publish.js.yml/badge.svg)](https://github.com/appium/io.appium.settings/actions/workflows/publish.js.yml)\n\nToggle settings in Android device or emulator.\n\nA small and simple Android application that deals with the system settings. Then the application shuts down.\n\n## Requirements\n\n* [Android SDK](http://developer.android.com)\n* [Java JDK](http://www.oracle.com/technetwork/java/javase/downloads/index.html)\n* [Gradle](https://gradle.org/)\n\nYou may also consider using the latest [Android Studio](https://developer.android.com/studio/index.html) to debug the code easily.\n\n### Enable access to non-SDK interfaces\n\n[Restrictions on non-SDK interfaces](https://developer.android.com/guide/app-compatibility/restrictions-non-sdk-interfaces#test-for-non-sdk) could affect some functionalities.\nChanging of the system locale in API Level 34 or later demonstrates the above restriction. Please [enable access to non-SDK interfaces](https://developer.android.com/guide/app-compatibility/restrictions-non-sdk-interfaces#how_can_i_enable_access_to_non-sdk_interfaces) via `adb`. [This issue comment](https://github.com/appium/io.appium.settings/issues/180#issuecomment-2156279885) is adb logcat output when the non-SDK interfaces are enabled, or disabled (system default). Please try out a device reboot if the same logcat continues even after setting the hidden api policy.\n\n## Building\n\n```shell\n$ ./gradlew clean assembleDebug\n```\n\nYou can also run `gradlew installDebug` to build and immediately deploy the app to a connected Android device or emulator.\n\n\n## Installing\n\nYou can install the apk through the [Android Debug Bridge](http://developer.android.com/tools/help/adb.html).\n\nTo install:\n\n```shell\n$ cd app/build/outputs/apk\n$ adb install settings_apk-debug.apk\n# You can grant permissions with -g option as below for over api level 23 devices\n# $ adb install -g settings_apk-debug.apk\n```\n\nTo uninstall:\n\n```shell\n$ adb uninstall io.appium.settings\n```\n\n## Using the JavaScript wrapper\n\nThis module exports the [SettingsApp](./lib/client.js) class, which allows you to automate the below interactions with JavaScript.\nThe wrapper expects you to also have the [appium-adb](https://github.com/appium/appium-adb) module listed\nin your dependencies. The actual version of the appium-adb module must satisfy the same semver requirement this module\nhas in its [devDependencies](./package.json).\nHere is the usage example:\n\n```js\nimport ADB from 'appium-adb'\nimport { SettingsApp } from 'io.appium.settings';\n\nasync function main() {\n  // It is expected 'io.appium.settings' is already installed on the device\n  // and the necessary permissions are granted to it.\n  // Check https://github.com/appium/appium-android-driver/blob/master/lib/helpers/android.ts\n  // if you are looking on how to automate this process.\n  const app = new SettingsApp({\n    adb: await ADB.createADB()\n  });\n  const recorder = app.makeMediaProjectionRecorder();\n  const filename = 'video.mp4';\n  const didStart = await recorder.start({filename});\n  if (didStart) {\n    log.info(`A new media projection recording '${filename}' has been successfully started`);\n  } else {\n    log.info('A new media projection recording was unable to start. Is it already running?');\n  }\n}\n\nmain();\n```\n\nThe module also exports various constants containing its service and action names, that could be useful in your\nscripts. Check [constants.js](./lib/constants.js) for more details.\n\n## Changing of system settings\n\nOnce installed on a device, you can change the `wifi`, `data`, `animation` and `locale` settings through the following commands:\n\nTo turn on `wifi`:\n\n```shell\n$ adb shell am broadcast -a io.appium.settings.wifi --es setstatus enable\n```\n\nTo turn off `wifi`:\n\n```shell\n$ adb shell am broadcast -a io.appium.settings.wifi --es setstatus disable\n```\n\nTo turn on `bluetooth`:\n\n```shell\n$ adb shell am broadcast -a io.appium.settings.bluetooth --es setstatus enable\n```\n\nTo turn off `bluetooth`:\n\n```shell\n$ adb shell am broadcast -a io.appium.settings.bluetooth --es setstatus disable\n```\n\nTo unpair known `bluetooth devices`:\n\n```shell\n$ adb shell am broadcast -a io.appium.settings.unpair_bluetooth\n```\n\nTo turn on `animation`:\n\n```shell\n$ adb shell am broadcast -a io.appium.settings.animation --es setstatus enable\n```\n\n(Note that [Restrictions on non-SDK interfaces](https://developer.android.com/guide/app-compatibility/restrictions-non-sdk-interfaces) affects this animation command.)\n\nTo turn off `animation`:\n\n```shell\n$ adb shell am broadcast -a io.appium.settings.animation --es setstatus disable\n```\n\n(Note that [Restrictions on non-SDK interfaces](https://developer.android.com/guide/app-compatibility/restrictions-non-sdk-interfaces) affects this animation command.)\n\nSet particular locale:\n\n```shell\n# If not granted already, grant locale change permission https://developer.android.com/reference/android/Manifest.permission#CHANGE_CONFIGURATION\n$ adb shell pm grant io.appium.settings android.permission.CHANGE_CONFIGURATION\n$ adb shell am broadcast -a io.appium.settings.locale -n io.appium.settings/.receivers.LocaleSettingReceiver --es lang ja --es country JP\n$ adb shell getprop persist.sys.locale # ja-JP\n$ adb shell am broadcast -a io.appium.settings.locale -n io.appium.settings/.receivers.LocaleSettingReceiver --es lang zh --es country CN --es script Hans\n$ adb shell getprop persist.sys.locale # zh-Hans-CN for API level 21+\n# When 'skip_locale_check' parameter is set appium settings application doesn't check that locale you are trying to set is a valid locale string, by default it validates the locale and throws error when invalid\n$ adb shell am broadcast -a io.appium.settings.locale -n io.appium.settings/.receivers.LocaleSettingReceiver --es lang xx --es country US --es skip_locale_check 1\n```\n\nYou can set the [Locale](https://developer.android.com/reference/java/util/Locale.html) format, especially this feature support [Locale(String language, String country)](https://developer.android.com/reference/java/util/Locale.html#Locale(java.lang.String,%20java.lang.String)) so far.\n\n`-n io.appium.settings/.receivers.LocaleSettingReceiver` is not necessary in some devices.\n\nList all supported locales as base64-encoded JSON:\n\n```shell\n$ adb shell am broadcast -a io.appium.settings.list_locales\n```\n\n## Retrieval of system settings\n\nYou can retrieve the current geo location by executing:\n\n```shell\n$ adb shell am broadcast -a io.appium.settings.location -n io.appium.settings/.receivers.LocationInfoReceiver --ez forceUpdate false\n```\n\nThe first value in the returned `data` string is the current latitude, the second is the longitude and the last one is the altitude. An empty string is returned if the data cannot be retrieved (more details on the failure cause can be found in the logcat output).\n\nSince version 3.6.0 it is also possible to provide `forceUpdate` boolean argument. If it is set to\n`true` then GPS cache refresh request is going to be send asynchronously every time when the\ncurrent location is requested. By default the cached location value is returned instead.\n\n_Note_\n\nThe forced GPS cache refresh feature only works if the device under test has\nGoogle Play Services installed. In case the vanilla LocationManager is used the device API level must be at\nversion 30 (Android R) or higher. If none of the conditions above is satisfied then enabling of the `forceUpdate`\noption would have no effect.\n\n\n## Setting Mock Locations\n\nPlease set the Appium Settings from the Settings app's _Developer Options_ -\u003e _Select mock location app_.\nOr `adb shell appops set io.appium.settings android:mock_location allow` let you do the same via adb command.\n`adb shell appops set io.appium.settings android:mock_location deny` is to turn it off.\n\n\nStart sending scheduled updates (every 2s) for mock location with the specified values by executing:\n(API versions 26+):\n```shell\n$ adb shell am start-foreground-service --user 0 -n io.appium.settings/.LocationService --es longitude {longitude-value} --es latitude {latitude-value} [--es altitude {altitude-value}] [--es speed {speed-value}] [--es bearing {bearing-value}] [--es accuracy {accuracy-value}]\n```\n(Older versions):\n```shell\n$ adb shell am startservice --user 0 -n io.appium.settings/.LocationService --es longitude {longitude-value} --es latitude {latitude-value} [--es altitude {altitude-value}]\n```\nRunning the command again stops sending the previously specified location and starts sending updates for the\nnew mock location.\n\nAdditionally the service allows to provide the following optional parameters to the mocked\nlocation:\n\n- `speed`: the speed, in meters/second over ground. A float value greater than zero is acceptable.\n- `bearing`: the bearing, in degrees. Bearing is the horizontal direction of travel of this device, and is not related to the device orientation. The input will be wrapped into the range (0.0, 360.0]\n\nStop sending new mocklocations and clean up everything (remove the mock location providers) by executing:\n```shell\n$ adb shell am stopservice io.appium.settings/.LocationService\n```\n\n\n## IME actions generation\n\nYou can simulate IME actions generation with this application. First, it is necessary to enable and activate the corresponding service:\n\n```bash\nadb shell ime enable io.appium.settings/.AppiumIME\nadb shell ime set io.appium.settings/.AppiumIME\n```\n\nAfter the service is active simply focus any edit field, which contains an IME handler, and send `/action_name_or_integer_code/` text into this field: `adb shell input text '/action_name_or_integer_code/'` (enclosing slashes are required). The following action names are supported (case-insensitive): `normal, unspecified, none, go, search, send, next, done, previous`. If the given action name is unknown then it is going to be printed into the text field as is without executing any action.\n\n\n## Unicode IME\n\nThis input method allows to enter unicode values into text fields using `adb shell input text` terminal command. The idea is to encode the given unicode string into UTF-7 and then let the corresponding IME to decode and transform the actual input. This helper is also useful for automating applications running under Android API19 and older where `sendText` method of `UiObject` did not support Unicode properly. The actual implementation is based on the [Uiautomator Unicode Input Helper](https://github.com/sumio/uiautomator-unicode-input-helper) by TOYAMA Sumio.\n\nUse the following commands to enable the Unicode IME:\n\n```bash\nadb shell ime enable io.appium.settings/.UnicodeIME\nadb shell ime set io.appium.settings/.UnicodeIME\n```\n\n\n## Clipboard\n\nThis action allows to retrieve the text content of the current clipboard\nas base64-encoded string.\nAn empty string is returned if the clipboard cannot be retrieved\nor the clipboard is empty.\nRemember, that since Android Q the clipboard content can only be retrieved if\nthe requester application is set as the default IME in the system:\n\n```bash\nadb shell ime enable io.appium.settings/.AppiumIME\nadb shell ime set io.appium.settings/.AppiumIME\nadb shell am broadcast -a io.appium.settings.clipboard.get\nadb shell ime set com.google.android.inputmethod.latin/com.android.inputmethod.latin.LatinIME\n```\n\n\n## Notifications\n\nSince version 2.16.0 Appium Settings supports retrieval of system notifications.\nYou need to manually switch the corresponding security switcher next to `Appium Settings`\napplication name in `Settings-\u003eNotification Access` (the path to this page under Settings\nmay vary depending on Android version and the device model)\nin order to make this feature available. The next step would be to send the following broadcast command:\n```bash\n$ adb shell am broadcast -a io.appium.settings.notifications\n```\nThe notifications listener service is running in the background and collects\nall the active and newly created notifications into the internal buffer with maximum\nsize of `100`. The collected data (e.g. the properties and texts of each notification)\nis returned as JSON-formatted string. An error description string is returned instead if the\nnotifications list cannot be retrieved.\nThe example of the resulting data:\n```json\n{\n  \"statusBarNotifications\": [\n    {\n      \"isGroup\":false,\n      \"packageName\":\"io.appium.settings\",\n      \"isClearable\":false,\n      \"isOngoing\":true,\n      \"id\":1,\n      \"tag\":null,\n      \"notification\":{\n        \"title\":null,\n        \"bigTitle\":\"Appium Settings\",\n        \"text\":null,\n        \"bigText\":\"Keep this service running, so Appium for Android can properly interact with several system APIs\",\n        \"tickerText\":null,\n        \"subText\":null,\n        \"infoText\":null,\n        \"template\":\"android.app.Notification$BigTextStyle\"\n      },\n      \"userHandle\":0,\n      \"groupKey\":\"0|io.appium.settings|1|null|10133\",\n      \"overrideGroupKey\":null,\n      \"postTime\":1576853518850,\n      \"key\":\"0|io.appium.settings|1|null|10133\",\n      \"isRemoved\":false\n    }\n  ]\n}\n```\nSee https://developer.android.com/reference/android/service/notification/StatusBarNotification\nand https://developer.android.com/reference/android/app/Notification.html\nfor more information on available notification properties and their values.\n\n\n## SMS\n\nSince version 3.1 Appium Settings supports retrieval of SMS messages.\nMake sure the corresponding permission has been granted to the app\nin order to make this feature available. The next step would be to send\nthe following broadcast command:\n```bash\n$ adb shell am broadcast -a io.appium.settings.sms.read --es max 10\n```\nIn this example the SMS reader broadcast receiver would retrieve\nthe properties of `10 recent` incoming SMS messages. By default the limit\nis set to `100`. The collected data (e.g. the properties and texts of each SMS)\nis returned as JSON-formatted string. An error description string is returned instead if the\nSMS list cannot be retrieved.\nThe example of the resulting data:\n```json\n{\n  \"items\":[\n    {\n      \"id\":\"2\",\n      \"address\":\"+123456789\",\n      \"person\":null,\n      \"date\":\"1581936422203\",\n      \"read\":\"0\",\n      \"status\":\"-1\",\n      \"type\":\"1\",\n      \"subject\":null,\n      \"body\":\"\\\"text message2\\\"\",\n      \"serviceCenter\":null\n    },\n    {\n      \"id\":\"1\",\n      \"address\":\"+123456789\",\n      \"person\":null,\n      \"date\":\"1581936382740\",\n      \"read\":\"0\",\n      \"status\":\"-1\",\n      \"type\":\"1\",\n      \"subject\":null,\n      \"body\":\"\\\"text message\\\"\",\n      \"serviceCenter\":null\n    }\n  ],\n  \"total\":2\n}\n```\n\n\n## Media Scanning\n\nSince version 3.5 Appium Settings supports broadcast messages handling\nthat performs media scanning in response to `io.appium.settings.scan_media`\nintent. This was done due to `android.intent.action.MEDIA_SCANNER_SCAN_FILE` deprecation\nsince Android API version 30. To scan the given file or folder for media data simply run:\n\n```bash\n$ adb shell am broadcast -a io.appium.settings.scan_media --es path /sdcard/media\n```\n\nThis command will _recursively_ scan all files inside of `/sdcard/media` folder\nand add them to the media library if their MIME types are supported. If the\nfile/folder in _path_ does not exist/is not readable or is not provided then an\nerror will be returned and the corresponding log message would be written into logs.\n\n## Internal Audio \u0026 Video Recording\n\nRequired steps to activate recording:\n\n```bash\nadb shell pm grant io.appium.settings android.permission.RECORD_AUDIO\nadb shell appops set io.appium.settings PROJECT_MEDIA allow\n```\n\nStart Recording:\n```bash\nadb shell am start -n \"io.appium.settings/io.appium.settings.Settings\" -a io.appium.settings.recording.ACTION_START --es filename abc.mp4 --es priority high --es max_duration_sec 900 --es resolution 1920x1080\n```\n\n### Arguments (see above start command as an example for giving arguments)\n- filename (Mandatory) - You can type recording video file name as you want, but recording currently supports only \"mp4\" format so your filename must end with \".mp4\"\n- priority (Optional) - Default value: \"high\" which means recording thread priority is maximum however if you face performance drops during testing with recording enabled, you can reduce recording priority to \"normal\" or \"low\"\n- max_duration_sec (Optional) (in seconds) - Default value: 900 seconds which means maximum allowed duration is 15 minute, you can increase it if your test takes longer than that\n- resolution (Optional) - Default value: maximum supported resolution on-device(Detected automatically on app itself), which usually equals to Full HD 1920x1080 on most phones however you can change it to following supported resolutions as well: \"1920x1080\", \"1280x720\", \"720x480\", \"320x240\", \"176x144\"\n\nStop Recording:\n```bash\nadb shell am start -n \"io.appium.settings/io.appium.settings.Settings\" -a io.appium.settings.recording.ACTION_STOP\n```\n\nObtain Recording Output File:\n```bash\nadb pull /storage/emulated/0/Android/data/io.appium.settings/files/abc.mp4 abc.mp4\n```\n\n\n## Notes:\n\n* You have to specify the receiver class if the app has never been executed before:\n```shell\n$ adb shell am broadcast -a io.appium.settings.wifi -n io.appium.settings/.receivers.WiFiConnectionSettingReceiver --es setstatus disable\n```\n* To change animation setting, the app should be granted `SET_ANIMATION_SCALE` permission:\n```shell\n$ adb shell pm grant io.appium.settings android.permission.SET_ANIMATION_SCALE\n```\n* To change locale setting, the app should be granted `CHANGE_CONFIGURATION` permission:\n```shell\n$ adb shell pm grant io.appium.settings android.permission.CHANGE_CONFIGURATION\n```\n* To get location, the app should be granted `ACCESS_FINE_LOCATION` permission at least:\n```shell\n$ adb shell pm grant io.appium.settings android.permission.ACCESS_FINE_LOCATION\n```\n* To set location, the location mocking must be enabled. On Android 5 this requires enabling option\n`Allow mock locations` in Developer Settings. In later versions following command can be used:\n```shell\n$ adb shell appops set io.appium.settings android:mock_location allow\n```\n\n* On Android 6.0+ you must enable the corresponding permissions for the app first. This can be\ndone in application settings, Permissions entry.\n\n* Switching mobile data on/off requires the phone to be rooted on Android 5.0+\n('su' binary is expected to be available on internal phone file system).\nRead [this](http://stackoverflow.com/questions/26539445/the-setmobiledataenabled-method-is-no-longer-callable-as-of-android-l-and-later)\nStackOverflow thread for more details.\n\nVoila!\n\n\n## Caveats\n\nThere are certain system services which cannot be accessed through an application. Two ones central here are `airplane_mode` and `gps`.\n\n\n## License\n\nApache License 2.0\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fappium%2Fio.appium.settings","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fappium%2Fio.appium.settings","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fappium%2Fio.appium.settings/lists"}