How to use adb socket to get the result from the phone? - android

I have written an executable file, and push it into /system/bin.
After run the file, it will give a result in float.
Now on PC side, I want to get this result.
At first I write this float number into a file and use 'adb pull' to pull this file, then read file.
Because I need to do this operation frequently, may 2 times per sec. This cause bad performance of the phone.
Wheather it will be little influence when I use adb socket?
Where my executable file should output?
How adb socket get the result?
Thanks.
James.

If you're leaving the phone connected, you could probably just do
adb shell /system/bin/myexecutable
and just have your binary print its output to stdout. As long as your program runs quickly, twice per second shouldn't be too fast. Otherwise, you could do
adb shell cat /somewhere/myoutfile
to see what's in a file currently.

You could potentially use logcat as a medium for getting data from your Android app to your desktop machine provided there is an ADB connection available.
My thinking is that there are two pieces:
Log your app output with logcat to a unique TAG on the Android side. For example,
Log.d("MyAppOutput", "This is the output I am looking for");
On the desktop side, you could run a command line that looks specifically for that TAG, something like:
adb logcat -s MyAppOutput
I believe this would allow you to read the results from the Android app in near realtime. If you need to know the timestamp of the log message, you could add the -v time parameter to prefix each message with a timestamp.

I had the same question before, you don't need output result to file, just output your result to a socket port, and use adb forward to get the result on your pc by adb socket. this is what you need solution.
adb forward tcp:18000 tcp:19000
this command means,pc's tcp port 18000 bind to device's tcp port 19000, if you send data to 18000 port on pc, you can get data from 19000 on device.vice versa.

Related

Is there a way to programatically check for used ports without looping?

I'm familiar with couple of methods to check for used ports on Android.
Loop over all possible ports, try creating a socket on each port, if socket creation fails port is used.
Use netstat command from shell which will list all open connections and used ports can be parsed from there.
Use cat /proc/net/tcp command from shell which is similar as netstat command.
Problem with 1st option is that looping over all possible ports is taking too much time, it's not efficient enough if I want to make sure that I'm getting all open ports.
Problem with 2nd and 3rd option is that (on non-rooted device) although shell command can be executed in shell (adb shell) and output is clearly seen, while trying to execute command from Java code in Android application, command output is empty string for cat /proc/net/tcp and only header is outputted from netstat command. I'm guessing that the problem are application permissions which are insufficient to run above commands.
Is there any other way of checking for used ports or am I doing something wrong by using commands from option 2 or 3?
EDIT:
To clarify, while using any command that should list connection info from adb shell this will work fine. However, if I'm trying to invoke any of the commands (same syntax as in adb shell) from my application's Java code, output of the command is empty string.
To get the process I tried using:
Runtime.getRuntime().exec(command);
new ProcessBuilder().command("sh", "-c", command).start();
E.g. output of netstat command (with any arguments) is as following:
Active Internet connections (only servers) Proto Recv-Q Send-Q Local Address Foreign Address State Active UNIX domain sockets (only servers) Proto RefCnt Flags Type State I-Node Path
How about:
netstat -ln | awk '/^tcp/ { split($4,arr,":");prts[arr[2]]="" } END { for (i in prts) { print i } }'
Take the netstat output and then using awk, concentrate on all lines beginning with tcp. Then split the 4th delimited field into a array called arr based on ":" as the delimiter. Put the second index of the array (port number) in another array prts as the index. At the end, loop through the prts array and print the indexes (ports)

Is bash redirection of file descriptor 3 the most efficient way to read a tcp port and write to a text file?

I am logging GPS data on a Raspberry Pi (Raspbian OS) by forwarding text from an Android phone connected by USB. The app ShareGPS correctly dumps several lines of text every second to port 50000. On the Pi I run adb to forward the port to the Pi.
From there I redirect the socket using a pseudo path to a file descriptor and then redirect the descriptor to a text file.
adb forward tcp:50000 tcp:50000
exec 3<>/dev/tcp/localhost/50000
cat &3 >> dump-file.txt
To me this seems a very convoluted route. Is there a more efficient way record from a port on the phone to a text file on the Pi?
Phone setup and adb reference http://ubuntuforums.org/showthread.php?t=2145434
Socket redirection http://hacktux.com/bash/socket
If you don't need back-and-forth communications, you don't have to open a separate FD:
cat < /dev/tcp/localhost/50000 > dump-file.txt
One way or another, there will need to be a process that listens to the port and writes to the file as there is no built-in O/S function to do so.
So, really, there isn't going to be a more efficient way to run that. You might be able to save some startup cost by turning the script into a program, but I wouldn't bother - the savings will be tiny.

Streaming file from android sdcard to windows host machine

I have a file on the sdcard which is being written to by an app constantly, I need to pull the file from the device as it is being written to by the app, onto my windows host machine for further analysis.
adb pull is no good as it pulls the whole file then stops, but of course the file is still being written too. And anyway the file gets very big so i don't want to copy the whole file each time, just the parts that have been written to since i last read it.
adb shell dd might be an option but i can only get it to copy from one file on the sdcard to another file on the sdcard, i.e. not my windows machine:
e.g. adb shell dd if=/sdcard/input.pcm of=/sdcard/output.pcm then use skip and seek dd options.
if i used dd and a pipe:: adb shell dd if=/sdcard/input.pcm > output.pcm the output file has some corruption: 0x0D, 0x0D is added randomly to the pcm data. Same as if I just do adb shell cat input.pcm.
I also thought about writing the data to logcat and parsing it, but this is rather clunky and messy and there is a ton of data.
Another option might be splitting the file up in to lots of small files as they are being written and then using adb pull.
None of these are ideal. Ideally i'd like a program on the host that can pull the data at my control, e.g fopen, fread, etc. But I am not sure if this is possible.
Can anyone suggest how I might be able to fulfill my requirements:
Read all the file that's available to windows host
Read the parts of the file that have been updated since i last did a read (e.g every 100ms)
Many thanks in advance.
I think it is your specific requirement, so it doesn't matter to modify the source code of Android.
Why don't you implement another adb command? Then you can record the last read position and use adb newcommand filename to incrementally pull out the file.
The implementation of adb can be divided into two parts: host side, and adbd.
In host side, when you type a command, it goes to adb_commandline() in commandline.c.
if(!strcmp(argv[0], "pull")) {
if (argc == 2) {
return do_sync_pull(argv[1], ".");
} else if (argc == 3) {
return do_sync_pull(argv[1], argv[2]);
} else {
return usage();
}
}
Then the do_sync_pull continously communicate with the adbd. The adbd(adb.c) listens to the request sent from the host side.
A simple approach is to add another argument to the do_sync_pull, and let the adbd continously seek the file and send back the file content.

ADB shell script to send AT commands to a modem-cannot return control to a shell and capture output

I already posted similar question, but still could not get my job done, so this a a second attempt, where
I would like to more clearly state my stumbling block.
So basically I am in Android phone's adb shell, communicating with the GPRS modem by sending AT commands.
I am able to do it by redirecting at command to the device file representing the modem; and I can read back
the response using cat utility running on the background (started earlier). I implemented it in a script
which can send a single AT command and read back the response. For example, here is the script to
send at+cops? to get the name of the operator the mobile is camping on:
#SendATCommand script
cat /dev/pts/7 &
echo -e at+cops?\\r > /dev/pts/7
The output looks as follows:
# ./sendATCommand
./sendATCommand
#
+COPS: 0,0,"AT&T",6
OK
/dev/pts/7: invalid length
Now here are two problems which I cannot resolve:
I still need to manually press ENTER button to get back adb shell prompt "#". Is there a way to return
to "#" prompt programmatically? Again, I am in adb shell.
The displayed response cannot be captured, neither in a variable, nor in file, (such as(#./sendATCommand > output.txt) Output.txt file will be empty. I tried various redirections, but still did not get it to work.
Can anyone please help me resolve those two problems (if ever possible)? Ultimately I want this little script to be
called from a "super" script (e.g. Perl or Powershell) running on PC to which my Android device is
connected, but there is no way to do it until those two problems resolved. Thanks a lot in advance!
I suggest that you try out my atinout program which should be exactly what you are asking for: a program to send AT commands from the command line and capture the output.
In your case the result should be like
$ echo 'at+cops?' | atinout - /dev/pts/7 -
+COPS: 0,0,"AT&T",6
OK
$
and to capture the output just put a file name instead of the last -.
I had similar problems with redirecting output to file. I resolved my problem by adding CMD /c in front of the echo command. I.e. if I understand correctly you need to tell the system that it needs to wait until command finishes executing and only then redirect output to a file. I was doing it in DOS.
Since you are running on ANDROID try adding sh -c in front of your command. Hope it helps.

wrong usage of BufferedReader

s=new Scanner(new BufferedReader(new InputStreamReader(this.clientSocket.getInputStream())));
while(s.hasNext()){
System.out.println("Am intrat in bucla s:");
longitude=Integer.parseInt(s.next());
System.out.println("Valoare longitudine:"+longitude);
latitude=Integer.parseInt(s.next());
System.out.println(latitude);
I'm using the lines above to read some data from a client-server connection;this is the server side.The data are read in scanner s and after that I try to display it,but when I look in logcat I have nothing display but this exception:
04-18 00:07:56.138: INFO/global(295):
Default buffer size used in
BufferedReader constructor. It would
be better to be explicit if an 8k-char
buffer is required.
Both my client and server are on android!Does anyone have any idea what I'm doing wrong?
This is how I read the data,I send latitude and longitude,I assume that is blank spaces delimited,the strange thing is that sometimes is working:
Cursor c=db.getAllData();
if(c.moveToFirst())
{
do{
longitude=Integer.parseInt(c.getString(1));
out.println(longitude);
latitude=Integer.parseInt(c.getString(2));
out.println(latitude);
}while(c.moveToNext());
}
The message seems to be for the BufferedReader construct.
First, I do not think you are doing anything "wrong", since you are saying that the code works as expected and the message is "INFO", not "ERROR" or even "WARNING".
Second, if you look at the BufferedReader constructor, you will see:
BufferedReader(Reader in, int size)
Constructs a new BufferedReader, providing in with size characters of buffer.
http://developer.android.com/reference/java/io/BufferedReader.html
Use that constructor instead and you should not see that message.
BTW, the logcat is full of output, some lines are more relevant than others.
Use Log.d instead of System.out.println(). Regarding System.out: http://developer.android.com/guide/developing/tools/adb.html
Viewing stdout and stderr
By default, the Android system sends
stdout and stderr (System.out and
System.err) output to /dev/null. In
processes that run the Dalvik VM, you
can have the system write a copy of
the output to the log file. In this
case, the system writes the messages
to the log using the log tags stdout
and stderr, both with priority I.
To route the output in this way, you
stop a running emulator/device
instance and then use the shell
command setprop to enable the
redirection of output. Here's how you
do it:
$ adb shell stop $ adb shell setprop
log.redirect-stdio true $ adb shell
start
The system retains this setting until
you terminate the emulator/device
instance. To use the setting as a
default on the emulator/device
instance, you can add an entry to
/data/local.prop on the device.
Is your data white-space delimited? If not, you will need to specify delimiter for your Scanner.
Do you have some exception handling code you are not showing... e.g. hiding a NumberFormatException if parseInt failed?
While you debug this issue (unless you can attach a debugger), you could log messages at points like when you accept new client connection and when you enter and exit your worker thread. This might help you see whether you are getting as far as scanning the data when you think you are receiving.

Categories

Resources