Android系统SettingsPrivider分析与修改方法

来源:互联网 发布:如何查看网络是否稳定 编辑:程序博客网 时间:2024/04/27 19:46

        继上次分析Settings的文章Android 系统Settings概要之后,现要增加一些系统中没有的设置项,因上次只是猜测DatabaseHelper.java 在创建数据库时将defaults.xml中的配制存入了数据库中,因此现在来分析下SettingsPrivider源码(源码还是官方android-4.4_r1版本).

第一,主要分析DatabaseHelper.java文件:

    1. 数据库文件为 settings.db  定义的表有人个 ,里面system , secure ,global 是比主要的三个。

    private static final String TAG = "SettingsProvider";    private static final String DATABASE_NAME = "settings.db";    // Please, please please. If you update the database version, check to make sure the    // database gets upgraded properly. At a minimum, please confirm that 'upgradeVersion'    // is properly propagated through your change.  Not doing so will result in a loss of user    // settings.    private static final int DATABASE_VERSION = 98;    private Context mContext;    private int mUserHandle;    private static final HashSet<String> mValidTables = new HashSet<String>();    private static final String TABLE_SYSTEM = "system";    private static final String TABLE_SECURE = "secure";    private static final String TABLE_GLOBAL = "global";    static {        mValidTables.add(TABLE_SYSTEM);        mValidTables.add(TABLE_SECURE);        mValidTables.add(TABLE_GLOBAL);        mValidTables.add("bluetooth_devices");        mValidTables.add("bookmarks");        // These are old.        mValidTables.add("favorites");        mValidTables.add("gservices");        mValidTables.add("old_favorites");    }

   2. 看onCreate()方法,创建表和各表的索引,然后调用了loadBookmarks(db); loadVolumeLevels(db);  loadSettings(db); 三个方法,loadBookmarks(db);是存系统几个常用的应用的intent ( 如,通讯录app,emailApp, 短信app,),loadVolumeLevels(db); 初始化的是与声音相关的配制,  loadSettings(db);方法就是从defaults.xml文件中读取默认值存入相应的表中,验证了之前 的猜测。

    @Override    public void onCreate(SQLiteDatabase db) {        db.execSQL("CREATE TABLE system (" +                    "_id INTEGER PRIMARY KEY AUTOINCREMENT," +                    "name TEXT UNIQUE ON CONFLICT REPLACE," +                    "value TEXT" +                    ");");        db.execSQL("CREATE INDEX systemIndex1 ON system (name);");        createSecureTable(db);        // Only create the global table for the singleton 'owner' user        if (mUserHandle == UserHandle.USER_OWNER) {            createGlobalTable(db);        }        db.execSQL("CREATE TABLE bluetooth_devices (" +                    "_id INTEGER PRIMARY KEY," +                    "name TEXT," +                    "addr TEXT," +                    "channel INTEGER," +                    "type INTEGER" +                    ");");        db.execSQL("CREATE TABLE bookmarks (" +                    "_id INTEGER PRIMARY KEY," +                    "title TEXT," +                    "folder TEXT," +                    "intent TEXT," +                    "shortcut INTEGER," +                    "ordering INTEGER" +                    ");");        db.execSQL("CREATE INDEX bookmarksIndex1 ON bookmarks (folder);");        db.execSQL("CREATE INDEX bookmarksIndex2 ON bookmarks (shortcut);");        // Populate bookmarks table with initial bookmarks        boolean onlyCore = false;        try {            onlyCore = IPackageManager.Stub.asInterface(ServiceManager.getService(                    "package")).isOnlyCoreApps();        } catch (RemoteException e) {        }        if (!onlyCore) {            loadBookmarks(db);        }        // Load initial volume levels into DB        loadVolumeLevels(db);        // Load inital settings values        loadSettings(db);    }

3  .    loadSettings(db); 里面的三个方法者是从defaults.xml文件中读取默认值存入相应的表中,loadSystemSettings(db)是存入System表中,loadSecureSettings(db)是存入 secure表中。

    

private void loadSettings(SQLiteDatabase db) {        loadSystemSettings(db);        loadSecureSettings(db);        // The global table only exists for the 'owner' user        if (mUserHandle == UserHandle.USER_OWNER) {            loadGlobalSettings(db);        }    }


loadSetting()方法中SQLiteStatement将值存入了数据库中:

 private void loadSystemSettings(SQLiteDatabase db) {        SQLiteStatement stmt = null;        try {            stmt = db.compileStatement("INSERT OR IGNORE INTO system(name,value)"                    + " VALUES(?,?);");            loadBooleanSetting(stmt, Settings.System.DIM_SCREEN,                    R.bool.def_dim_screen);            //..............省略..................            loadIntegerSetting(stmt, Settings.System.POINTER_SPEED,                    R.integer.def_pointer_speed);        } finally {            if (stmt != null) stmt.close();        }    }



第二,那如何来增加设置项(例如要在设置中增加一项 账户信息):

      1. 在Settings 中增加界面相关的代码:

          1.a.    Settings/res/xml/settings_headers.xml文件中增加:

           <header
            android:id="@+id/account_info"
            android:fragment="com.android.settings.accounts.AccountInfoSettings"
            android:title="@string/account_info_label"
            android:icon="@drawable/ic_menu_add_dark"/>

         1.b.   增加字符串图标等 ,如  Settings/res/values/strings.xml文件中:
           <string name="account_info_label" >"账号信息"</string>

         1.c  相关类与代码的编写:如 创建Fragment:AccountInfoSettings 并写代码,里面的代码会Settings.System.put**的代码将操作SettingsProvider    
   
     2. 修改SettingsPrivider

       2. a   defalult.xml

         <bool name="def_acctount_islogin">false</bool>
         <string name="def_acctount_name">请设置昵称</string>

       2. b  DatabaseHelper.java 在loadSecureSettings(SQLiteDatabase db) 方法中增加

            loadBooleanSetting(stmt, Settings.Secure.ACCOUNT_ISLOGIN,
                    R.bool.def_account_islogin);
            loadStringSetting(stmt, Settings.Secure.ACCOUNT_NAME,
                    R.string.def_account_name);

      3. 在/android-4.4_r1/frameworks/base/core/java/android/provider/Settings.java 文件中找到内部静态类:public static final class Secure extends NameValueTable {..........} 在Secure类中增加:

        public static final String ACCOUNT_ISLOGIN = "def_account_islogin";
        public static final String ACCOUNT_NAME = "def_account_name";

         

     到此修改基本完成,可以编译,运行,测试了。实际开发中的步骤应该是3.2,1按倒着的顺序来做^-^.

1 0
原创粉丝点击