Attend XDA's Second Annual Developer Conference, XDA:DevCon 2014!
5,731,053 Members 46,116 Now Online
XDA Developers Android and Mobile Development Forum

[Guide] Accessing all Build.prop values without Root

Tip us?
 
torpedo mohammadi
Old
(Last edited by torpedo mohammadi; 27th July 2013 at 08:29 PM.)
#1  
Member - OP
Thanks Meter 32
Posts: 86
Join Date: Aug 2012
Default [Guide] Accessing all Build.prop values without Root

Hi.
I was developing an app in which I needed to access some of the build.prop values without accessing root.
After some days finally I found a good & working solution.
So, for whom they need it later, I decided to share it here.
All you have to do is this :

1. Make a process which executes "getprop" from the "/system/bin/getprop" directory and initialize the String which we want to get (ro.board.platform in example).
2. Make a BufferedReader which gets the value (String) by retrieving the data from a inputStreamReader().
3.Convert the BufferedReader to String.


Help your selves.

Code:
Process p = null;
String board_platform = "";
try {
p = new ProcessBuilder("/system/bin/getprop", "ro.board.platform").redirectErrorStream(true).start();
BufferedReader br = new BufferedReader(new InputStreamReader(p.getInputStream()));
String line = "";
while ((line=br.readLine()) != null){
board_platform = line;
}
p.destroy();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
The Following 19 Users Say Thank You to torpedo mohammadi For This Useful Post: [ Click to Expand ]
 
uxmanz
Old
#2  
Member
Thanks Meter 7
Posts: 52
Join Date: Jun 2010
Thanks man!.,,..
 
Dr.Alexander_Breen
Old
#3  
Dr.Alexander_Breen's Avatar
Senior Member
Thanks Meter 892
Posts: 415
Join Date: Jun 2012
Location: Moscow

 
DONATE TO ME
But are we really in such a need of getprop? If I remember correctly, on all Android devices /system partition is world-readable. So we can just read it build.prop like a normal text file and then parse it.
The Following User Says Thank You to Dr.Alexander_Breen For This Useful Post: [ Click to Expand ]
 
torpedo mohammadi
Old
#4  
Member - OP
Thanks Meter 32
Posts: 86
Join Date: Aug 2012
Quote:
Originally Posted by Dr.Alexander_Breen View Post
But are we really in such a need of getprop? If I remember correctly, on all Android devices /system partition is world-readable. So we can just read it build.prop like a normal text file and then parse it.
Maybe you're right.
But before the Tut، I collected some info on build.prop.
I read different files from different devices with different ROMs.
And I gained a result : The file differs from ROM to ROM and from device to device.
I had thought of this knowing that in device Nexus 4 "ro.x.y" is in line "z" forexample :

1. Create BufferedReader to read the build.prop file.
2.
// Let's consider ro.x.y : outcome in build.prop
int x = 0;
String y ="";
If ((y = br.readLine()) != null) {
x++;
String line = y;
if (x = z){
// So we have found ro.x.y
String result = line;
result = result.replaceAll("ro.x.y", "");
result = result.replaceAll(" :", "");
}
}


Using this procedure we have retreived the ro.x.y value in Nexus 4.
But does anybody promise that ro.x.y is in line "z" in all devices?
The answer is NO as I mentioned above.
Maybe someone has changed his build.prop file and ... .
I hope it helps.
 
torpedo mohammadi
Old
#6  
Member - OP
Thanks Meter 32
Posts: 86
Join Date: Aug 2012
Quote:
Originally Posted by nikwen View Post
Shouldn't the title be [Guide], not [Guilde]?
Thanks sir.
Didn't notice at all.
The Following User Says Thank You to torpedo mohammadi For This Useful Post: [ Click to Expand ]
 
OmarBizreh
Old
(Last edited by OmarBizreh; 27th July 2013 at 09:49 PM.)
#7  
OmarBizreh's Avatar
Recognized Developer
Thanks Meter 3311
Posts: 1,942
Join Date: Oct 2011
Location: Damascus

 
DONATE TO ME
And here is C# Translation for the code:
------------------------------------------------------------------------------------------------
Global Variables
------------------------------------------------------------------------------------------------
Code:
private Process p = null;
private string AdbPath = Path.Combine(Path.GetTempPath(), "RegawMOD", "AndroidLib", "adb");
------------------------------------------------------------------------------------------------
Process Definition
------------------------------------------------------------------------------------------------
Code:
 
try
{
    p = new Process();
    ProcessStartInfo sInfo = new ProcessStartInfo("cmd");
    sInfo.RedirectStandardOutput = true;
    sInfo.RedirectStandardInput = true;
    sInfo.CreateNoWindow = true;
    sInfo.UseShellExecute = false;
    sInfo.WindowStyle = ProcessWindowStyle.Hidden;
    p.StartInfo = sInfo;
    p.OutputDataReceived += p_OutputDataReceived;
    p.EnableRaisingEvents = true;
    p.Start();
    p.BeginOutputReadLine();
}
catch (Exception ex)
{
      MessageBox.Show(ex.Message, "Error starting adb process", MessageBoxButton.OK, MessageBoxImage.Error);
}
------------------------------------------------------------------------------------------------
p_OutputDataReceived Definition
------------------------------------------------------------------------------------------------
Code:
void p_OutputDataReceived(object sender, DataReceivedEventArgs e)
{
string line = "";
try
{
    if (!(line = e.Data).Trim().Length.Equals(0) && !line.Contains("/system/bin/getprop ro.board.platform"))
     {
           this.Dispatcher.BeginInvoke(new Action(() => txt.AppendText(line + "\n")));
     }
}
catch (Exception ex)
{
       MessageBox.Show(ex.Message, "Error Reading Output", MessageBoxButton.OK, MessageBoxImage.Error);
 }
}
------------------------------------------------------------------------------------------------
Passing command to our little adb process
------------------------------------------------------------------------------------------------
Code:
if (p != null)
{
     p.StandardInput.WriteLine(AdbPath + " shell /system/bin/getprop ro.board.platform");
}
------------------------------------------------------------------------------------------------
Side Notes:
------------------------------------------------------------------------------------------------
  • Code above will result in active shell, it's a simulation for executing commands via CMD
  • What you need to do is the following:
    • Change "AdbPath" content to match the path of your adb executable.
    • "txt" is the Textbox that will show the output, put your own object.
    • Remove this line " !line.Contains("/system/bin/getprop ro.board.platform);" from "p_OutputDataReceived" to have an idea why I included it in the first place, it's not a must to have it but it will make output look nicer.
    • In the "Passing command to our little adb process" section, you can replace " shell /system ...etc" with your own object to make the app flexible and be able to execute any command the user type [example: .p.StandardInput.WriteLine(String.Join(" ", AdbPath , CommandTextBox.Text));]
  • This is almost the same code I execute in Droid Manager for the active shell, I just added few more lines to serve my active shell demands
  • My device is rooted, nevertheless it doesn't matter which language we are using, as long as we are executing the same command, then it should work with non rooted devices too just like OP says
  • I use AndroidLib that's why my Adb path points to AndroidLib's adb executable.
------------------------------------------------------------------------------------------------
Good luck

------------------------------------------------------------------------------------------------

Edit:
Quote:
Originally Posted by Dr.Alexander_Breen View Post
But are we really in such a need of getprop? If I remember correctly, on all Android devices /system partition is world-readable. So we can just read it build.prop like a normal text file and then parse it.
@Dr.Alexander_Breen Yes /system is read only and we can read the file, but if you read it like a text file you will have to break text apart to get the value and not key + value. and you will have to go line by line to reach the key you want, so by using "getprop" you will get the value without having to write extra lines of code to make the app show you value only. As for me I prefer it that way, no need to make the app execute more lines of code just to get a part of the string.
The Following 2 Users Say Thank You to OmarBizreh For This Useful Post: [ Click to Expand ]
 
Dr.Alexander_Breen
Old
#8  
Dr.Alexander_Breen's Avatar
Senior Member
Thanks Meter 892
Posts: 415
Join Date: Jun 2012
Location: Moscow

 
DONATE TO ME
Quote:
Originally Posted by torpedo mohammadi View Post
Using this procedure we have retreived the ro.x.y value in Nexus 4.
But does anybody promise that ro.x.y is in line "z" in all devices?
The answer is NO as I mentioned above.
Maybe someone has changed his build.prop file and ... .
I hope it helps.
Well, we are supposed to write smart parser which is indifferent to line number, it searches by key name...and gets the value. However, that is the reinvention of the wheel - getprop does exactly the same.

Just saying that the same result is available without the getprop. But it will be (or will not if you're really good in regular expressions) harder, yes.
The Following User Says Thank You to Dr.Alexander_Breen For This Useful Post: [ Click to Expand ]
 
Androguide.fr
Old
(Last edited by rwestergren; 4th February 2014 at 12:00 PM.)
#9  
Androguide.fr's Avatar
Recognized Contributor
Thanks Meter 6909
Posts: 2,048
Join Date: Jul 2012
Location: Lyon, France

 
DONATE TO ME
Alternatively, you can use reflection to access Android's internal android.os.SystemProperties class.
Here is the class I use to reflect it in Pimp My Rom :

Code:
package com.androguide.pimpmyrom.helpers;

import android.content.Context;

import java.io.File;
import java.lang.reflect.Method;

import dalvik.system.DexFile;

/*
  Class using reflection to grant access to the private hidden android.os.SystemProperties class
 */
public class SystemPropertiesReflection {

    /**
     * This class cannot be instantiated
     */
    private SystemPropertiesReflection() {

    }

    /**
     * Get the value for the given key.
     *
     * @return an empty string if the key isn't found
     * @Throws IllegalArgumentException if the key exceeds 32 characters
     */
    public static String get(Context context, String key) throws IllegalArgumentException {

        String ret = "";

        try {

            ClassLoader cl = context.getClassLoader();
 @suppressWarnings("rawtypes")
            Class SystemProperties = cl.loadClass("android.os.SystemProperties");

            //Parameters Types
 @suppressWarnings("rawtypes")
            Class[] paramTypes = new Class[1];
            paramTypes[0] = String.class;

            Method get = SystemProperties.getMethod("get", paramTypes);

            //Parameters
            Object[] params = new Object[1];
            params[0] = new String(key);

            ret = (String) get.invoke(SystemProperties, params);

        } catch (IllegalArgumentException iAE) {
            throw iAE;
        } catch (Exception e) {
            ret = "";
            //TODO
        }

        return ret;

    }

    /**
     * Get the value for the given key.
     *
     * @return if the key isn't found, return def if it isn't null, or an empty string otherwise
     * @Throws IllegalArgumentException if the key exceeds 32 characters
     */
    public static String get(Context context, String key, String def) throws IllegalArgumentException {

        String ret = def;

        try {

            ClassLoader cl = context.getClassLoader();
 @suppressWarnings("rawtypes")
            Class SystemProperties = cl.loadClass("android.os.SystemProperties");

            //Parameters Types
 @suppressWarnings("rawtypes")
            Class[] paramTypes = new Class[2];
            paramTypes[0] = String.class;
            paramTypes[1] = String.class;

            Method get = SystemProperties.getMethod("get", paramTypes);

            //Parameters
            Object[] params = new Object[2];
            params[0] = new String(key);
            params[1] = new String(def);

            ret = (String) get.invoke(SystemProperties, params);

        } catch (IllegalArgumentException iAE) {
            throw iAE;
        } catch (Exception e) {
            ret = def;
            //TODO
        }

        return ret;

    }

    /**
     * Get the value for the given key, and return as an integer.
     *
     * @param key the key to lookup
     * @param def a default value to return
     * @return the key parsed as an integer, or def if the key isn't found or
     *         cannot be parsed
     * @Throws IllegalArgumentException if the key exceeds 32 characters
     */
    public static Integer getInt(Context context, String key, int def) throws IllegalArgumentException {

        Integer ret = def;

        try {

            ClassLoader cl = context.getClassLoader();
 @suppressWarnings("rawtypes")
            Class SystemProperties = cl.loadClass("android.os.SystemProperties");

            //Parameters Types
 @suppressWarnings("rawtypes")
            Class[] paramTypes = new Class[2];
            paramTypes[0] = String.class;
            paramTypes[1] = int.class;

            Method getInt = SystemProperties.getMethod("getInt", paramTypes);

            //Parameters
            Object[] params = new Object[2];
            params[0] = new String(key);
            params[1] = new Integer(def);

            ret = (Integer) getInt.invoke(SystemProperties, params);

        } catch (IllegalArgumentException iAE) {
            throw iAE;
        } catch (Exception e) {
            ret = def;
            //TODO
        }

        return ret;

    }

    /**
     * Get the value for the given key, and return as a long.
     *
     * @param key the key to lookup
     * @param def a default value to return
     * @return the key parsed as a long, or def if the key isn't found or
     *         cannot be parsed
     * @Throws IllegalArgumentException if the key exceeds 32 characters
     */
    public static Long getLong(Context context, String key, long def) throws IllegalArgumentException {

        Long ret = def;

        try {

            ClassLoader cl = context.getClassLoader();
 @suppressWarnings("rawtypes")
            Class SystemProperties = cl.loadClass("android.os.SystemProperties");

            //Parameters Types
 @suppressWarnings("rawtypes")
            Class[] paramTypes = new Class[2];
            paramTypes[0] = String.class;
            paramTypes[1] = long.class;

            Method getLong = SystemProperties.getMethod("getLong", paramTypes);

            //Parameters
            Object[] params = new Object[2];
            params[0] = new String(key);
            params[1] = new Long(def);

            ret = (Long) getLong.invoke(SystemProperties, params);

        } catch (IllegalArgumentException iAE) {
            throw iAE;
        } catch (Exception e) {
            ret = def;
            //TODO
        }

        return ret;

    }

    /**
     * Get the value for the given key, returned as a boolean.
     * Values 'n', 'no', '0', 'false' or 'off' are considered false.
     * Values 'y', 'yes', '1', 'true' or 'on' are considered true.
     * (case insensitive).
     * If the key does not exist, or has any other value, then the default
     * result is returned.
     *
     * @param key the key to lookup
     * @param def a default value to return
     * @return the key parsed as a boolean, or def if the key isn't found or is
     *         not able to be parsed as a boolean.
     * @Throws IllegalArgumentException if the key exceeds 32 characters
     */
    public static Boolean getBoolean(Context context, String key, boolean def) throws IllegalArgumentException {

        Boolean ret = def;

        try {

            ClassLoader cl = context.getClassLoader();
 @suppressWarnings("rawtypes")
            Class SystemProperties = cl.loadClass("android.os.SystemProperties");

            //Parameters Types
 @suppressWarnings("rawtypes")
            Class[] paramTypes = new Class[2];
            paramTypes[0] = String.class;
            paramTypes[1] = boolean.class;

            Method getBoolean = SystemProperties.getMethod("getBoolean", paramTypes);

            //Parameters
            Object[] params = new Object[2];
            params[0] = new String(key);
            params[1] = new Boolean(def);

            ret = (Boolean) getBoolean.invoke(SystemProperties, params);

        } catch (IllegalArgumentException iAE) {
            throw iAE;
        } catch (Exception e) {
            ret = def;
            //TODO
        }

        return ret;

    }

    /**
     * Set the value for the given key.
     *
     * @Throws IllegalArgumentException if the key exceeds 32 characters
     * @Throws IllegalArgumentException if the value exceeds 92 characters
     */
    public static void set(Context context, String key, String val) throws IllegalArgumentException {

        try {

 @suppressWarnings("unused")
            DexFile df = new DexFile(new File("/system/app/Settings.apk"));
 @suppressWarnings("unused")
            ClassLoader cl = context.getClassLoader();
 @suppressWarnings("rawtypes")
            Class SystemProperties = Class.forName("android.os.SystemProperties");

            //Parameters Types
 @suppressWarnings("rawtypes")
            Class[] paramTypes = new Class[2];
            paramTypes[0] = String.class;
            paramTypes[1] = String.class;

            Method set = SystemProperties.getMethod("set", paramTypes);

            //Parameters
            Object[] params = new Object[2];
            params[0] = new String(key);
            params[1] = new String(val);

            set.invoke(SystemProperties, params);

        } catch (IllegalArgumentException iAE) {
            throw iAE;
        } catch (Exception e) {
            //TODO
        }

    }
}
Then, you can create a static method like the following in order to avoid NPEs if the property we're asking for isn't present and such:
Code:
public static String getSystemProp(Context context, String prop, String default) {
        String result = null;
        try {
            result = SystemPropertiesReflection.get(context, prop);
        } catch (IllegalArgumentException iae) {
            Log.e(TAG, "Failed to get prop: " + prop);
        }
        return result == null ? default : result;
    }
And simply invoke it to get the returned property, for example:
Code:
String prop = getSystemProp(this, "ro.sf.lcd_density", "213");
EDIT : sorry to the guys that were @ mentionned by the code's annotations

Quote:
My Contributions
(Apps, Librairies, Roms & Guides)
 

Pimp My Rom: Website / App / Thread

dSploit: Website / Github

Flash Gordon (Flash zips without a recovery): Thread

Universal init.d: App

PlayView/CardsUI Library: Portal / Github

HoloGraph Library: Portal / Github

Ubuntu Touch for i9300: Thread

Omni nightlies for Xperia Z1: Thread

Paranoid Android builds: Thread

Revive your bricked p68xx : Guide
Follow me on Github
The Following 6 Users Say Thank You to Androguide.fr For This Useful Post: [ Click to Expand ]
 
Tezlastorme
Old
(Last edited by Tezlastorme; 22nd August 2013 at 03:38 PM.)
#10  
Tezlastorme's Avatar
Senior Member
Thanks Meter 184
Posts: 3,344
Join Date: Mar 2012
@ whoever's code I decide to use: Thanks, I'll make use of this in my library I'll put you in the credits
Current Devices: Samsung Galaxy Nexus [maguro] (GSM), HTC Wildfire S [marvel] (GSM)
Other Devices: BlackBerry 8800: bricked
Websites: tezlastorme.tk my (blog?) site, landsofdarkan.tk
My work:
Wildfire S Root and CWM Guide
[Library]Build.prop Tools
I have hidden the rest of my sig because it was huge
 




Thread Tools Search this Thread
Search this Thread:

Advanced Search
Display Modes