开发的时候,我们经常会有这样的一种需求:
在什么位置(如db)保存一个变量,可以跨应用的读写此值。
我们可以在system.prop中定义一个宏开关,可以很好的实现此目的。
参考:
android system.prop使用(1)
android Systemproperties数据读写
先看一个framework本身就有的一个变量:
config_sms_ringtone_incall
定义此变量:
./frameworks/base/core/res/res/values/symbols.xml:
type="bool" name="config_sms_ringtone_incall" />
./frameworks/base/core/res/res/values/config.xml
<bool name="config_sms_ringtone_incall">truebool>
在java文件中的读取此变量:
./frameworks/base/services/core/java/com/android/server/notification/NotificationManagerService.java
boolean smsRingtone = getContext().getResources().getBoolean(
com.android.internal.R.bool.config_sms_ringtone_incall);
我们可以参考上面的例子,也添加一个宏开关:
config_gesture_mode
定义此变量:
./frameworks/base/core/res/res/values/symbols.xml:
type="bool" name="config_gesture_mode" />
./frameworks/base/core/res/res/values/config.xml:
<bool name="config_gesture_mode">falsebool>
读取方式:
context.getResources().getBoolean(com.android.internal.R.bool.config_gesture_mode)
SettingProvider本质是使用contentprovider的跨应用的特性来实现此需求的。
我们先看一个已有的样例:
wifi_scan_always_enabled
定义变量:
./frameworks/base/core/java/android/provider/Settings.java
public static final String WIFI_SCAN_ALWAYS_AVAILABLE =
"wifi_scan_always_enabled";
定义默认值:
./frameworks/base/packages/SettingsProvider/res/values/defaults.xml
<integer name="def_wifi_scan_always_available">0integer>
将默认值给其赋值:
./frameworks/base/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java
loadIntegerSetting(stmt, Settings.Global.WIFI_SCAN_ALWAYS_AVAILABLE,
R.integer.def_wifi_scan_always_available);
读写方式:
import android.provider.Settings;
import android.provider.Settings.Global;
Settings.Global.putInt(getContentResolver(),
Settings.Global.WIFI_SCAN_ALWAYS_AVAILABLE, 1);
android.provider.Settings.Global.getInt(getActivity().getContentResolver(), android.provider.Settings.Global.WIFI_SCAN_ALWAYS_AVAILABLE, 0)
我们参考此方式,来添加一个宏开关:
leather_sheath
在./frameworks/base/core/java/android/provider/Settings.java文件中定义变量:
public static final String LEATHER_SHEATH = "leather_sheath";
在frameworks/base/packages/SettingsProvider/res/values/defaults.xml定义一个值:
<bool name="def_leather_sheath">truebool>
将默认值给其赋值:
在./frameworks/base/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java文件中:
loadBooleanSetting(stmt, Settings.Secure.LEATHER_SHEATH, R.bool.def_leather_sheath);
读取方式:
import android.provider.Settings;
Settings.Secure.getInt(mContext.getContentResolver(), Settings.Secure.LEATHER_SHEATH, 0)
Settings.Secure.putInt(mContext.getContentResolver(), Settings.Secure.LEATHER_SHEATH, state);
(注):
今天无意中发现,原来,我们不需要在framework下来定义这个db字段,可以直接在app层来新增加一个字段,然后直接使用。
比如:
import android.provider.Settings;
//新增加一个test_set_db,给其赋值
Settings.System.putInt(context.getContentResolver(), "test_set_db", 1);
//新增加一个test_set_db,获取其值
Settings.System.getInt(context.getContentResolver(), "test_set_db", 0)
以上是三种添加全局变量宏开关的方法,其优势和不足大家自己比较,选择自己需要的方式。