继上次分析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按倒着的顺序来做^-^.
版权声明:本文为博主原创文章,未经博主允许不得转载。