wrong usage of BufferedReader - android

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.

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)

Complete terminal control on android

I have been trying to run a few Linux commands on my android phone with
Process process = Runtime.getRuntime().exec(COMMAND);
BufferedReader in = new BufferedReader(new InputStreamReader(process.getInputStream()));
And noticed that I can only run specific commands and get the proper output even if the device is rooted with SuperSU (I have also tested it with a device without SuperSU on it).
For example, if I run ls and try to put it on a screen (through a TextView) as follows:
public void onBtnClick(View view) {
try {
EditText commandLine = findViewById(R.id.commandText);
Process process = Runtime.getRuntime().exec(commandLine.getText().toString());
BufferedReader in = new BufferedReader(new InputStreamReader(process.getInputStream()));
((TextView) findViewById(R.id.mainTextView)).setText(((TextView) findViewById(R.id.mainTextView)).getText() + "\n" + in.readLine());
commandLine.setText("");
} catch (IOException e) {
e.printStackTrace();
}
}
the output is acct which makes sense.
But on the other hand, if lets say I run pwd it gives me the following error:
W/System.err: java.io.IOException: Error running exec(). Command:
[pwd] Working Directory: null Environment: null
I did some research online and stumbled upon Termux that can have complete control over the phone through a terminal which is exactly what I'm looking to make (for my own learning and testing purposes).
And although it's just an emulator it can do exactly what I want but the only problem is that it requires I input the commands through the terminal.
What I'm here for is to sort of replicate what Termux does for myself so that I could run Linux commands properly from the Java code of the application, not requiring the user to actually input commands.
Can anyone help me with where to start and the basics of running those commands properly on my device?
Termux states that it doesn't work as a traditional Linux bash does since it sets its own virtual-ish environment when first setting up in its data directory in /data/data/com.termux/files/usr see here and here
Also, according to the official android docs, the exec(command) method,
Executes the specified string command in a separate process.
This is a convenience method. An invocation of the form exec(command)
behaves in exactly the same way as the invocation exec(command, null,
null).
So if it's a separate process, when executing a command, it will run it inside that process' directory (Each process in Linux gets its directory and is assigned an PID which os uses). So what the ls command gives you is simply whatever's inside that process' directory. You should be somewhere like /proc/31415/ and there's only a acct file (cgroup in regular Linux).
What you should be doing is running the command inside a directory by declaring it when invoking getRuntime().exec() see the link above to find the right one you'll need. I'd suggest using the override which handles all the parameters.
You'll need something like this:
String[] cmd = {"mkdir", "testDir"};
File env = new File(getFilesDir().getAbsolutePath());
Runtime.getRuntime().exec(cmd, null, env);
Also, it doesn't hurt to take a look at Termux's installer code (exec(). It'll give you a good overlook to setting up your environment as well as working with basic commands.
Also, I think you've done it already but double check to make sure that you're requesting WRITE_EXTERNAL_STORAGE permission for your application.

Any way to grab a snapshot of current logcat output without opening up the output stream?

I'm trying to grab some filtered output from logcat through command line, but would prefer to not have a logcat stream opened up for automation purposes.
Here's my use case: I want to clear logcat, perform some instrumentation tests with AccessibilityChecks enabled, then check logcat for Accessibility errors that the class has found in my UI.
Currently, here's what I can do via command line:
//clear logcat history:
adb logcat -c
// Run instrumentation tests at this time.
// Run following command when tests done:
adb logcat AccessibilityValidator:E *:S
// ctrl-c to close stream
This does what it is supposed to. I will see just the Accessibility errors printed out. The problem is that I do not want to open up a logcat stream. I'd like to get the results as is, right at the point that my instrumentation tests have completed. Opening up a stream is not very ideal as I would then need to pipe in a ctrl-C to my pipeline to close the stream. I would really like to get a snapshot of the output in plain text. Is such a thing possible?
Thank you!
Edit: I was able to find what I believe is a working solution - I just needed to add the -d flag. This will not open a stream and will print the contents of the logcat file. Combine with my filtering, I am able to get exactly what I was looking for.
I was able to find what I believe is a working solution - I just needed to add the -d flag. -d will dump the logs and exit. This will not open a stream and will print the contents of the logcat file to stdout. Combine with my filtering, I am able to get exactly what I was looking for.
The command I needed is:
adb logcat -d AccessibilityValidator:E *:S

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.

Android Error Logging

How do i retrieve the error logs of my application from device (and send them over the internet to a server)?
(Assuming you are using log framework from android.util.Log package.)
You can start "logcat" process with specific parameters from within your process. It will dump last 16k of logs (16k - is default for my phone, it can be different on other phones).
Here is an example of command line that dumps all logs: logcat -d -f /mnt/sdcard/log-dump.txt
Another example that dumps errors from all applications: logcat -d -f /mnt/sdcard/err-dump.txt *:e
You'll need to launch the process from within your application programatically. And then process log-dump.txt/err-dump.txt in the way you want.
You also may want to monitor logs longer then those default 16k can allow you. For this you'll need to start logcat without -d parameter. If this is done, logcat process will write logs to file for as long as you want. When you are done just kill logcat process.
In any case you can look & test manually logcat using adb logcat <params> from you computer.
I think you need to implement the try_catch block.
try
{
}
catch(Exception e)
{
Log.e("Exception found ",e.getMessage);
// post the exception message to your server
}
This way you can send the error log messages to the server.

Categories

Resources