Please excuse my english.
In the Device Settings the system status just shows the recent uptime.
I want the total uptime from factory.
In Android, there is no direct way to get total Uptime from factory.
There is a kinda-workaround, where via PackageManager you can get the install time of and app using getPackageInfo() and long firstInstallTime. So, you can try to get the oldest app installed and take it from there.
Besides that - like I have said, there is no direct way.
Based on answer from here
adb shell commend in java.lang.Runtime.getRuntime().
String cmd = "shellscript.sh";
String cmdreturn = "";
Runtime run = Runtime.getRuntime();
Process pr = run.exec(cmd);
pr.waitFor();
BufferedReader buf = new BufferedReader(new InputStreamReader(pr.getInputStream()));
while ((line=buf.readLine())!=null) {
System.out.println(cmdreturn);
}
Refer adb and Debugging
Related
How can I determine the security patch level of an Android device using an API or other mechanism? I'm looking for the same security patch information that can be found manually by clicking the Settings -> About menu on the device.
Google issues security patches every month, for example 2016-12-01.
In Android SDK 23 (Marshmallow) and later, you can retrieve the security patch date from android.os.Build.VERSION.SECURITY_PATCH. The date is a string value in YYYY-MM-DD form.
In Lollipop, you can use the getprop command to read the value of ro.build.version.security_patch. See this S/O question for how to execute getprop using ProcessBuilder.
Security patches have been released on a monthly basis since October 2015, see Android Security Bulletins for more details.
I do not think that is possible without root access since the Security Patch Level is stored in ro.build.version.security_patch field inside build.prop which is in /system/ path.
If you have root access, you can just read that file and look for the above mentioned field.
EDIT: as #v6ak mentioned, you access the value of the properly without root too.
This value is stored in the /system/bin/getprop system file. You can read it in this way:
try {
Process process = new ProcessBuilder()
.command("/system/bin/getprop")
.redirectErrorStream(true)
.start();
InputStream is = process.getInputStream();
BufferedReader br = new BufferedReader(new InputStreamReader(is));
String line;
while ((line = br.readLine()) != null) {
str += line + "\n";
if (str.contains("security_patch")) {
String[] splitted = line.split(":");
if (splitted.length == 2) {
return splitted[1];
}
break;
}
}
br.close();
process.destroy();
} catch (IOException e) {
e.printStackTrace();
}
From an adb shell you can execute getprop ro.build.version.security_patch.
Hopefully those properties are available to a non-root process on Android.
So in C/C++ I'd try using:
system("getprop ro.build.version.security_patch");
Or in Java something like:
import android.os.Bundle;
public static final String SECURITY_PATCH = SystemProperties.get(
"ro.build.version.security_patch");
you can also use the following adb command
adb shell getprop | egrep
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 am working on a simple app but don't know how to stop continuous action in terminal such as PING programmatically.
I just want to know the command, then I'll add it to runtime.getruntime.exec...
I know there's a CTRL+C shortcut in pc but how do I execute this on Android?
Sorry for not adding examples, I'm writing from my phone.
Another way:
Process proc = Runtime.getRuntime().exec("ping 127.0.0.1");
proc.destroy();
As you execute your command, you get the relating process. You can use it to stop your ping, too.
You can't directly send CTRL + C, but take a look at Process.sendSignal() (Android Developers)
First, get the process ID of the ping-process.
Then you can easily send a Process.sendSignal(yourPid, Process.SIGNAL_QUIT);
After debugging for a long time I found out how to solve the problem
"Kill results without the ping statistics being returned".
Get pid of ping process.
Ex:
Progress proc = runtime.exec("ping 192.168.1.1");
where proc will be something like Process[pid=2343], so you need to extract 2343.
Then when you are reading the ping output, you can use
"Runtime.getRuntime().exec("kill -INT " + 2243);" to kill the process.
InputStreamReader reader = new InputStreamReader(proc.getInputStream());
BufferedReader buffer = new BufferedReader(reader);
String line;
while ((line = buffer.readLine()) != null) {
echo.append(line).append("\n");
if (UserStopPing) {
Runtime.getRuntime().exec("kill -INT " + temp);
}
proc.waitFor();
This program will stop ping and you will get the statistic also [variable echo].
You can try this.
There is a CTRL option on your screen. Press that and then enter c.
This might help you.
Just in case people are still looking for a solution to this -- On an Android the equivalent of CTRL+C is "Volume down button" + C on your keyboard. This should stop the ping.
I feel like I am on crazy pills right now. A specific part of my application has been working just fine for several days, and today it just stopped working and I can not figure out why. This part of my code used to output the total data since boot that each specific app has sent and received. Now, the values always show up as 0.
A couple things that may or may not be affecting this:
1.) My Nexus 4 was just updated to Android 4.3 today, but I doubt this is an issue because this worked just fine right after I updated.
2.) With the Android API 18 update, some methods from the Traffic Stats API are now deprecated, but these are methods I am not even using, so this should have no effect.
http://developer.android.com/reference/android/net/TrafficStats.html
All help is greatly appreciated.
PackageManager packageManager=this.getPackageManager();
List<ApplicationInfo> appList=packageManager.getInstalledApplications(0);
for (ApplicationInfo appInfo : appList) {
String appLabel = (String) packageManager.getApplicationLabel(appInfo);
int uid = appInfo.uid;
Log.d("data", String.valueOf(TrafficStats.getUidRxBytes(uid) + TrafficStats.getUidTxBytes(uid)));
Update[January 23, 2014]: Testing the getUidRxBytes() and getUidTxBytes() on my Nexus 4 running Android 4.4.2 shows that the values are no longer 0, but are reporting the correct statistics.
I have reported the issue to the AOSP issue tracker: here
I have also created an alternate solution to the problem which I have pasted below:
private Long getTotalBytesManual(int localUid){
File dir = new File("/proc/uid_stat/");
String[] children = dir.list();
if(!Arrays.asList(children).contains(String.valueOf(localUid))){
return 0L;
}
File uidFileDir = new File("/proc/uid_stat/"+String.valueOf(localUid));
File uidActualFileReceived = new File(uidFileDir,"tcp_rcv");
File uidActualFileSent = new File(uidFileDir,"tcp_snd");
String textReceived = "0";
String textSent = "0";
try {
BufferedReader brReceived = new BufferedReader(new FileReader(uidActualFileReceived));
BufferedReader brSent = new BufferedReader(new FileReader(uidActualFileSent));
String receivedLine;
String sentLine;
if ((receivedLine = brReceived.readLine()) != null) {
textReceived = receivedLine;
}
if ((sentLine = brSent.readLine()) != null) {
textSent = sentLine;
}
}
catch (IOException e) {
}
return Long.valueOf(textReceived).longValue() + Long.valueOf(textReceived).longValue();
}
The TrafficStats class get the information about network traffic from the /proc/uid_stat/<uid> directory. This contains information about the tcp, udp bytes and packets sent and received. If the files are not present the TrafficStats class can't get the network stats. You can check if the files are present, If not you are out of luck and should look for other way.
If the files are present you can try to read it yourself.
Also the getUidTxBytes() and getUIDRxBytes() report only the TCP traffic and miss UDP traffic. So if your app is doing lots of UDP traffic (like voip) then you'll not get any info.
There is already a bug filed for this : https://code.google.com/p/android/issues/detail?id=32410
I have done some detailed research about this, and to clarify some details, since Android 4.3 the TrafficStats API has changed in the way it extracts details from the device.
Prior to Android 4.3 the UID traffic stats were available for TCP and UDP and included API for bytes and packets & sent and received. That data was extracted from the /proc/uid_stat/[pid]/* files.
In Android 4.3, the developers has decided to switch to a better and more safe API, using the xt_qtaguid UID statistics, which is part of the netfilter kernel module in Linux.
This API (procfs) allows access based on process UID, and this is why when you try to access to TrafficStats API in Android=>4.3 you will get zero information for not-own UID.
btw, the commit that caused the issue is the following:
https://github.com/android/platform_frameworks_base/commit/92be93a94edafb5906e8bc48e6fee9dd07f5049e
*Improve TrafficStats UID APIs.
Deprecate transport layer statistics, leaving only the summarized
network layer statistics.
Improve documentation to be clear about layers where measurements
occur, and their behavior since boot. Under the hood, move to using
xt_qtaguid UID statistics.
Bug: 6818637, 7013662
Change-Id: I9f26992e5fcdebd88c671e5765bd91229e7b0016*
Is is possible to run getevent from an Android service and get output similar to what you see when running adb to call getevent from a command prompt on a development machine? When I try something like:
ProcessBuilder builder = new ProcessBuilder()
.command("getevent")
.redirectErrorStream(true)
.start();
BufferedReader reader = new BufferedReader(new InputStreamReader(builder.getInputStream()));
...
the output I get for each device looks like:
could not open /dev/input/event[n], Permission denied
Is it just not possible to access low level information like this because of Android's security protections? Would it be possible on a "rooted" device?
Why I am trying to do this:
I would like to record a user's actions (touch and gesture events) on an Android device for the purpose of usability testing. An accessibility service seems to be the way to go, but the information is not detailed enough. For a swipe gesture, for example, I cannot get the screen coordinates of where the user swiped. I was thinking that getting the low-level input from the touch screen might let me get more detailed information. Maybe there is a better way to do this?
(I'm a newbie in the Android world. This kind of thing is easy on Windows.)
You can do like this.
th = new Thread(new Runnable(){
private Process exec;
#Override
public void run() {
try {
exec = Runtime.getRuntime().exec(new String[]{"su","-c","getevent -t " + device});
InputStreamReader is = new InputStreamReader(
exec.getInputStream());
String s;
BufferedReader br = new BufferedReader(is);
while(((s = br.readLine()) != null) && run){
...
}
is.close();
exec.destroy();
} catch (IOException e) {
e.printStackTrace();
}
}
You must use 'su' to get the root permission, but by this way you can't get the real time event, because there is a buffer size of 4k, you could get data only after contained 4k data.
Search for UIAutomator. This does what you want to do.
Your phone must be rooted to execute getevent/sendevent command.
One way is to install any terminal emulator from play store like Qute: Command Console & Terminal Emulator.
In terminal enter following:
1) su (it'll gain the root access required for getevent)
2) getevent (or getevent -c 8 to output only 8 lines else it would flood the terminal)