安卓通过反射获取build.prop中的值



  前言

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

系统源码展示

  1. /* 
  2.  * Copyright (C) 2006 The Android Open Source Project 
  3.  * 
  4.  * Licensed under the Apache License, Version 2.0 (the "License"); 
  5.  * you may not use this file except in compliance with the License. 
  6.  * You may obtain a copy of the License at 
  7.  * 
  8.  *      http://www.apache.org/licenses/LICENSE-2.0 
  9.  * 
  10.  * Unless required by applicable law or agreed to in writing, software 
  11.  * distributed under the License is distributed on an "AS IS" BASIS, 
  12.  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
  13.  * See the License for the specific language governing permissions and 
  14.  * limitations under the License. 
  15.  */  
  16.   
  17. package android.os;  
  18.   
  19. import java.util.ArrayList;  
  20.   
  21.   
  22. /** 
  23.  * Gives access to the system properties store.  The system properties 
  24.  * store contains a list of string key-value pairs. 
  25.  * 
  26.  * {@hide} 
  27.  */  
  28. public class SystemProperties  
  29. {  
  30.     public static final int PROP_NAME_MAX = 31;  
  31.     public static final int PROP_VALUE_MAX = 91;  
  32.   
  33.     private static final ArrayList<Runnable> sChangeCallbacks = new ArrayList<Runnable>();  
  34.   
  35.     private static native String native_get(String key);  
  36.     private static native String native_get(String key, String def);  
  37.     private static native int native_get_int(String key, int def);  
  38.     private static native long native_get_long(String key, long def);  
  39.     private static native boolean native_get_boolean(String key, boolean def);  
  40.     private static native void native_set(String key, String def);  
  41.     private static native void native_add_change_callback();  
  42.   
  43.     /** 
  44.      * Get the value for the given key. 
  45.      * @return an empty string if the key isn't found 
  46.      * @throws IllegalArgumentException if the key exceeds 32 characters 
  47.      */  
  48.     public static String get(String key) {  
  49.         if (key.length() > PROP_NAME_MAX) {  
  50.             throw new IllegalArgumentException("key.length > " + PROP_NAME_MAX);  
  51.         }  
  52.         return native_get(key);  
  53.     }  
  54.   
  55.     /** 
  56.      * Get the value for the given key. 
  57.      * @return if the key isn't found, return def if it isn't null, or an empty string otherwise 
  58.      * @throws IllegalArgumentException if the key exceeds 32 characters 
  59.      */  
  60.     public static String get(String key, String def) {  
  61.         if (key.length() > PROP_NAME_MAX) {  
  62.             throw new IllegalArgumentException("key.length > " + PROP_NAME_MAX);  
  63.         }  
  64.         return native_get(key, def);  
  65.     }  
  66.   
  67.     /** 
  68.      * Get the value for the given key, and return as an integer. 
  69.      * @param key the key to lookup 
  70.      * @param def a default value to return 
  71.      * @return the key parsed as an integer, or def if the key isn't found or 
  72.      *         cannot be parsed 
  73.      * @throws IllegalArgumentException if the key exceeds 32 characters 
  74.      */  
  75.     public static int getInt(String key, int def) {  
  76.         if (key.length() > PROP_NAME_MAX) {  
  77.             throw new IllegalArgumentException("key.length > " + PROP_NAME_MAX);  
  78.         }  
  79.         return native_get_int(key, def);  
  80.     }  
  81.   
  82.     /** 
  83.      * Get the value for the given key, and return as a long. 
  84.      * @param key the key to lookup 
  85.      * @param def a default value to return 
  86.      * @return the key parsed as a long, or def if the key isn't found or 
  87.      *         cannot be parsed 
  88.      * @throws IllegalArgumentException if the key exceeds 32 characters 
  89.      */  
  90.     public static long getLong(String key, long def) {  
  91.         if (key.length() > PROP_NAME_MAX) {  
  92.             throw new IllegalArgumentException("key.length > " + PROP_NAME_MAX);  
  93.         }  
  94.         return native_get_long(key, def);  
  95.     }  
  96.   
  97.     /** 
  98.      * Get the value for the given key, returned as a boolean. 
  99.      * Values 'n', 'no', '0', 'false' or 'off' are considered false. 
  100.      * Values 'y', 'yes', '1', 'true' or 'on' are considered true. 
  101.      * (case sensitive). 
  102.      * If the key does not exist, or has any other value, then the default 
  103.      * result is returned. 
  104.      * @param key the key to lookup 
  105.      * @param def a default value to return 
  106.      * @return the key parsed as a boolean, or def if the key isn't found or is 
  107.      *         not able to be parsed as a boolean. 
  108.      * @throws IllegalArgumentException if the key exceeds 32 characters 
  109.      */  
  110.     public static boolean getBoolean(String key, boolean def) {  
  111.         if (key.length() > PROP_NAME_MAX) {  
  112.             throw new IllegalArgumentException("key.length > " + PROP_NAME_MAX);  
  113.         }  
  114.         return native_get_boolean(key, def);  
  115.     }  
  116.   
  117.     /** 
  118.      * Set the value for the given key. 
  119.      * @throws IllegalArgumentException if the key exceeds 32 characters 
  120.      * @throws IllegalArgumentException if the value exceeds 92 characters 
  121.      */  
  122.     public static void set(String key, String val) {  
  123.         if (key.length() > PROP_NAME_MAX) {  
  124.             throw new IllegalArgumentException("key.length > " + PROP_NAME_MAX);  
  125.         }  
  126.         if (val != null && val.length() > PROP_VALUE_MAX) {  
  127.             throw new IllegalArgumentException("val.length > " +  
  128.                 PROP_VALUE_MAX);  
  129.         }  
  130.         native_set(key, val);  
  131.     }  
  132.   
  133.     public static void addChangeCallback(Runnable callback) {  
  134.         synchronized (sChangeCallbacks) {  
  135.             if (sChangeCallbacks.size() == 0) {  
  136.                 native_add_change_callback();  
  137.             }  
  138.             sChangeCallbacks.add(callback);  
  139.         }  
  140.     }  
  141.   
  142.     static void callChangeCallbacks() {  
  143.         synchronized (sChangeCallbacks) {  
  144.             //Log.i("foo", "Calling " + sChangeCallbacks.size() + " change callbacks!");  
  145.             if (sChangeCallbacks.size() == 0) {  
  146.                 return;  
  147.             }  
  148.             ArrayList<Runnable> callbacks = new ArrayList<Runnable>(sChangeCallbacks);  
  149.             for (int i=0; i<callbacks.size(); i++) {  
  150.                 callbacks.get(i).run();  
  151.             }  
  152.         }  
  153.     }  
  154. }  
/*
 * 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
 *
 *      http://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里面的内容。

  1. package com.mufeng.testproject.tools;  
  2.   
  3. import android.content.Context;  
  4. import android.util.Log;  
  5.   
  6. import java.io.File;  
  7. import java.io.IOException;  
  8. import java.lang.reflect.Method;  
  9.   
  10. import dalvik.system.DexFile;  
  11.   
  12. /** 
  13.  * Created by zhangqing on 2017/3/1. 
  14.  */  
  15. public class SystemPropertiesProxy {  
  16.     public static final String TAG = "SystemPropertiesProxy";  
  17.   
  18.     /** 
  19.      * 根据给定的Key返回String类型的值 
  20.      * 
  21.      * @param context 上下文 
  22.      * @param key     获取指定信息所需的key 
  23.      * @return 返回一个String类型的值,如果不存在该key则返回空字符串 
  24.      */  
  25.     public static String getString(Context context, String key) {  
  26.         String result = "";  
  27.         try {  
  28.             ClassLoader classLoader = context.getClassLoader();  
  29.             @SuppressWarnings("rawtypes")  
  30.             Class SystemProperties = classLoader.loadClass("android.os.SystemProperties");  
  31.             //参数类型  
  32.             @SuppressWarnings("rawtypes")  
  33.             Class[] paramTypes = new Class[1];  
  34.             paramTypes[0] = String.class;  
  35.             Method getString = SystemProperties.getMethod("get", paramTypes);  
  36.             //参数  
  37.             Object[] params = new Object[1];  
  38.             params[0] = new String(key);  
  39.   
  40.             result = (String) getString.invoke(SystemProperties, params);  
  41.         } catch (IllegalArgumentException e) {  
  42.             //e.printStackTrace();  
  43.             //如果key超过32个字符则抛出该异常  
  44.             Log.w(TAG, "key超过32个字符");  
  45.         } catch (Exception e) {  
  46.             result = "";  
  47.         }  
  48.         return result;  
  49.     }  
  50.   
  51.     /** 
  52.      * 根据给定的Key返回String类型的值 
  53.      * 
  54.      * @param context 上下文 
  55.      * @param key     获取指定信息所需的key 
  56.      * @param def     key不存在时的默认值 
  57.      * @return 返回一个String类型的值,如果key不存在, 并且如果def不为null则返回def,否则返回空字符串 
  58.      */  
  59.     public static String getString(Context context, String key, String def) {  
  60.         String result = def;  
  61.         try {  
  62.             ClassLoader classLoader = context.getClassLoader();  
  63.             @SuppressWarnings("rawtypes")  
  64.             Class SystemProperties = classLoader.loadClass("android.os.SystemProperties");  
  65.             //参数类型  
  66.             @SuppressWarnings("rawtypes")  
  67.             Class[] paramTypes = new Class[2];  
  68.             paramTypes[0] = String.class;  
  69.             paramTypes[1] = String.class;  
  70.             Method getString = SystemProperties.getMethod("get", paramTypes);  
  71.             //参数  
  72.             Object[] params = new Object[2];  
  73.             params[0] = new String(key);  
  74.             params[1] = new String(def);  
  75.   
  76.             result = (String) getString.invoke(SystemProperties, params);  
  77.         } catch (IllegalArgumentException e) {  
  78.             //e.printStackTrace();  
  79.             //如果key超过32个字符则抛出该异常  
  80.             Log.w(TAG, "key超过32个字符");  
  81.         } catch (Exception e) {  
  82.             result = def;  
  83.         }  
  84.         return result;  
  85.     }  
  86.   
  87.     /** 
  88.      * 根据给定的key返回int类型的值 
  89.      * 
  90.      * @param context 上下文 
  91.      * @param key     要查询的key 
  92.      * @param def     默认返回值 
  93.      * @return 返回一个int类型的值,如果没有发现则返回默认值 def 
  94.      */  
  95.     public static Integer getInt(Context context, String key, int def) {  
  96.         Integer result = def;  
  97.         try {  
  98.             ClassLoader classLoader = context.getClassLoader();  
  99.             @SuppressWarnings("rawtypes")  
  100.             Class SystemProperties = classLoader.loadClass("android.os.SystemProperties");  
  101.             //参数类型  
  102.             @SuppressWarnings("rawtypes")  
  103.             Class[] paramTypes = new Class[2];  
  104.             paramTypes[0] = String.class;  
  105.             paramTypes[1] = int.class;  
  106.             Method getInt = SystemProperties.getMethod("getInt", paramTypes);  
  107.             //参数  
  108.             Object[] params = new Object[2];  
  109.             params[0] = new String(key);  
  110.             params[1] = new Integer(def);  
  111.             result = (Integer) getInt.invoke(SystemProperties, params);  
  112.         } catch (IllegalArgumentException e) {  
  113.             //e.printStackTrace();  
  114.             //如果key超过32个字符则抛出该异常  
  115.             Log.w(TAG, "key超过32个字符");  
  116.         } catch (Exception e) {  
  117.             result = def;  
  118.         }  
  119.         return result;  
  120.     }  
  121.   
  122.     /** 
  123.      * 根据给定的key返回long类型的值 
  124.      * 
  125.      * @param context 上下文 
  126.      * @param key     要查询的key 
  127.      * @param def     默认返回值 
  128.      * @return 返回一个long类型的值,如果没有发现则返回默认值def 
  129.      */  
  130.     public static Long getLong(Context context, String key, long def) {  
  131.         Long result = def;  
  132.         try {  
  133.             ClassLoader classLoader = context.getClassLoader();  
  134.             @SuppressWarnings("rawtypes")  
  135.             Class SystemProperties = classLoader.loadClass("android.os.SystemProperties");  
  136.             //参数类型  
  137.             @SuppressWarnings("rawtypes")  
  138.             Class[] paramTypes = new Class[2];  
  139.             paramTypes[0] = String.class;  
  140.             paramTypes[1] = long.class;  
  141.             Method getLong = SystemProperties.getMethod("getLong", paramTypes);  
  142.             //参数  
  143.             Object[] params = new Object[2];  
  144.             params[0] = new String(key);  
  145.             params[1] = new Long(def);  
  146.             result = (Long) getLong.invoke(SystemProperties, params);  
  147.         } catch (IllegalArgumentException e) {  
  148.             //e.printStackTrace();  
  149.             //如果key超过32个字符则抛出该异常  
  150.             Log.w(TAG, "key超过32个字符");  
  151.         } catch (Exception e) {  
  152.             result = def;  
  153.         }  
  154.         return result;  
  155.     }  
  156.   
  157.     /** 
  158.      * 根据给定的key返回boolean类型的值 
  159.      * 如果值为'n','no','0','false' or 'off'返回false 
  160.      * 如果值为'y','yes','1','true' or 'on'返回true 
  161.      * 如果key不存在, 或者是其它的值, 则返回默认值 
  162.      * 
  163.      * @param context 上下文 
  164.      * @param key     要查询的key 
  165.      * @param def     默认返回值 
  166.      * @return 返回一个boolean类型的值,如果没有发现则返回默认值def 
  167.      */  
  168.     public static Boolean getBoolean(Context context, String key, boolean def) {  
  169.         Boolean result = def;  
  170.         try {  
  171.             ClassLoader classLoader = context.getClassLoader();  
  172.             @SuppressWarnings("rawtypes")  
  173.             Class SystemProperties = classLoader.loadClass("android.os.SystemProperties");  
  174.             //参数类型  
  175.             @SuppressWarnings("rawtypes")  
  176.             Class[] paramTypes = new Class[2];  
  177.             paramTypes[0] = String.class;  
  178.             paramTypes[1] = boolean.class;  
  179.             Method getBoolean = SystemProperties.getMethod("getBoolean", paramTypes);  
  180.             //参数  
  181.             Object[] params = new Object[2];  
  182.             params[0] = new String(key);  
  183.             params[1] = new Boolean(def);  
  184.             result = (Boolean) getBoolean.invoke(SystemProperties, params);  
  185.         } catch (IllegalArgumentException e) {  
  186.             //e.printStackTrace();  
  187.             //如果key超过32个字符则抛出该异常  
  188.             Log.w(TAG, "key超过32个字符");  
  189.         } catch (Exception e) {  
  190.             result = def;  
  191.         }  
  192.         return result;  
  193.     }  
  194.   
  195.     /** 
  196.      * 根据给定的key和值设置属性, 该方法需要特定的权限才能操作. 
  197.      * 
  198.      * @param context 上下文 
  199.      * @param key     设置属性的key 
  200.      * @param val     设置属性的value 
  201.      */  
  202.     public static void set(Context context, String key, String val) {  
  203.         try {  
  204.             @SuppressWarnings("rawtypes")  
  205.             DexFile df = new DexFile(new File("/system/app/Settings.apk"));  
  206.             ClassLoader classLoader = context.getClassLoader();  
  207.             @SuppressWarnings("rawtypes")  
  208.             Class SystemProperties = Class.forName("android.os.SystemProperties");  
  209.             //参数类型  
  210.             @SuppressWarnings("rawtypes")  
  211.             Class[] paramTypes = new Class[2];  
  212.             paramTypes[0] = String.class;  
  213.             paramTypes[1] = String.class;  
  214.             Method set = SystemProperties.getMethod("set", paramTypes);  
  215.             //参数  
  216.             Object[] params = new Object[2];  
  217.             params[0] = new String(key);  
  218.             params[1] = new String(val);  
  219.             set.invoke(SystemProperties, params);  
  220.         } catch (IllegalArgumentException e) {  
  221.             //e.printStackTrace();  
  222.             //如果key超过32个字符或者value超过92个字符则抛出该异常  
  223.             Log.w(TAG, "key超过32个字符或者value超过92个字符");  
  224.         } catch (Exception e) {  
  225.             e.printStackTrace();  
  226.         }  
  227.     }  

        

  转载于: https://blog.csdn.net/u013693649/article/details/60143634

     反射技术在安卓中的应用:https://blog.csdn.net/tiefeng0606/article/details/51700866






猜你喜欢

转载自blog.csdn.net/kai_zone/article/details/80217219