在工程项目中,为什么vendor目录下的platformconfigs.xml文件可以对部分手机的属性特性进行设置?

答:在framework目录下,android.provider.Settings文件为这种方式提供了可能。通过官方文档对其描述:“The Settings provider contains global system-level device preferences.”。即android.provider.Setttings类是为设备系统提供全局的、系统级别的设备属性。在Settings类中,包含五个外部可以访问的内部类:   
Setttings.Global: 为设备系统提供全局的系统属性,该属性特性对设备上的任何用户都是无差别的。   
Settings.NameValueTable: 根据key-value的组合,作为数据库中表的公共基础。

    public static class NameValueTable implements BaseColumns {        public static final String NAME = "name";        public static final String VALUE = "value";        protected static boolean putString(ContentResolver resolver, Uri uri,                String name, String value) {            // The database will take care of replacing duplicates.            try {                ContentValues values = new ContentValues();                values.put(NAME, name);                values.put(VALUE, value);                resolver.insert(uri, values);                return true;            } catch (SQLException e) {                Log.w(TAG, "Can't set key " + name + " in " + uri, e);                return false;            }        }        public static Uri getUriFor(Uri uri, String name) {            return Uri.withAppendedPath(uri, name);        }    }

Settings:Secure: 仅仅只有读权限,而没有写权限的系统属性。
Settings.SettingNotFoundException: 未找到系统属性的异常处理,
Settings.System: 各类的系统系统属性。

如果想添加一个系统属性,既可以在该文件中进行添加相应的属性内容。比如:希望添加一个全局性的属性,即可以在Settings.Global类进行处理:
```
public static final String AIRPLANE_MODE_ON = "airplane_mode_on";

public static final String[] SETTINGS_TO_BACKUP = {
            ~~~~~
            AIRPLANE_MODE_ON,
            ~~~~~
```
可以通过
```
Settings.Global.getInt(getContentResolver(), Settings.Global.AIRPLANE_MODE_ON,0);
Settings.Global.putInt(getContentResolver(), Settings.Global.AIRPLANE_MODE_ON,0);
```
去得到和设置“AIRPLANE_MODE_ON”的属性值。那么,PlatformConfigs.xml文件中的属性值,是如何写入到系统级文件build.prop文件中的呢?   
答:在build/core/Makefile中,可以发现有这样一段内容:

# platform properties, which will be writen to build.propPLATFORM_PROPERTIES_SH := $(PWD)/vendor/tinno/platform/configs/$(TARGET_PRODUCT)/$(PROJECT_NAME)/PlatformConfigs    # add for platform configs    @if [ -f "$(PLATFORM_PROPERTIES_SH)" ]; then \            echo 'PLATFORM_PROPERTIES_SH exits'; \            echo >> $@; \      echo "#" >> $@; \      echo "# PLATFORM_PROPERTIES START" >> $@; \      echo "#" >> $@; \            while read word; do \                    if [ -n "$$word" ]; then \                        echo "the word = $$word"; \                        key=`echo "$$word" | cut -d = -f 1`; \                        echo "the key = $$key"; \                        value=`echo "$$word" | cut -d = -f 2`; \                        echo "the value = $$value"; \                        sed -i "/^$$key=/d" $@; \                        echo "$$word" >> $@;    \                    fi; \            done < $(PLATFORM_PROPERTIES_SH); \      echo "#" >> $@; \      echo "# PLATFORM_PROPERTIES END" >> $@; \      echo "#" >> $@; \    fi;


从这段脚本可以发现,其将PlatformConfig.xml的属性值写到build.prop文件上。

1. Android里拥有很多属性,每一个属性都有一个名称和值,类似于Map的方式。这些属性可以在开机启动时预先设定,亦可以是动态加载的。
系统启动时,将分别以相面的次序加载预先设定的Android属性。如果出现了重名属性,那么后者可以覆盖前者的属性值,即后者的优先级高于前者。


/default.prop ->
/system/build.prop ->
/system/default.prop -> 
/data/local.prop ->
/data/property/* 

persist.*  : 以persist开始的属性会在 /data/property 存一个副本。也就是说,如果程序调用property_set设以persist为前缀的属性,系统会在 /data/property/* 记录下这个属性的副本,重启以后,这个属性依然存在。有点类似于持久化技术。如果调用property_set以非 persist 为前缀的属性,这个属性仅仅存在于手机运存中,在手机重启后,这个属性就初始化了。(pt)

ro.* : 不能修改,即表示系统属性。当然手机开发者可以对源代码进行修改。(read only)


2. 在应用程序属性使用方法


```
import android.os.SystemProperties; 
SystemProperties.set("persist.sys.country",”china”); 
```
在java里取得属性:
```
String vmHeapSize = SystemProperties.get("dalvik.vm.heapgrowthlimit", "24m"); 
```
也可以用SystemProperties.getBoolean,getInt等


3. 属性初始化的入口点是property_init ,在system/core/init/property_service.c中定义。它的主要工作是申请32k共享内存,其中前1k是属性区的头,后面31k可以存247个属性(受前1k头的限制)。property_init初始化完property以后,加载/default.prop的属性定义。 

其它的系统属性(build.prop, local.prop,…)在start_property_service中加载。加载完属性服务创建一个socket和其他
进程通信(设置或读取属性)。 


> Init进程poll属性的socket,等待和处理属性请求。如果有请求到来,则调用handle_property_set_fd来处理这个请求。在这个函数里,首先检查请求者的uid/gid看看是否有权限,如果有权限则调property_service.c中的property_set函数。 

>  在property_set函数中,它先查找就没有这个属性,如果找到,更改属性。如果找不到,则添加新属性。更改时还会判断是不是“ro”属性,如果是,则不能更改。如果是persist的话还会写到/data/property/中。 

>  最后它会调property_changed,把事件挂到队列里,如果有人注册这个属性的话(比如init.rc中on property:ro.kernel.qemu=1),最终会调它的会调函数。 

 

当然,对于在PlatformConfigs.xml文件中,有些属性可以使用**SystemProperties**(SystemProperties位于frameworks/base/core/java/android/os中)来进行管理。如果用户需要对某些属性进行全局的处理,即可以在PlatformConfigs.xml文件中添加相应的宏。示例:
java代码:
```
    import android.os.SystemProperties;
    String value = SystemProperties.get("ro.pt.show_photos_name", "false");
```

PlatformConfigs.xml
```
 



```

再来看看源码:

package android.os;import java.util.ArrayList;public class SystemProperties{    public static final int PROP_NAME_MAX = 31;    public static final int PROP_VALUE_MAX = 91;    private static final ArrayList sChangeCallbacks = new ArrayList();    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();    public static String get(String key) {        if (key.length() > PROP_NAME_MAX) {            throw new IllegalArgumentException("key.length > " + PROP_NAME_MAX);        }        return native_get(key);    }    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);    }    public static boolean is_target(final String s) {    return get("ro.target", "").equals(s);    }    public static boolean is_project(final String s) {    return get("ro.project", "").equals(s);    }    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);    }    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);    }    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);    }    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 callbacks = new ArrayList(sChangeCallbacks);            for (int i=0; i

---
 


除了SystemProperties可以增加全局宏控外,还可以使用Context.getResource()方法,来处理相应模块的属性设置。该方法先在strings.xml、config.xml文件中定义各种字符类型,然后在java源码中调用。

```

boolean_value


boolean str= getResources().getBoolean(R.bool.test_about);
```

在 Android 代码中,如果需要对 CPP 等 c 语言文件的代码块进行宏控,那么需要采用采用三个步骤。

1. 在对应模块下的 Android.mk 文件中进行处理

+ifeq ($(strip $(FEATURE_FINERPRINT_CAMERA_SURPORT)), yes)+LOCAL_CFLAGS += -DMM_FINERPRINT_CAMEEA+endif

这里 LOCAL_CFLAGS += -DXXXX, XXXX 是一个CPP文件的宏控属性。

2. 在C 语言文件中

#ifdef MM_FINERPRINT_CAMEEA  property_set("sys.fp_camshot.enable", "false");#endif

3. 在 ProjectConfig.mk

FEATURE_FINERPRINT_CAMERA_SURPORT := yes

 

更多相关文章

  1. 一款常用的 Squid 日志分析工具
  2. GitHub 标星 8K+!一款开源替代 ls 的工具你值得拥有!
  3. RHEL 6 下 DHCP+TFTP+FTP+PXE+Kickstart 实现无人值守安装
  4. Linux 环境下实战 Rsync 备份工具及配置 rsync+inotify 实时同步
  5. Nginx系列教程(六)| 手把手教你搭建 LNMP 架构并部署天空网络电影
  6. Android判断当前系统时间是否在指定时间的范围内(免消息打扰)
  7. android adb命令打印logcat日志 到指定目录
  8. 利用Android(安卓)Studio将Protobuf文件生成Java文件
  9. android 怎么动态设置button 的style

随机推荐

  1. android在java代码中绘制矩形框
  2. android 复制、粘贴字符串 (判断API 11 )
  3. Android的权限permission
  4. android 开发上传图片遇到返回 FileNotFo
  5. 11.时钟&计时器
  6. Android ListView(Selector 背景图片 全选
  7. Android碎片积累
  8. Android核心基础(五)
  9. 第12天android:短信发送+测试使用
  10. Android中NDK各版本下载