I am trying to write an app which reads the logs created by adb logcat. Following the code on link1 and link2, I have the following code:
try {
Process process = Runtime.getRuntime().exec("logcat");
System.out.println("Process : " + process); // shows process id
BufferedReader bufferedReader = new BufferedReader(
new InputStreamReader(process.getInputStream()));
System.out.println("Buffered reader : " + bufferedReader.readLine());
StringBuilder log = new StringBuilder();
String line;
while ((line = bufferedReader.readLine()) != null) {
log.append(line);
}
TextView tv = (TextView) findViewById(R.id.textView1);
tv.setText(log.toString());
} catch (IOException e) {
}
To test what the buffered reader is reading, I put a println, but I get a message "cannot bind tcp:5038". The above code does not read any logs. I also tried using "logcat *:V" but I did not get logs of even lowest priority.
I gave my app the permission: android.permission.READ_LOGS.
I am testing my code on Android emulator.
Can someone please point out what am I doing wrong.
Thanks for helping.
EDIT:
I tried "logcat -d" and I got one line of log. In the code, it can be observed that a try/catch block has been provided; when I remove the permission READ_LOGS from the app, no exception is raised and the bufferReader simply prints null (Usually when an app does not find a permission it requires, it raises an exception). What is the reason for this behavior ?
EDIT2:
I tried Log.d(TAG, log.toString()) and got more than one line of text. Can someone please explain the last question from the previous edit: when I remove the required permission, why is an exception not raised by the app ?
You are likely getting the message "cannot bind tcp:5038" due to not having
<uses-permission android:name="android.permission.INTERNET" />
in your manifest
You can never get the permission to read logs through Runtime.getRuntime().
The android dev team decided to stop granting these permissions to third-party apps. Only system apps can now get them.
More details:https://code.google.com/p/acra/issues/detail?id=100
Related
When I use adb to access my device (Android 4.4.2 straight from the manufactures with their custom rom - its not a regular device - it has built in 2D barcode scanner) it goes straight to having a # which I've read means I have root access. And if I run "id" I get the following:
uid=0(root) gid=0(root) context=u:r:adbd:s0
However, when I run "su" from within my app and then "id" I get the following:
uid=10079(u0_a79) gid=10079(u0_a79) groups=50079(all_a79) context=u:r:untrusted_app:s0n
So it's clearly not running as root.
Is my understanding all wrong, in believing that it should be running as root from within the app, or is there something else I need to do in order to get this working?
Any advice would be much appreciated.
Here is the code I'm currently using to run the su and id commands:
p = Runtime.getRuntime().exec("su");
p.waitFor();
BufferedReader reader = new BufferedReader(new InputStreamReader(p.getInputStream()));
String line = "";
while ((line = reader.readLine())!= null) {
output.append(line + "n");
}
p = Runtime.getRuntime().exec("id");
p.waitFor();
reader = new BufferedReader(new InputStreamReader(p.getInputStream()));
line = "";
while ((line = reader.readLine())!= null) {
output.append(line + "n");
}
One other thing I forgot to mention - I copy the app to /system/priv-app and run it from there. Still no luck.
I had a Chinese tablet with problem like that. Just re-root it (replace su binary). Should work.
P.S. Seeing any code would also help.
There is an android manifest permission you can use to gain root access
<uses-permission android:name="android.permission.FACTORY_TEST" />
Your app will run as a manufacturer test application, running as the root user. Thus making the 'su' command accessible to your app.
However, I doubt that Google Play will allow you to upload in store with such permission.
I'm using the Android's log to supervise an application use, so I'm using logcat into the phone not in Eclipse.
Well, if I just write in the log and send me the information everything it's ok, but I receive information from previous executions.
I decided to clear the log every time that my application starts, but now I usually lose the first log messages. Maybe logcat needs some time to get cleared? because when I try to do into debug everything it's ok.
Example:
clear log, message 1, message 2, message 3, ...
Sometimes I don't receive message 1, sometimes don't receive 1 and 2...
I have checked all my code for possible accidental clears but I didn't find anything...
I call this function at the beginning (in onCreate())
public static void clearLog(){
ArrayList<String> commandLine = new ArrayList<String>();
commandLine.add("logcat");
commandLine.add("-c");//CLEAR
Runtime process = Runtime.getRuntime();
process.exec(commandLine.toArray(new String[0]));
TAG = "";
}
Then I add logs
log.i(TAG, "message1");
..
log.i(TAG, "messageN");
And this is how I collect the log:
ArrayList<String> commandLine = new ArrayList<String>();
commandLine.add("logcat");
commandLine.add("-d");//dump and exit
commandLine.add("-v");//especify verbose mode
commandLine.add("raw");//raw show only the message, brief for show all
commandLine.add(TAG + ":V");//show TAG's log
commandLine.add("*:S");//hide others
Process process = Runtime.getRuntime().exec(
commandLine.toArray(new String[0]));
BufferedReader bufferedReader = new BufferedReader(
new InputStreamReader(process.getInputStream()));
String line, log = "";
while ((line = bufferedReader.readLine()) != null) {
log += line + LINE_SEPARATOR;
}
From the docs for exec():
Executes the specified command and its arguments in a separate native process.
So it's running in a separate process. There's not really a good way to tell if it has finished before you start logging.
Instead of clearing the log, you could change the log TAG on each run. Just use the regular tag an append some number that identifies the run, even just a random one. Then when you collect your logs, you can filter by that, and only collect the ones you want.
I'm developing a multi-tab application. In one of the tab I want to show the logcat but I have a lot of problem running it correctly.
Right now I'm using the following command but I don't get anything in my TextView. :
Process process = Runtime.getRuntime().exec("/system/bin/logcat -s com.vittorio:I");
But when I run the same command into Terminal it works flawlessy.
I've also tryed this other command :
Process process = Runtime.getRuntime().exec("/system/bin/logcat *:I");
but for some reason it prints also Debug level messages ...
EDIT (1):
I've by-passed the problem by adding an high-level filter (java) to the whole log.. so I only print in my textview what I need. It's a very dirty solution but for now is the only one I managed to come with.
I would like to point out that I'me experiencing different behaviours on my phones :
Galaxy S Plus (rooted) : I can see the log.
Galaxy Y (rooted) : No log
Nexus One (not-rooted) : No log
EDIT (2) - SOLVED (NEED ROOTED PHONE):
After some struggling I managed to solve my problem. Actually navigating through the init.rc system file I saw that the permissions for /dev/log/main and /dev/log/system where setted to 620.. that's why I couldn't open the log on some of my phones. So I rooted also my Nexus One and added this commands into my activity before calling the logcat command :
Process process_su = Runtime.getRuntime().exec("su");
Process process_ch = Runtime.getRuntime().exec("chmod 777 /dev/log/main");
Done! :D
Hope this info will help anyone who will face my same issue.
You have to use this permission :
<uses-permission android:name="android.permission.READ_LOGS" />
and then you can use that snippet i found
try {
Process process = Runtime.getRuntime().exec("logcat -v");
BufferedReader bufferedReader = new BufferedReader(
new InputStreamReader(process.getInputStream()));
StringBuilder logString=new StringBuilder();
String line;
while ((line = bufferedReader.readLine()) != null) {
logString.append(line);
}
TextView tv = (TextView)findViewById(R.id.logTextView);
tv.setText(logString.toString());
} catch (IOException e) {
}
I didn't try it but it seems correct
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
How can I check if an app running on Android?
I would like to know if there is a way to check if the Android default browser (browser in Android OS) has been opened. Suppose it's opened, I would like a toast to be displayed. How can I do this programmatically?
This is the code that I used in the class that extends the Service class which listens to the logs and checks if the Android default browser has been opened. If it is then it prints a log in the LogCat stating that the Android default browser has been opened.
try {
Process mLogcatProc = null;
BufferedReader reader = null;
mLogcatProc = Runtime.getRuntime().exec(new String[] { "logcat", "-d" });
reader = new BufferedReader(new InputStreamReader(mLogcatProc.getInputStream()));
String line;
final StringBuilder log = new StringBuilder();
String separator = System.getProperty("line.separator");
while ((line = reader.readLine()) != null) {
log.append(line);
log.append(separator);
}
String w = log.toString();
Log.d("LogService", "The log is: " + w);
if (w.contains("Starting activity: Intent { act=android.intent.action.MAIN flg=0x10000000 cmp=com.android.browser/.BrowserActivity }")) {
Log.d("LogService", "The browser has been opened");
}
}
catch (Exception e) {
Log.d("LogService", "The stacktrace is: " + e.getMessage());
}
google said on the google IO that such a behavior is considered as malware .
however , up until API 15 (including) , you can use a service that listens to the logs , and check if the desired app has started . that's because each time you run an app , android writes to the log about it .
this is considered as a workaround but a lot of apps use it and it works fine .
not sure if on the new version (API 16) reading logs would be that simple . they said that the permission to read from logs won't work anymore , and that they allow apps to read their own logs instead (without any permission needed) .
of course , if the app you are trying to monitor gives any kind of API to tell the world (via intent for example) that it has started , you can use it . i don't think that the built in web browser does that , though.
To the best of my (current) understanding, Android has no console to send the messages to so the System.out.println messages get lost. Instead, Log.x (outputing to LogCat) should be used.
Yet, in the acclaimed Pro Android 2 book, listing 8-1 does just that:
in = new BufferedReader(new InputStreamReader(response.getEntity().getContent()));
StringBuffer sb = new StringBuffer("");
String line = "";
String NL = System.getProperty("line.separator");
while ((line = in.readLine()) != null) {
sb.append(line + NL);
}
in.close();
String page = sb.toString();
System.out.println(page);
Does System.out.println really work in Android or is it only a typo?
If the former (i.e. not a typo), what does it really do and where should I expect to find the output?
System.out.println prints to whatever is currently defined as the "standard" output PrintStream. It is possible to hook this up to point to the log stream, but really there is no good reason to use it. Use Log.x.
This is probably just a typo in the book. Nothing in that code snippet is Android specific.
That System.out.println code does work (despite what the android documentation says). I've tried it on my on my Android development set up (without changing the settings as they describe in the documentation). I've had tried on the set ups of my Android programming students, both on their Windows and Macs. And it always comes out the same way:
The following line does output to logcat by default.
System.out.println("blah blah");
Now of course, it's probably best to stick to Log.x() anyway. It's probably never a good idea to rely on undocumented features, especially in a book. This feature could be here today, and be just as well gone the next time the tools get updated.
From the android docs:
By default, the Android system sends stdout and stderr (System.out and System.err) output to /dev/null.
It also explains how to use System.out and System.err properly.
If you're using Eclipse, System.out will be displayed on the LogCat tab not in the Console.
You can also try the Log.i("MyLog", "The message here...."); also displayed on the LogCat.
Enjoy!