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
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.
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
I have a Java SE Application that use
input = new Scanner(System.in);
to get Input parameters
and use System.out.println("..");
to print results
Since all Java APIs used in the original Java Project are also available in Android, I have tried to import all classes without any error, but now I don't know how replicate the behaviour of the classic Java console in Android.
I have seen that there are developers that have achieved this in some IDE-like apps, but I don't know how.
Could you help me?
Example:
assume that you want to port this dummy Java SE Application in Android mantaining the console-like approach of the original code
public static void main(String[] args) {
System.out.println("Please enter your choice");
System.out.println("A, B");
Scanner myScanner = new Scanner(System.in);
String choice = myScanner .nextLine();
if (choice.charAt(0) == 'A') {
...do something
}
else{
...do something
}
}
You can execute system commands with exec(). Here is how to do it:
Runtime r = Runtime.getRuntime();
Process p = r.exec("uname -a"); // here goes your input
p.waitFor();
BufferedReader b = new BufferedReader(new InputStreamReader(p.getInputStream()));
String line = "";
while ((line = b.readLine()) != null) {
System.out.println(line);
}
Update:
Ok, from what I understand, you would like to compile and run code written by user. I can see 3 options:
Most difficult I think. Get the source code of some Java compiler and include it in your project. So, user inputs a text. You compile it, run and give the output.
Using already built compiler. This requires root. Install javac on your device. Then, in your application you can call it with the above exec() code.
Easiest one. Using internet and for example, Ideone.com. In your app you send code to compile on Ideone. You get back the output and present it to the user.
I develop an app and want update itself and want following fetures, device have been rooted :
1 automatic check can update every start (I can do)
2 download the apk file to local (I can do)
3 update with custom dialog, or update silently (I dont know )
edit:
My app run on TV with remote, the default dialog which can control but perfect , so I want use my dialog if there must a dialog.Its best if need not a dialog.
First declare this variables, then call function wherever you want. Then grant superuser, on your superuser application, check the option to always grant, for non user interaction.
#Override
public void onCreate() {
super.onCreate();
//some code...
final String libs = "LD_LIBRARY_PATH=/vendor/lib:/system/lib ";
final String commands = libs + "pm install -r " + "your apk directory"+ "app.apk";
instalarApk(commands);
}
private void instalarApk( String commands ) {
try {
Process p = Runtime.getRuntime().exec( "su" );
InputStream es = p.getErrorStream();
DataOutputStream os = new DataOutputStream(p.getOutputStream());
os.writeBytes(commands + "\n");
os.writeBytes("exit\n");
os.flush();
int read;
byte[] buffer = new byte[4096];
String output = new String();
while ((read = es.read(buffer)) > 0) {
output += new String(buffer, 0, read);
}
p.waitFor();
} catch (IOException e) {
Log.v(Debug.TAG, e.toString());
} catch (InterruptedException e) {
Log.v(Debug.TAG, e.toString());
}
}
The regular way (without root and a default installer dialog) is described in another question, and should be used in most cases imho, as I dislike requesting root privileges for a update feature.
There is no difference in providing a custom dialog and installing an apk silently, as both technically are silent installs (e.g. not made by the install activity). With root privileges, you could use a root shell and either replace the apk (as in the open-source keybord manager app) or invoke the package manager from shell. I'd suggest you go for the second way, I linked the keybord manager app source mainly for the root shell creation stuff.
The Android Framework make it defficult to update silently, on custom devices you must call system install service for your apk file, and it will show the install dialog for the user, but if the device is rooted, I think you can make that silently.
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)