欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  移动技术

Android通过反射获取build.prop中的值(代码实例)

程序员文章站 2022-04-25 19:57:12
前言 我们知道system.prop文件中存储着运行的很多配置信息(具体特定平台或产品的修改信息),system.prop文件中的内容最终会被编译到build.prop文件中,当程序运行时需要某种系...

前言

我们知道system.prop文件中存储着运行的很多配置信息(具体特定平台或产品的修改信息),system.prop文件中的内容最终会被编译到build.prop文件中,当程序运行时需要某种系统状态时,会到build.prop中进行读取。android中提供了一个android.os.systemproperties类来负责读取其中的内容,并且提供了几个static的方法,可以让应用很方便地使用。

/* 
 * copyright (c) 2006 the android open source project 
 * 
 * licensed under the apache license, version 2.0 (the "license"); 
 * you may not use this file except in compliance with the license. 
 * you may obtain a copy of the license at 
 * 
 *      https://www.apache.org/licenses/license-2.0 
 * 
 * unless required by applicable law or agreed to in writing, software 
 * distributed under the license is distributed on an "as is" basis, 
 * without warranties or conditions of any kind, either express or implied. 
 * see the license for the specific language governing permissions and 
 * limitations under the license. 
 */  
  
package android.os;  
  
import java.util.arraylist;  
  
  
/** 
 * gives access to the system properties store.  the system properties 
 * store contains a list of string key-value pairs. 
 * 
 * {@hide} 
 */  
public class systemproperties  
{  
    public static final int prop_name_max = 31;  
    public static final int prop_value_max = 91;  
  
    private static final arraylist<runnable> schangecallbacks = new arraylist<runnable>();  
  
    private static native string native_get(string key);  
    private static native string native_get(string key, string def);  
    private static native int native_get_int(string key, int def);  
    private static native long native_get_long(string key, long def);  
    private static native boolean native_get_boolean(string key, boolean def);  
    private static native void native_set(string key, string def);  
    private static native void native_add_change_callback();  
  
    /** 
     * 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(string key) {  
        if (key.length() > prop_name_max) {  
            throw new illegalargumentexception("key.length > " + prop_name_max);  
        }  
        return native_get(key);  
    }  
  
    /** 
     * 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(string key, string def) {  
        if (key.length() > prop_name_max) {  
            throw new illegalargumentexception("key.length > " + prop_name_max);  
        }  
        return native_get(key, def);  
    }  
  
    /** 
     * 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 int getint(string key, int def) {  
        if (key.length() > prop_name_max) {  
            throw new illegalargumentexception("key.length > " + prop_name_max);  
        }  
        return native_get_int(key, def);  
    }  
  
    /** 
     * 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(string key, long def) {  
        if (key.length() > prop_name_max) {  
            throw new illegalargumentexception("key.length > " + prop_name_max);  
        }  
        return native_get_long(key, def);  
    }  
  
    /** 
     * 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 sensitive). 
     * 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(string key, boolean def) {  
        if (key.length() > prop_name_max) {  
            throw new illegalargumentexception("key.length > " + prop_name_max);  
        }  
        return native_get_boolean(key, def);  
    }  
  
    /** 
     * 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(string key, string val) {  
        if (key.length() > prop_name_max) {  
            throw new illegalargumentexception("key.length > " + prop_name_max);  
        }  
        if (val != null && val.length() > prop_value_max) {  
            throw new illegalargumentexception("val.length > " +  
                prop_value_max);  
        }  
        native_set(key, val);  
    }  
  
    public static void addchangecallback(runnable callback) {  
        synchronized (schangecallbacks) {  
            if (schangecallbacks.size() == 0) {  
                native_add_change_callback();  
            }  
            schangecallbacks.add(callback);  
        }  
    }  
  
    static void callchangecallbacks() {  
        synchronized (schangecallbacks) {  
            //log.i("foo", "calling " + schangecallbacks.size() + " change callbacks!");  
            if (schangecallbacks.size() == 0) {  
                return;  
            }  
            arraylist<runnable> callbacks = new arraylist<runnable>(schangecallbacks);  
            for (int i=0; i<callbacks.size(); i++) {  
                callbacks.get(i).run();  
            }  
        }  
    }  
}  

系统展示

/* 
 * copyright (c) 2006 the android open source project 
 * 
 * licensed under the apache license, version 2.0 (the "license"); 
 * you may not use this file except in compliance with the license. 
 * you may obtain a copy of the license at 
 * 
 *      https://www.apache.org/licenses/license-2.0 
 * 
 * unless required by applicable law or agreed to in writing, software 
 * distributed under the license is distributed on an "as is" basis, 
 * without warranties or conditions of any kind, either express or implied. 
 * see the license for the specific language governing permissions and 
 * limitations under the license. 
 */  
  
package android.os;  
  
import java.util.arraylist;  
  
  
/** 
 * gives access to the system properties store.  the system properties 
 * store contains a list of string key-value pairs. 
 * 
 * {@hide} 
 */  
public class systemproperties  
{  
    public static final int prop_name_max = 31;  
    public static final int prop_value_max = 91;  
  
    private static final arraylist<runnable> schangecallbacks = new arraylist<runnable>();  
  
    private static native string native_get(string key);  
    private static native string native_get(string key, string def);  
    private static native int native_get_int(string key, int def);  
    private static native long native_get_long(string key, long def);  
    private static native boolean native_get_boolean(string key, boolean def);  
    private static native void native_set(string key, string def);  
    private static native void native_add_change_callback();  
  
    /** 
     * 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(string key) {  
        if (key.length() > prop_name_max) {  
            throw new illegalargumentexception("key.length > " + prop_name_max);  
        }  
        return native_get(key);  
    }  
  
    /** 
     * 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(string key, string def) {  
        if (key.length() > prop_name_max) {  
            throw new illegalargumentexception("key.length > " + prop_name_max);  
        }  
        return native_get(key, def);  
    }  
  
    /** 
     * 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 int getint(string key, int def) {  
        if (key.length() > prop_name_max) {  
            throw new illegalargumentexception("key.length > " + prop_name_max);  
        }  
        return native_get_int(key, def);  
    }  
  
    /** 
     * 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(string key, long def) {  
        if (key.length() > prop_name_max) {  
            throw new illegalargumentexception("key.length > " + prop_name_max);  
        }  
        return native_get_long(key, def);  
    }  
  
    /** 
     * 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 sensitive). 
     * 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(string key, boolean def) {  
        if (key.length() > prop_name_max) {  
            throw new illegalargumentexception("key.length > " + prop_name_max);  
        }  
        return native_get_boolean(key, def);  
    }  
  
    /** 
     * 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(string key, string val) {  
        if (key.length() > prop_name_max) {  
            throw new illegalargumentexception("key.length > " + prop_name_max);  
        }  
        if (val != null && val.length() > prop_value_max) {  
            throw new illegalargumentexception("val.length > " +  
                prop_value_max);  
        }  
        native_set(key, val);  
    }  
  
    public static void addchangecallback(runnable callback) {  
        synchronized (schangecallbacks) {  
            if (schangecallbacks.size() == 0) {  
                native_add_change_callback();  
            }  
            schangecallbacks.add(callback);  
        }  
    }  
  
    static void callchangecallbacks() {  
        synchronized (schangecallbacks) {  
            //log.i("foo", "calling " + schangecallbacks.size() + " change callbacks!");  
            if (schangecallbacks.size() == 0) {  
                return;  
            }  
            arraylist<runnable> callbacks = new arraylist<runnable>(schangecallbacks);  
            for (int i=0; i<callbacks.size(); i++) {  
                callbacks.get(i).run();  
            }  
        }  
    }  
}  

工具类源码展示

因为systemproperties.java类已被系统隐藏,因此我们通过java反射机制获取该类内容,通过get和set方法来读取、设置build.prop里面的内容。

package com.mufeng.testproject.tools;  
  
import android.content.context;  
import android.util.log;  
  
import java.io.file;  
import java.io.ioexception;  
import java.lang.reflect.method;  
  
import dalvik.system.dexfile;  
  
/** 
 * created by zhangqing on 2017/3/1. 
 */  
public class systempropertiesproxy {  
    public static final string tag = "systempropertiesproxy";  
  
    /** 
     * 根据给定的key返回string类型的值 
     * 
     * @param context 上下文 
     * @param key     获取指定信息所需的key 
     * @return 返回一个string类型的值,如果不存在该key则返回空字符串 
     */  
    public static string getstring(context context, string key) {  
        string result = "";  
        try {  
            classloader classloader = context.getclassloader();  
            @suppresswarnings("rawtypes")  
            class systemproperties = classloader.loadclass("android.os.systemproperties");  
            //参数类型  
            @suppresswarnings("rawtypes")  
            class[] paramtypes = new class[1];  
            paramtypes[0] = string.class;  
            method getstring = systemproperties.getmethod("get", paramtypes);  
            //参数  
            object[] params = new object[1];  
            params[0] = new string(key);  
  
            result = (string) getstring.invoke(systemproperties, params);  
        } catch (illegalargumentexception e) {  
            //e.printstacktrace();  
            //如果key超过32个字符则抛出该异常  
            log.w(tag, "key超过32个字符");  
        } catch (exception e) {  
            result = "";  
        }  
        return result;  
    }  
  
    /** 
     * 根据给定的key返回string类型的值 
     * 
     * @param context 上下文 
     * @param key     获取指定信息所需的key 
     * @param def     key不存在时的默认值 
     * @return 返回一个string类型的值,如果key不存在, 并且如果def不为null则返回def,否则返回空字符串 
     */  
    public static string getstring(context context, string key, string def) {  
        string result = def;  
        try {  
            classloader classloader = context.getclassloader();  
            @suppresswarnings("rawtypes")  
            class systemproperties = classloader.loadclass("android.os.systemproperties");  
            //参数类型  
            @suppresswarnings("rawtypes")  
            class[] paramtypes = new class[2];  
            paramtypes[0] = string.class;  
            paramtypes[1] = string.class;  
            method getstring = systemproperties.getmethod("get", paramtypes);  
            //参数  
            object[] params = new object[2];  
            params[0] = new string(key);  
            params[1] = new string(def);  
  
            result = (string) getstring.invoke(systemproperties, params);  
        } catch (illegalargumentexception e) {  
            //e.printstacktrace();  
            //如果key超过32个字符则抛出该异常  
            log.w(tag, "key超过32个字符");  
        } catch (exception e) {  
            result = def;  
        }  
        return result;  
    }  
  
    /** 
     * 根据给定的key返回int类型的值 
     * 
     * @param context 上下文 
     * @param key     要查询的key 
     * @param def     默认返回值 
     * @return 返回一个int类型的值,如果没有发现则返回默认值 def 
     */  
    public static integer getint(context context, string key, int def) {  
        integer result = def;  
        try {  
            classloader classloader = context.getclassloader();  
            @suppresswarnings("rawtypes")  
            class systemproperties = classloader.loadclass("android.os.systemproperties");  
            //参数类型  
            @suppresswarnings("rawtypes")  
            class[] paramtypes = new class[2];  
            paramtypes[0] = string.class;  
            paramtypes[1] = int.class;  
            method getint = systemproperties.getmethod("getint", paramtypes);  
            //参数  
            object[] params = new object[2];  
            params[0] = new string(key);  
            params[1] = new integer(def);  
            result = (integer) getint.invoke(systemproperties, params);  
        } catch (illegalargumentexception e) {  
            //e.printstacktrace();  
            //如果key超过32个字符则抛出该异常  
            log.w(tag, "key超过32个字符");  
        } catch (exception e) {  
            result = def;  
        }  
        return result;  
    }  
  
    /** 
     * 根据给定的key返回long类型的值 
     * 
     * @param context 上下文 
     * @param key     要查询的key 
     * @param def     默认返回值 
     * @return 返回一个long类型的值,如果没有发现则返回默认值def 
     */  
    public static long getlong(context context, string key, long def) {  
        long result = def;  
        try {  
            classloader classloader = context.getclassloader();  
            @suppresswarnings("rawtypes")  
            class systemproperties = classloader.loadclass("android.os.systemproperties");  
            //参数类型  
            @suppresswarnings("rawtypes")  
            class[] paramtypes = new class[2];  
            paramtypes[0] = string.class;  
            paramtypes[1] = long.class;  
            method getlong = systemproperties.getmethod("getlong", paramtypes);  
            //参数  
            object[] params = new object[2];  
            params[0] = new string(key);  
            params[1] = new long(def);  
            result = (long) getlong.invoke(systemproperties, params);  
        } catch (illegalargumentexception e) {  
            //e.printstacktrace();  
            //如果key超过32个字符则抛出该异常  
            log.w(tag, "key超过32个字符");  
        } catch (exception e) {  
            result = def;  
        }  
        return result;  
    }  
  
    /** 
     * 根据给定的key返回boolean类型的值 
     * 如果值为'n','no','0','false' or 'off'返回false 
     * 如果值为'y','yes','1','true' or 'on'返回true 
     * 如果key不存在, 或者是其它的值, 则返回默认值 
     * 
     * @param context 上下文 
     * @param key     要查询的key 
     * @param def     默认返回值 
     * @return 返回一个boolean类型的值,如果没有发现则返回默认值def 
     */  
    public static boolean getboolean(context context, string key, boolean def) {  
        boolean result = def;  
        try {  
            classloader classloader = context.getclassloader();  
            @suppresswarnings("rawtypes")  
            class systemproperties = classloader.loadclass("android.os.systemproperties");  
            //参数类型  
            @suppresswarnings("rawtypes")  
            class[] paramtypes = new class[2];  
            paramtypes[0] = string.class;  
            paramtypes[1] = boolean.class;  
            method getboolean = systemproperties.getmethod("getboolean", paramtypes);  
            //参数  
            object[] params = new object[2];  
            params[0] = new string(key);  
            params[1] = new boolean(def);  
            result = (boolean) getboolean.invoke(systemproperties, params);  
        } catch (illegalargumentexception e) {  
            //e.printstacktrace();  
            //如果key超过32个字符则抛出该异常  
            log.w(tag, "key超过32个字符");  
        } catch (exception e) {  
            result = def;  
        }  
        return result;  
    }  
  
    /** 
     * 根据给定的key和值设置属性, 该方法需要特定的权限才能操作. 
     * 
     * @param context 上下文 
     * @param key     设置属性的key 
     * @param val     设置属性的value 
     */  
    public static void set(context context, string key, string val) {  
        try {  
            @suppresswarnings("rawtypes")  
            dexfile df = new dexfile(new file("/system/app/settings.apk"));  
            classloader classloader = context.getclassloader();  
            @suppresswarnings("rawtypes")  
            class systemproperties = class.forname("android.os.systemproperties");  
            //参数类型  
            @suppresswarnings("rawtypes")  
            class[] paramtypes = new class[2];  
            paramtypes[0] = string.class;  
            paramtypes[1] = string.class;  
            method set = systemproperties.getmethod("set", paramtypes);  
            //参数  
            object[] params = new object[2];  
            params[0] = new string(key);  
            params[1] = new string(val);  
            set.invoke(systemproperties, params);  
        } catch (illegalargumentexception e) {  
            //e.printstacktrace();  
            //如果key超过32个字符或者value超过92个字符则抛出该异常  
            log.w(tag, "key超过32个字符或者value超过92个字符");  
        } catch (exception e) {  
            e.printstacktrace();  
        }  
    }  
}