Android Framework 自定义系统选项

Android系统默认提供了一些Contont Provider,如 Contacts ProviderDocuments ProviderSettings Provider等等。这些provider源码都放在frameworks/base/core/java/android/provider文件夹中。

当我们需要自定义一些系统设置,比如在Settings界面中增加了一个设置keyguard特效的选项,当用户在Settings界面中设置了某个特效后,keyguard那边能够读取这个设置项,并做出相应的改变。很显然的这里涉及到IPC,通常我们可以自己写一个Provider,但如果你有源码就完全可以复用Android提供的已有Settings Provider,达到简洁统一。

打开frameworks/base/core/java/android/provider/Settings.java文件,导航到NameValueCache类。在这个类中你会看到很多我们熟悉的一些系统设置(WIFI、亮度等等),这些值都会储存到数据库中(系统的或者用户的)。我们在这个类中增加一个常量来标记我们新增的设置项:

public static final String KEYGUARD_TRANSITION_TYPE = "keyguard_transition_type"; 

修改完之后需要重新编译一下framework。

现在Settings Provider中有了我们需要的字段,下一步就是怎么往里存储和读取了。方法很简单,从上面Settings.java文件中可以看到有很多put和get方法,我们可以使用这些方法来对NameValueCache中声明的字段进行存取操作。

import static android.provider.Settings.System.KEYGUARD_TRANSITION_TYPE;

Settings.System.putInt(getContentResolver(),
                    KEYGUARD_TRANSITION_TYPE, value);

int currentValue = Settings.System.getInt(
                    getContentResolver(), KEYGUARD_TRANSITION_TYPE,);

Settings.System.putIntForUser(getContentResolver(),
                    KEYGUARD_TRANSITION_TYPE, value, UserHandle.USER_CURRENT);

int currentValue = Settings.System.getIntForUser(
                    getContentResolver(), KEYGUARD_TRANSITION_TYPE,
                    UserHandle.USER_CURRENT);

需要注意的是上面带有用户参数的方法(*ForUser)是Hide属性的。

最后需要一个数据监听器,这样才能做到实时更新选项:

    private static final Uri mUri = Settings.System.getUriFor(KEYGUARD_TRANSITION_TYPE);

    private final ContentObserver mObserver = new ContentObserver(new Handler()) {
        public void onChange(boolean selfChange) {
           //you can do something here
        }
    };

    getContentResolver().registerContentObserver(mUri, false, mObserver);