Change Device language via ADB - android

I want to change language via ADB.
I try:
adb shell setprop persist.sys.language fr;setprop persist.sys.country CA;stop;sleep 5;start
but I get errors:
setprop: command not found
stop: missing job name
Try `stop --help' for more information.
start: missing job name
Try `start --help' for more information.
what is wrong?
I want to do this on physical device

Your errors have nothing to do with adb. You just lack understanding of how your local shell processes your command. What you are doing is running these commands locally (on your PC):
adb shell setprop persist.sys.language fr
setprop persist.sys.country CA
stop
sleep 5
start
and the error messages you see are from local shell (i.e. there is no setprop executable on your system and start and stop commands have non-optional parameters.
the correct command would be
adb shell "setprop persist.sys.language fr; setprop persist.sys.country CA; setprop ctl.restart zygote"
or in more recent Android versions:
adb shell "setprop persist.sys.locale fr-CA; setprop ctl.restart zygote"

You can change the locale/language for testing purposes without rooting the device, also on newer (4.2+) devices. You have to create an application that changes the device locale. Or, you can use a helper app, e.g. ADB Change Language.
Next, on 4.2+ devices, you have to use grant the app CHANGE_CONFIGURATION permission via adb, adb shell pm grant <package_name> android.permission.CHANGE_CONFIGURATION.
Finally, you can use adb commands (launch activity) to switch locale.

There is few solutions.It works for me.
1.
adb shell am start -a android.settings.LOCALE_SETTINGS
(You could see the language menu, then choose language by appium)
2.
download adbchangelanguage on google store
adb shell pm grant net.sanapeli.adbchangelanguage android.permission.CHANGE_CONFIGURATION
adb shell am start -n net.sanapeli.adbchangelanguage/.AdbChangeLanguage -e language zh -e country TW
https://gist.github.com/douglasselph/b9998e69998759c6cceec1df1aa96ac5
3.
using appium then set desired capabilities (language and locale)
http://appium.io/docs/en/writing-running-appium/caps/

Run through the following steps:
Create emulator with google APIs Intel x86
Root the emulator, by running the command:
adb root
Run the following shell command through adb:
adb -e shell "su root; setprop persist.sys.locale pt-PT; stop; sleep 2; start”
then, exit the shell which restarts the emulator.
Locales we need for screenshots:
de_DE
en_EN
fr_FR
ko_KO
pt_PT
es_ES
ja_JA

This is all over the place, to put it simply
setprop will only work on an AVD or a rooted physical device
The alternative is to use the settings in the Launcher.
Rooted device or AVD this works:
<android-sdk path>/platform-tools/adb shell
root#generic:/ # getprop persist.sys.language
getprop persist.sys.language
en
root#generic:/ # setprop persist.sys.language fr
setprop persist.sys.language fr
root#generic:/ # setprop persist.sys.country CA
setprop persist.sys.country CA
root#generic:/ # stop
stop
root#generic:/ # start
start
root#generic:/ # sleep 5
sleep 5
root#generic:/ # getprop |grep lang
getprop |grep lang
[persist.sys.language]: [fr]
root#generic:/ # getprop |grep country
getprop |grep country
[persist.sys.country]: [CA]
root#generic:/ #

Try this
adb shell "su -c 'setprop persist.sys.language fr; setprop persist.sys.country CA; stop; sleep 5; start'
You need a rooted device.

To set the language to US English, run the following command in the terminal:
adb shell "setprop persist.sys.locale en-US; setprop ctl.restart zygote"
To change to other languages, refer this list of languages:
https://developers.google.com/interactive-media-ads/docs/sdks/android/client-side/localization#locale-codes

On Emulator:
When changed language manually, it stopped working and had to do wipe data of Emulator in AVD manager to make it work again.
And the script used:
adb shell "su 0 setprop persist.sys.locale ja";adb shell "su 0 setprop ctl.restart zygote"
May add ;sleep 20 in the end if some commands in script below this command depend on device to be ready.

According to official documents:
To change the locale in the emulator by using the adb shell.
Pick the locale you want to test and determine its BCP-47 language tag, for example, Canadian French would be fr-CA.
Launch an emulator.
From a command-line shell on the host computer, run the following command:
adb shell
or if you have a device attached, specify that you want the emulator by adding the -e option:
adb -e shell
At the adb shell prompt (#), run this command:
setprop persist.sys.locale [BCP-47 language tag];stop;sleep 5;start
Replace bracketed sections with the appropriate codes from Step 1.
For instance, to test in Canadian French:
setprop persist.sys.locale fr-CA;stop;sleep 5;start
This causes the emulator to restart. (It looks like a full reboot, but it isn't.) Once the Home screen appears again, re-launch your app, and the app launches with the new locale.

In case this helps someone: I changed my phone's language to something buggy called en-XA (it was called English one in the UI I believe?) by mistake, and I couldn't even unlock the screen, but I had to fix my language settings somehow. I had no root access, but I had a custom recovery (TWRP) flashed fortunately.
The solution for me was to edit the /data/system/users/0/settings_system.xml file, this line in particular:
<setting id="24885" name="system_locales" value="en-XA,pl-PL" package="android" defaultValue="en-XA,pl-PL" defaultSysSet="true" preserve_in_restore="true" />
I changed the en-XA to en-US, rebooted, and the phone works again!
You can edit the file using your recovery's built-in file editor or use /adb pull /data/system/users/0/settings_system.xml to download and edit the file locally, then adb push settings_system.xml /data/system/users/0/settings_system.xml to update it on the device.
BTW I also changed the en-XA to en-US in the /data/property/persistent_properties file before and it didn't work alone, but perhaps both are needed.
Everything tested on a clean Android 11 device.

For Android M or newer, you need use:
setprop ro.product.locale xx-XX
setprop persist.sys.locale xx-XX
xx is language, XX is country

The solution to do it without rooting.
You can use something like this the below function.
The function goes into settings and exercises the UI to change the locale settings.
https://github.com/dtmilano/AndroidViewClient/blob/480ab93dbd01296a68c1ce7109ceb8275d1ed8a7/src/com/dtmilano/android/viewclient.py#L1302
The tricky part is to get to the right language when you are in a different language. You would think the language always maintain the same index in the list, but unfortunately not. So you have to have a solution like this.
Con: You my have to tweak it a little for handling different phones, the settings may have a different order.

The solution for API 28+ is
adb shell am broadcast -a com.android.intent.action.SET_LOCALE --es com.android.intent.extra.LOCALE "en_US" com.android.customlocale2

You cant do that with the adb on your device. Your adb outside the device, I mean on your computer connected with usb, can change it with passing a permission before changing the language.
On your device directly, you need a rooted device.

Related

Android skip chrome welcome screen using adb

I am trying to skip the chrome welcome screen when running tests. The problem is other solutions that I have found like this one don't seem to work anymore.
Commands used:
$ adb shell pm clear com.android.chrome
$ adb shell 'echo "chrome --disable-fre --no-default-browser-check --no-first-run" > /data/local/tmp/chrome-command-line'
$ adb shell am start -n com.android.chrome/com.google.android.apps.chrome.Main
The solution for me was actually a combination of the question and this answer. The solution can also be found in another question/answer, though it's not entirely clear.
The following should work:
$ adb shell am set-debug-app --persistent com.android.chrome
$ adb shell 'echo "chrome --disable-fre --no-default-browser-check --no-first-run" > /data/local/tmp/chrome-command-line'
$ adb shell am start -n com.android.chrome/com.google.android.apps.chrome.Main
Some notes:
In the Chromium project documentation, it's mentioned that for the command line file to be used, the user should
"Enable command line on non-rooted devices" in chrome://flags
Setting Chrome as the debug application replaces this requirement.
In older device versions, the command line file was expected in /data/local. This folder is no longer writable from adb shell in non-rooted devices, so /data/local/tmp should be used instead. This is documented in this bug
In the ChromeSwitches.java current source code, only --disable-fre still exists. The other flags might be required in older Chrome versions, but I didn't verify.
What is your OS version? It is working on Android 10. You can try the below commands:
$ adb shell pm clear com.android.chrome
$ adb shell am set-debug-app --persistent com.android.chrome
$ adb shell am start -n com.android.chrome/com.google.android.apps.chrome.Main

How do I run "adb shell" commands in a terminal emulator locally on an Android device?

From a shell on my PC, I can run adb shell cmd package list packages, and get a list of all installed packages. I would like to run this and similar commands locally on my Android phone (Nexus 6P) in a terminal emulator (currently using Termux).
If I open the same shell with /system/bin/sh, and then try to run /system/bin/cmd package list packages, nothing happens (no errors, just outputs nothing and reloads the prompt).
If I run /system/bin/cmd -l the list of options appears as expected. $PATH and $LD_LIBRARY_PATH are the same in both environments. One major difference is that echo $USER returns "shell" from adb shell, but returns my local username from /system/bin/sh launched from Termux.
Is there any way to replicate the behavior of commands run from adb shell in a terminal emulator locally on Android?
Edit:
My device is rooted, and I am OK with root only solutions.
The problem is Termux. By design, Termux runs only (or is mostly?) the Linux command line programs that you install from within Termux using apt or the newer "native" package management interface, e.g. apt install bsdtar. What you need to run the adb shell commands is a terminal emulator that can truly access the underlying Android file system, not just the Termux that is practically a chroot save for the fact that it's aware it's not running commands from the filesystem root /.
As a simple test, run the following command:
which ls
It should return something like /system/bin/ls. But if it returns something like /data/data/com.termux/files/usr/bin/applets/ls then you have to change your terminal emulator to something else. I suspect that Termux was designed to take into account the more restrictive shell execution policies that Google put into place after KitKat or the Android 4.X.
The Android distribution I'm using, LineageOS 14.1, comes with a built-in shell emulator that allows me to run commands found in /system/bin/ls.
I don't have a rooted Nougat device handy, but something like the following may be a close enough approximation to adb shell (assuming you are using SuperSU):
env -i USER=shell "$(PATH=/system/xbin:/system/bin:/su/bin:/sbin:/magisk/.core/bin which su)" shell --context u:r:shell:s0 --shell /system/bin/sh --command COMMAND
I (very briefly) tested it from Termux on a rooted Marshmallow device.
To elaborate:
the -i flag is used to start with an empty environment
USER=shell isn't specifically required, but for some reason su refuses to run with a completely empty environment
$(PATH=/system/xbin:/system/bin:/su/bin:/sbin:/magisk/.core/bin which su) points to the full path of the su binary on your device and can be hardcoded if you prefer
shell instructs the su binary to login as the shell user (the same as adb shell)
--context u:r:shell:s0 sets the appropriate SELinux context
--shell /system/bin/sh instructs SuperSU to use the system shell rather than it's own sush shell
Another option would be to actually run adb from the device, connecting to itself over TCP. If you need some functionality that is only available via adb (e.g. in my case it was adb forward) then this may be your only option. Unfortunately this isn't particularly convenient.
I wasn't able to find success with any publicly available adb binaries, so I build it myself with a few minor changes. You can see the sources I used and the changes I made at https://github.com/shakalaca/fastboot-adb-android and https://github.com/brbsix/fastboot-adb-android, respectively.
Once you have adb installed, here's an abbreviated list of commands I used to connect to the device:
# Add iptables rules to block external connections to port 9999'
su root iptables -N adbd
su root iptables -A adbd -i lo -p tcp -m tcp --dport 9999 -j ACCEPT
su root iptables -A adbd -p tcp -m tcp --dport 9999 -j DROP
su root iptables -A INPUT -j adbd
# Necessary in order to display authorization prompt
su shell setprop ro.debuggable 1
su shell setprop service.adb.tcp.port 9999
su root start adbd
adb connect 127.0.0.1:9999
adb wait-for-local-device
To shut down:
adb kill-server
su root stop adbd
su shell setprop ro.debuggable 0
su shell setprop service.adb.tcp.port 0
su root iptables -D INPUT -j adbd
su root iptables -F adbd
su root iptables -X adbd
So I tried this recently...if you're rooted you can use a terminal emulator.
su
then the command you want without "adb shell" part of it.
i tried the command "adb shell dumpsys deviceidle force-idle" in order to force device into doze.
I did this on the device via terminal emulator as:
"dumpsys deviceidle force-idle" and it did take effect.
also the dumpsys batterystats command worked.
be careful with commands with extensive text output, as the screen will be flooded with the output and will be unresponsive for some time.
EDIT
I originally answered this without the termux tag in mind. This worked for me while trying to execute shell commands on a vanilla emulator and saw this question while researching, so I tried to answer it differently.
You almost had it there in your question. You only need to execute sh:
int result = -1;
try {
final Process shell = Runtime.getRuntime().exec("sh");
final DataOutputStream commands = new DataOutputStream(shell.getOutputStream());
commands.writeBytes("write a series");
commands.writeBytes("of commands here");
commands.writeBytes("exit\n");
commands.flush();
result = shell.waitFor();
}
} catch (Exception e) {
e.printStackTrace();
}
If result == 0 the commands were succesful, else otherwise
Only rooted android
Busybox must be installed (though you can try without it)
Just write the normal command without the prefix adb

Android: How can I get device hardware information with adb command?

I would like to know how to retrieve specific hardware information, for example, from the camera, using an adb command. I would like to know if its possible to retrieve hardware ID or Physical device object name for example, to store these values.
Sdk:
adb shell getprop ro.build.version.sdk
Complete list:
adb shell getprop
Through the package manager:
adb shell pm list features
To retrieve detailed information about the camera
adb shell dumpsys media.camera
adb shell getprop
replace x with the prop. you want

Have aliases in adb shell non-interactive mode

Hi I need to run things in the form of adb shell <command>
When I test everything out inside adb shell, it works because I was able to set some aliases in .bashrc.
However, when I do adb shell <command>, nothing works because .bashrc is not used when you run adb shell <command>, because it's in the non-interactive mode.
How can I work around this? Can I adb push some files to the filesystem so that the alias will be there when adb shell is run?
If your android device is rooted you can add your aliases for adb shell into the /system/etc/mkshrc file.
One way to do this is to issue several shell commands in a single ADB command. You can put them in a string, and separate them with semicolons, thus:
adb shell "alias foo bar ; export MY_VARIABLE=/path/to/somewhere ; my_executable "
The " are crucial here, make sure they are paired up correctly. You could run your .bashrc this way, thus:
adb shell "source /path/to/.bashrc ; my_executable"
You can write a bash script that sets the aliases and then executes your shell:
#!/usr/bin/bash
. $HOME/.bashrc
adb shell $#

How to restart adb from root to user mode?

Basic question on ADB.
adb root restarts adb as root. But what i want is to restart it back to user after some time.
I tried the following :
adb kill-server
adb start-server
doesnt work..
ps -A -> noted the process number of adb and killed it.. even this did not work. Finally i am restarting my device. Is there any way i can come back from root adb to general adb?
Thank you.
If you used adb root, you would have got the following message:
C:\>adb root
* daemon not running. starting it now on port 5037 *
* daemon started successfully *
restarting adbd as root
To get out of the root mode, you can use:
C:\>adb unroot
restarting adbd as non root
adb kill-server and adb start-server only control the adb daemon on the PC side. You need to restart adbd daemon on the device itself after reverting the service.adb.root property change done by adb root:
~$ adb shell id
uid=2000(shell) gid=2000(shell)
~$ adb root
restarting adbd as root
~$ adb shell id
uid=0(root) gid=0(root)
~$ adb shell 'setprop service.adb.root 0; setprop ctl.restart adbd'
~$ adb shell id
uid=2000(shell) gid=2000(shell)
Try this to make sure you get your shell back:
enter adb shell (root). Then type below comamnd.
stop adbd && setprop service.adb.root 0 && start adbd &
This command will stop adbd, then setprop service.adb.root 0 if adbd has been successfully stopped, and finally restart adbd should the .root property have successfully been set to 0. And all this will be done in the background thanks to the last &.
I would like to add a little more explanation to #user837048's answer. on my OSX Yosemite and Galaxy S3 which is rooted and using firmware CyanogenMod 11 and KitKat I have done the below proceedings to Enable and Disable root prompt.
Please make ensure below
On your system
Make sure you have installed Android SDK and you have set paths to binary files. type which adb on your shell. It must give you somewhat result.
$ which adb
/Applications/Android Studio.app/sdk/platform-tools/adb
On your Mobile
Settings > Developer Options> Android Debugging = ON
Settings > Developer Options> Root Access = Apps and ADB
If you don't see Developer Options in your settings, Goto Settings > About Phone. Scroll down to Build number and tap there 7 times. I know its crazy. But believe me it works :D
Connect your phone via USB Cable.
type on your computer's terminal
$ adb shell
you will see a prompt similiar, If any prompt has been shown on your mobile, to trust the connection, tap 'Always Trust' and 'OK'
shell#m0:/ $
now type
shell#m0:/ $ id
uid=2000(shell) gid=2000(shell) groups=1004(input),1007(log),1011(adb),1015(sdcard_rw),1028(sdcard_r),3001(net_bt_admin),3002(net_bt),3003(inet),3006(net_bw_stats) context=u:r:shell:s0
See you are not root
Now exit from shell, which will fall back to computer's prompt
shell#m0:/ $ exit
Now activate root
$adb shell
* daemon not running. starting it now on port 5037 *
* daemon started successfully *
root#m0:/ #
Wow.. you are root
root#m0:/ # id
uid=0(root) gid=0(root) context=u:r:shell:s0
I tried many solutions to go back to normal non root prompt. But didn't worked except #user837048's solution.
root#m0:/ # stop adbd && setprop service.adb.root 0 && start adbd &
[1] 32137
root#m0:/ #
$
This might exit you from Adb prompt to normal prompt. Now connect again.
$ adb shell
shell#m0:/ $
Well.. You are Non root
For quick steps just check summary. If interested to know details, go on to read below.
adb is a daemon. Doing ps adb we can see its process.
shell#grouper:/ $ ps adb
USER PID PPID VSIZE RSS WCHAN PC NAME
shell 133 1 4636 212 ffffffff 00000000 S /sbin/adbd
I just checked what additional property variables it is using when adb is running as root and user.
adb user mode :
shell#grouper:/ $ getprop | grep adb
[init.svc.adbd]: [running]
[persist.sys.usb.config]: [mtp,adb]
[ro.adb.secure]: [1]
[sys.usb.config]: [mtp,adb]
[sys.usb.state]: [mtp,adb]
adb root mode :
shell#grouper:/ # getprop | grep adb
[init.svc.adbd]: [running]
[persist.sys.usb.config]: [mtp,adb]
[ro.adb.secure]: [1]
[service.adb.root]: [1]
[sys.usb.config]: [mtp,adb]
[sys.usb.state]: [mtp,adb]
We can see that service.adb.root is a new prop variable that came up when we did adb root.
So, to change back adb to user from root, I went ahead and made this 0
setprop service.adb.root 0
But this did not change anything.
Then I went ahead and killed the process (with an intention to restart the process). The pid of adbd process in my device is 133
kill -9 133
I exited from shell automatically after I had killed the process.
I did adb shell again it was in user mode.
SUMMARY :
So, we have 3 very simple steps.
Enter adb shell as a root.
setprop service.adb.root 0
kill -9 (pid of adbd)
After these steps just re-enter the shell with adb shell and you are back on your device as a user.
This is a very common issue.
One solution is to kill adb server and restart it through command prompt. Sometimes this may not help out.
Just go to Window Task Manager to kill adb process and restart Eclipse.
Will work perfect :)
i've been with this issue using elementary OS loki. For like one day and i solved it restarting the adb using this command:
./adb kill-server
and
./adb start-server
You need to be in the Sdk folder >Platform Tools
Now, restart your phone this will restart all the process in your phone.
And that's how i fixed it.
if you cannot access data folder on Android Device Monitor
cmd
C:\Users\bscis\AppData\Local\Android\sdk\platform-tools
(Where you located sdk folder)
C:\Users\bscis\AppData\Local\Android\sdk\platform-tools>adb shell
generic_x86:/ $
C:\Users\bscis\AppData\Local\Android\sdk\platform-tools>adb kill-server
C:\Users\bscis\AppData\Local\Android\sdk\platform-tools>adb start-server
* daemon not running. starting it now at tcp:5037 *
* daemon started successfully *
C:\Users\bscis\AppData\Local\Android\sdk\platform-tools>adb root
C:\Users\bscis\AppData\Local\Android\sdk\platform-tools>
working fine.....

Categories

Resources