This question already has answers here:
Read binary stdout data like screencap data from adb shell?
(19 answers)
Closed 5 years ago.
When I use adb exec-out screencap -p in python commands.getstatusoutput or subprocess.call on my Macbook to get screenshot like bellow, I can get perfect png file bytes, but when running on Windows, I just get an cannot identify image file <_io.BytesIO object at 0x000002ADDDB49BF8> when Image.open()
def cmd(line, out_is_binary=False):
cmdline = line if isinstance(line, str) else ' '.join(line)
with tempfile.TemporaryFile() as stdout:
status = subprocess.call(line, stdout=stdout, stderr=stdout)
stdout.seek(0)
output = stdout.read()
output = str(output, 'utf-8') if not out_is_binary else output
output_log = output if not out_is_binary else '<binary data>'
print('"%s" returned %s, and says:%s%s' % (cmdline, status, os.linesep, output_log))
return status, output
def capture():
line = [ADB_BIN, 'exec-out', 'screencap', '-p']
status, output = cmd(line, out_is_binary=True)
if status:
raise RuntimeError('通过USB调试截屏失败')
fp = BytesIO(output)
return Image.open(fp)
PS: This question should not be the duplication of adb question. Because the point in this is the way to get a screenshot in a DAMMIT Windows CMD or Python in Windows.
finally I got the solution like bellow, if run on windows, use base64 to transfer data and then decode it in python
def capture():
line = [ADB_BIN, 'exec-out', 'screencap', '-p']
if os.name == 'nt':
line = [ADB_BIN, 'shell', 'screencap -p | base64']
status, output = cmd(line, out_is_binary=True)
if status:
raise RuntimeError('通过USB调试截屏失败')
if os.name == 'nt':
output = base64.decodebytes(output)
fp = BytesIO(output)
return Image.open(fp)
Related
I have a rooted Android 7 phone and I would like to dump unix input event files. Using adb I could do it using the following command:
adb shell getevent -t /dev/input/event7 > recorded_touch_events.txt
This will dump the event7 file into recorded_touch_events.txt. But this only works when the phone is connected by usb cable with the PC. Using Android I can dump files with the following code:
th = new Thread(new Runnable(){
private Process exec;
#Override
public void run() {
try {
exec = Runtime.getRuntime().exec(new String[]{"su","-c","getevent -t /dev/input/event7"});
InputStreamReader is = new InputStreamReader(
exec.getInputStream());
String s;
BufferedReader br = new BufferedReader(is);
while(((s = br.readLine()) != null) && run){
// write line to text file
}
is.close();
exec.destroy();
} catch (IOException e) {
e.printStackTrace();
}
}
In this way, I could store every read line in a text file.
Are there other approaches (probably faster ones) for directly dumping the event file?
getevent is used to print input events out in human readable form. For example during interactive debug session. You do not need to use getevent for just dumping or any other computer processing task. Just open and read the input file. The event record format is very simple.
Certainly No, you are doing it right.
I am copying a kernel executable through my app in my package folder in /data/data and trying to run it in android app using Instrumentation
I have tried ProcessBuilder and Runtime.getRuntime().exec as well both are showing Exit Code 1 and command does not run.
My command:
String command = "/data/data/<packageName>/e4crypt add_key -S 0x11112222333344445555666677778888 <<< "+key;
Process proc = Runtime.getRuntime().exec(command);
int i = proc.exitValue();
BufferedReader stdInputs = new BufferedReader(new InputStreamReader(proc.getInputStream()));
String line = "";
StringBuilder output = new StringBuilder();
while ((line = stdInputs.readLine()) != null) {
output.append(line);
}
How to format the long string? I have tried ProcessBuilder and Runtime.getRuntime().exec and UiDevice.getInstance(getInstrumentation()).executeShellCommand()
The first parameter is "add_key" Even when i run the executable with one parameter it shows Exitcode=1 and it does not run. Same command works fine from command window.
I suspect the command formatting is incorrect.
I have a SNMP agent in android.
I'm trying to recover the whole MIBTree with this python script:
from pysnmp.entity.rfc3413.oneliner import cmdgen
cmdGen = cmdgen.CommandGenerator()
errorIndication, errorStatus, errorIndex, \
varBinds = cmdGen.bulkCmd(
cmdgen.CommunityData('public', mpModel=0),
cmdgen.UdpTransportTarget(('192.168.0.90', 32150)),
0,
25,
(1,3,6,1,4,1,12619,1,1)
)
if errorIndication:
print(errorIndication)
elif errorStatus:
print('%s at %s' % (errorStatus.prettyPrint(),
errorIndex and varBinds[int(errorIndex) - 1][0] or '?'))
else:
for varBind in varBinds:
print(' = '.join([repr(x) for x in varBind]))
if I use the oid (1,3,6,1,4,1,12619,1,1) as the root oid, the output is this:
ObjectType(ObjectIdentity(ObjectName('1.3.6.1.4.1.12619.1.1.1.0')),OctetString('intel ICI101'))
ObjectType(ObjectIdentity(ObjectName('1.3.6.1.4.1.12619.1.1.2.0')),OctetString('4.4.4'))
ObjectType(ObjectIdentity(ObjectName('1.3.6.1.4.1.12619.1.1.3.0')), TimeTicks(10100333))
(ObjectIdentity(ObjectName('1.3.6.1.4.1.12619.1.2.1.0')), EndOfMibView())
It is working right. The problem is I want the whole MIB tree, so I want to use the root oid which is (1,3,6,1,4,1,12619,1). But the output using that OID is:
OIDs are not increasing
How can make this work?
ignoreNonIncreasingOid = True
adding that parameter as an option made it work.
varBinds = cmdGen.bulkCmd(
cmdgen.CommunityData('public', mpModel=0),
cmdgen.UdpTransportTarget(('192.168.0.90', 32150)),
0,
25,
(1,3,6,1,4,1,12619,1),
ignoreNonIncreasingOid = True
)
I am intermittently getting Too many open files exceptions when I try to write to a text file in my Xamarin / Android app.
I understand that this is because each Android app has a limit on the number of files it can have open, and obviously my app is exceeding it in some circumstances. Hence I must be leaving some files open / not disposing of them properly somewhere.
I would like to know if I can programatically list the files that my app has open at any given time? Obviously the operating system knows this, is it possible to do this from within my app? This will help me find the problem.
Thanks to fiddler, this is how I solved it in case anyone else needs to do it in the future (in C# / Xamarin):
private static List<string> m_commandData;
private static void GetOpenedFiles()
{
m_commandData = new List<string>();
RunCommand("lsof");
RunCommand("ps | grep TestNoFilesOpen");
}
private static void RunCommand(string command)
{
string data;
using (Java.Lang.Process process = Java.Lang.Runtime.GetRuntime().Exec(command))
{
Stream stream = process.InputStream;
StreamReader bodyReader = new StreamReader(stream);
data = bodyReader.ReadToEnd();
}
m_commandData.Add(data);
}
private static void WriteCommands()
{
for (int i = 0; i < m_commandData.Count; i++)
{
using (TextWriter tw = new StreamWriter(Android.OS.Environment.ExternalStorageDirectory.AbsolutePath + "/NoFilesOpen/adb_" + i.ToString() + ".txt"))
{
tw.Write(m_commandData[i]);
tw.Close();
}
}
m_commandData = new List<string>();
}
You could use the Unix lsof command in the ADB shell.
1) Start the shell:
$ adb shell
2) Find the process ID of your app:
shell#android:/ $ ps | grep <packagename>
3) List files opened by your app:
shell#android:/ $ lsof <pid>
I've implemented a service that listens to commands issued through ADB. An example of a command sent through ADB could look like this:
adb shell am startservice -a com.testandroid.SEND_SMS -e number 123123123 -e message "åäö"
Now, the problem here is that the encoding of the string "åäö" seems to mess up. If I take that string extras and immediately output it to the log, I get a square "[]", unknown character. If I send this message I get chinese characters in the messages app. As long as I stick to non-umlaut characters (ASCII I guess), everything works fine.
I'm using Windows 7 and the command line for this. I have not touched the encoding of the command line and I've tried to process the extras string by getting the byte characters, passing in UTF-8 as an encoding argument, then creating a new String passing in UTF-8 as an encoding argument there as well. No dice, though.
The values of the bytes, when using getBytes() are å: -27, ä: -92, ö: -74
How do I get this to play nice so I can make use of at least the umlauts?
All of this works perfectly fine in Linux.
i ran into the same issue, but finally i got it work!
if you use for example C#, you have to do it like the following example:
02.12.2019
According to the protocol.txt, the ADB-Protocol supports "smart-sockets". Those sockets can be used to do all the stuff, the ADB-Client inside the adb.exe does. For example if you want upload an file, you have to request such an "smart-socket". After that, you have to follow the protocol assigned to the service (for an service overview see SERVICE.txt) as described, for example, in the SYNC.txt.
13.10.2014
public static List<string> ExecuteBG(string exe, string args, int timeOut = -1)
{
if (File.Exists(exe) || exe == "cmd.exe")
{
ProcessStartInfo StartInfo = new ProcessStartInfo();
StartInfo.FileName = exe;
StartInfo.Arguments = Encoding.Default.GetString(Encoding.UTF8.GetBytes(args));
StartInfo.CreateNoWindow = true;
StartInfo.UseShellExecute = false;
StartInfo.RedirectStandardError = true;
StartInfo.RedirectStandardOutput = true;
StartInfo.StandardErrorEncoding = Encoding.UTF8;
StartInfo.StandardOutputEncoding = Encoding.UTF8;
AutoResetEvent errorWaitHandle = new AutoResetEvent(false);
AutoResetEvent outputWaitHandle = new AutoResetEvent(false);
List<string> response = new List<string>();
Process proc = new Process();
proc.StartInfo = StartInfo;
proc.ErrorDataReceived += (s, e) =>
{
if (String.IsNullOrEmpty(e.Data))
{
errorWaitHandle.Set();
}
else
{
response.Add(e.Data);
}
};
proc.OutputDataReceived += (s, e) =>
{
if (String.IsNullOrEmpty(e.Data))
{
outputWaitHandle.Set();
}
else
{
response.Add(e.Data);
}
};
proc.Start();
proc.BeginErrorReadLine();
proc.BeginOutputReadLine();
proc.WaitForExit(timeOut);
errorWaitHandle.WaitOne(timeOut);
outputWaitHandle.WaitOne(timeOut);
return response;
}
return new List<string>();
}
Really important is this part "StartInfo.Arguments = Encoding.Default.GetString(Encoding.UTF8.GetBytes(args));", here we convert the UTF8 string into the Windows "default" charset which is known by cmd. So we send a "destroyed" "default" encoded string to cmd and the Android shell will convert it back to UTF8. So we have the "umlauts" like "üöäÜÖÄàè etc.".
Hope this helps someone.
PS: If u need a working "Framework" which supports UTF8 push/pull for files/folders also have a look at my AndroidCtrl.dll it's C# .NET4 written.
Regards,
Sebastian
Concluding, either the problem is situated in cmd.exe or adb.exe. Until either one or both are updated to be more compliant with eachother I will sadly not be able to make use of this for the time being.