I have an application/phone which I am developing to be given to people who will be using it in remote areas and not so tech-savvy. I want a mechanism to be able to read their log files remotely. The android app is making use of the logcat logging. I want to be able to just read my logs for my app by some remote mechanism. I was thinking more along the lines of reading the logcat then posting that up periodically to a REST service where I can database these. So question is how do I read the Logcat files programatically from my app?
If you invoke:
Proccess p = Runtime.getRuntime().exec("logcat");
InputStream in = p.getInputStream();
//code to process the InputStream
I honestly do not know the entire process of getting the input stream back, but the code above will allow your app to read the logcat file. You can go here for possible command-line paramaters for "logcat". The exec method runs the string through a linux shell, btw.
You must have the permission READ_LOGS
Related
Is there a way to programmatically get list of apps connecting to the internet and their inbound and outbound connection.
Thinking of doing an app that does this and do not need to root the phone.
If you want a low level solution you can try the netstat approach.
On linux based systems you can read network information from /proc/net/route.
One way to do this is to to include a busybox binary in your app (make sure to look at the licencse) And run busybox netstat, then read the output into your app.
Process process = Runtime.getRuntime().exec("busybox netstat -n");
BufferedReader reader = new BufferedReader(
new InputStreamReader(process.getInputStream())
process.getOutputStream().close();
Then you can identify which app is using which connection by the process id column, you'll get the procces user which can be identified with an application such as app_23 , see this answer how to get the app name from the pid
If you don't want to include the busybox binary you can try reading the information from procfs yourself.
Luckily someone already did that work for you, see this example.
This information is already available in settings under "DataUsage". You just have to extract it from there; have a look at - TrafficStats.
Similar question - about app level data consumption
I have some question related to the Android Logcat, I am refering these questions to be in REAL DEVICE not the emulator:
I have a program which has a lot of Log.d (or other similar log functions), I did some google search and found that those logs will be output to a circular 64K buffer. My question is, where are those 64K buffer located? Is it located in RAM or file system? Will it be removed after my app exits?
I google and found that, the log will be output to a file called /dev/event (not sure), but I couldn't see any application-related logging inside, why? Only system-related log entries can be seen.
Does every app output its log to a different log file? Or are they all dumped into the same log file? In this case, how can we seperate the log?
If the logging buffer is 64K, how can we increase it? If we want to re-direct the log to a file which is on a sd card, how can we limit the file size (of course make it circular too)?
Going point by point:
(1) The log buffers are in RAM, in the kernel. Logging is handled by a kernel driver. On recent devices, the log buffer is much larger than 64KB. They are not lost when an application exits, but will not survive a device reboot.
(2) The device entries are in /dev/log, e.g. /dev/log/main for the main log, /dev/log/radio for the radio log, and /dev/log/events for the event log. The logs are stored in a format that is generally more compact than what you see in logcat, so reading them directly with something like cat may be confusing.
(3) All apps write to the same log devices. Each log message is tagged with the process ID and thread ID of the log writer, so you can separate them out that way. (logcat -v threadtime will show you the pid, tid, timestamp, and tag.)
(4) You would need to change a value in the driver to alter the size of the log. Again, recent devices have much larger log buffers, so this is probably not so useful. You can send the output to a file with logcat; if you want to do some sort of circular buffer you will need to capture the output of logcat and handle it yourself. (You could also read the log device directly, but I don't think the API is public. See the AOSP logcat sources.)
Recent versions of Android do not allow apps to read all entries in the log. Instead, apps may only read the entries that they themselves generated. This was done to allow bug reporting systems to capture the logs, while preventing wayward apps from "spying" on other apps. When you run logcat from adb shell, it runs as the shell user, which has permission to read all logs.
I'm developing an Android App which i want to communicate with a device connected via USB. This device is delivering data all the time. These data are visible with a programm on the android linux shell.
My goal is to see those data in my App and after that deliver them via a Service to other Apps.
So my question is: Can i "open" a connection from my Android App to the USB-Port so im continuesly receiveing the data in my app, which are sent by the usb-device? And if yes, how would the code look like?
*Edit
Thank you for your answers, the app itself doesn't run on the commandline any more. So its no executable anymore but a shared library getting load by my android app.
It did before, but i want to be able to initiate the connection using NDK methods in my App to be able to see the data in my App itself. So I've tried to see if a connection is allready open.
I've added some functions to my code, so i can see if the usb-connection is open and i have the permission to that usb device.
UsbManager.hasPermission(device)
returns true, because I'm using an itent filter.
UsbManager.openDevice(device)
returns an UsbDeviceConnection, so i seem to have the access to use that device.
What im not capable of so far is receiving either iniciating the bus connection to by usb-device and of course either getting data input of that device.
Since my native code allready has a while(true)-method which is only using callbacks to send data to my app when actually data getting sent trough my usb-device i want to keep the work done in my c-code.
The only job my app should do is open the bus-connection once and after that be ready for callback from the c-code.
Is that possible?
If you have the app that runs on the command line, you can actually run a command line from within your app. Take a look at the Process class and the ProcessBuilder docs for full details. The example given is below
To run /system/bin/ping to ping android.com:
Process process = new ProcessBuilder()
.command("/system/bin/ping", "android.com")
.redirectErrorStream(true)
.start();
try {
InputStream in = process.getInputStream();
OutputStream out = process.getOutputStream();
readStream(in);
finally {
process.destroy();
}
}
I'm trying to set up a web server using the Restlet framework on my Android phone. My idea is to build a game where one phone creates some markers on a map which then can be transferred directly to other phones using rest. At first (and for simplicity) I want to transfer a List of Objects.
Running a server on my computer seems to work fine, but when I transfer the code to my Android application, it won't start the server. Here is the code:
Component serverComponent = new Component();
serverComponent.getServers().add(Protocol.HTTP, 80);
final Router router = new Router(serverComponent.getContext().createChildContext());
router.attach("/gamedata", GameDataResourceServer.class);
serverComponent.getDefaultHost().attach(router);
serverComponent.start();
When the line serverComponent.start(); is executed, this Exception is thrown:
java.net.BindException: Permission denied (maybe missing INTERNET permission), although the internet permission is in the manifest file. Searching for some tutorials didn't help either. The result are either client applications or very complicated scenarios.
Could someone give an example for a simple application?
In Unix-type environments you typically need root access to bind to a TCP port below 1024. You're trying to bind to port 80, and unless you run this code as root the OS will prevent the request.
using logcat I can see the log messages generated by my app in the emulator. How can I read/retrieve the same log file but this time from the device the app is running on ? The device is not attached to any computer and the log file has to be sent via email.
To read the log from within your application you need to have the android.permission.READ_LOGS permission.
Once you have that, you could start up a process to read logcat with something like
Process logcatProcess = Runtime.getRuntime().exec("logcat");
Then you can create a buffered reader from it:
BufferedReader logcat = new BufferedReader(new InputStreamReader(logcatProcess.getInputStream()), 8192);
From here you can String s = logcat.readLine(); to read the log.
There is a log collector project that you can use from your code/application. If you want an already existing application, try Log Collector.
Check out this app on the market. It does what you need and it is open source!