Streaming file from android sdcard to windows host machine - android

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.

Related

How to use a file of fixed size to measure the bandwidth using iPerf?

I am trying to use iPerf to measure the performance of my network which is android-base and all my nodes (i.e.:phones) are rooted.
I've created a file of size 1 MB using the following command in Linux:
dd if=/dev/zero of=testFile bs=1k count=1000
Now, on iPerf, I am trying to use "-F" option like this:
-c serverIp -F testFile
to:
"read from the file and write to the network, instead of using random data"
However, the iperf is showing me the following error:
unable to open the file stream, will use the default data stream
My question is how to use a file of fixed size to measure the bandwidth using iPerf ?
That sequence of commands succeeded for me on a Linux machine. Are you sure that your file creation was successful? Can you cat the file you created and check its permissions with ls -l?
If you don't need to send a specific file, you can pass -n <number of bytes> to iperf to specify the amount of data to transfer.

Make adb monitor for an intent?

Like the headline suggestes I would like to make adb wait for an intent, is that possible?
I have an app that writes a file to filesystem and I would like to pull it with adb once its done, problem is I dont know how long it will take on each device.
Is there a way to make adb wait for an activity to close or wait for an intent?
Or maybe someone has a better idea of how to achieve what I want to do?
I have read through all of the pm and am API and there doesnt seem to be anything useful in there.
Thanks!
I don't think there is a way to wait intent by using adb.
How about using tmp file to check file writing completed?
from your app, create completed.trx file if target file writing completed
write simple scripts to check completed.trx file (routinely) by using adb shell command
if completed.trx exist, get written file by adb pull and delete completed.trx file by adb shell

Receive ADB status events in Android app

I am transfering files to an android device using adb push. I am able to push the files to the SD card, and the commandline tells me the transfer rate, file size, and time elapsed, e.g:
C:\Users\some_guy\Pictures>adb -d push wilford.jpg /sdcard/wilford.jpg
2558 KB/s (13104 bytes in 0.005s)
I'm looking to create an app or service that can subscribe to events through a broadcast receiver to get updates on when the adb push starts, finishes, and includes the current file transfer rate while the transfer is in progress. So, as the file gets written from adb, it would notify my applicatoin of its current % complete and transfer rate. Is this possible? What permissions are required and how would the application subscribe to the updates? I've looked around at the list of permissions and other resources and can't figure out a way to do this.
Another possibility would be to simply monitor the SD card file system for incoming files, but I'm not sure what that would give me beyond monitoring when new files are written fully.
I had a very similar issue a while back, and I believe I exhausted all options to no avail. There's no broadcast as part of the adb push process. However, you can create your own broadcasts before and after each push using adb shell am broadcast ... and even send extras (such as filename or transfer rate).
This will be easier if you use bash or python to script your adb transfers, rather than windows batch files -- I wound up using the jython implementation for MonkeyRunner included with the SDK tools, and only had to drop out to the shell to do the actual file push, as MonkeyRunner doesn't provide that.
You can detect at least the creation of new files using the Linux kernel inotify mechanism on the target directory.
Android exposes this functionality through the FileObserver class:
Monitors files (using inotify) to fire an event after files are accessed or changed by by any process on the device (including this one). FileObserver is an abstract class; subclasses must implement the event handler onEvent(int, String).
Each FileObserver instance monitors a single file or directory. If a directory is monitored, events will be triggered for all files and subdirectories inside the monitored directory.
see http://developer.android.com/reference/android/os/FileObserver.html
Note that the mechanism is not recursive in that monitoring a directory monitors only entires in that directory, not entries in its subdirectories. This question discusses some recursive possibilities.

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

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.

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.

Categories

Resources