1.ContentProvider概念
目的:在应用程序之间交换(共享)数据。
当一个应用程序需要把自己的数据暴露给其他程序使用时,该应用程序就可以通过提供ContentProvider来实现;
其他应用程序可以通ContentResolve来操作ContentProvider暴露的数据。
一个应用程序通过
ContentProvider暴露了自己的数据操作接口,那么不管该应用程序是否启动,其他应用程序都可以通过该接口来操作该应用程序的内部数据。
2.开发
ContentProvider的步骤
(1)定义自己的
ContentProvider类,需要继承
ContentProvider基类,实现一系列方法。
(2)在Manifest文件中注册该
ContentProvider。
3.主要实现方法
OnCreate:在
ContentProvider创建后会被调用,当其他应用程序第一次访问
ContentProvider时,该
ContentProvider会被创建,并立即回调该OnCreate方法。一般在onCreate方法中打开数据库。
insert:插入
delete:删除
update:更新
query:查询
4.Uri概念
例:content://mstar.tv.usersetting.backup/systemsetting
包括3个部分:
content:// Android规定
mstar.tv.usersetting.backup ContentProvider的authority,系统根据这个来找到操作哪个ContentProvider
systemsetting 资源
(数据部分),当访问者需要访问不同的数据时,这个部分是变化的
Android 提供的Uri工具类提供了parse()静态方法将一个字符串转换成Uri
Uri uri = Uri.parse("content://xxx/xx");
5.
UriMatcher工具类
6.使用ContentResolver来操作数据
开发
ContentProvider时实现的增删改查方法都需要一个Uri参数,该参数决定了对哪个Uri执行数据操作。
为了确定该
ContentProvider实际能匹配的Uri,以及确定每个方法中Uri参数所操作的数据,Android提供了UriMatcher工具类。
提供2个主要方法:
void addURI(String authority,String path,int code) //像UriMatcher对象注册Uri,其中authority和path组成一个Uri
int matcher(Uri uri) //根据注册的Uri来判断指定Uri的标识码,找不到则返回-1
public static final String AUTHORITY = "mstar.tv.usersetting";
private static final UriMatcher s_urlMatcher = new UriMatcher(UriMatcher.NO_MATCH);
private static final int URL_VideoSetting = 180;
private String VideoSetting = "tbl_VideoSetting";
s_urlMatcher.addURI(AUTHORITY, "videosetting", URL_VideoSetting);
public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) {
SQLiteQueryBuilder qb = new SQLiteQueryBuilder();
int match = s_urlMatcher.match(uri);
switch (match) {
case URL_VideoSetting:
qb.setTables(VideoSetting);
break;
case URL_VideoSetting_ID:
qb.setTables(VideoSetting);
qb.appendWhere("InputSrcType = " + uri.getLastPathSegment());
break;
case URL_DlpSetting:
qb.setTables(DlpSetting);
break;
}
Cursor c = qb.query(userSettingDB, projection, selection, selectionArgs, null, null,
sortOrder);
c.setNotificationUri(getContext().getContentResolver(), uri);
return c;
}
6.使用ContentResolver来操作数据
Cursor cursor = getContentResolver().query(
Uri.parse("content://mstar.tv.factory/nonlinearadjust"), null,
"InputSrcType = " + com.GetCurrentInputSource().ordinal(), null,
"CurveTypeIndex");
ContentResolver调用query等方法,实际上是调用制定Uri对应的ContentProvider的query等方法。
7.ContentObserve介绍
为了在应用程序中监听ContentProvider数据的改变,需要利用Android提供的ContentObserver类
监听ContentProvider数据改变的监听器需要继承ContentObserver类,并重写该类所定义的onChange(boolean selfChange)方法----当它所监听的ContentProvider数据发生改变时,该onChange将会被触发。
为了监听指定
ContentProvider的数据变化,需要通过ContentResolver
像指定Uri注册
ContentObserver监听器。
ContentResolver提供如下方法来注册监听器:
registerContentObserver(Uri uri,boolean notifyForDescendents,ContentObserver observer)
uri:该监听器所监听的
ContentProvider的Uri
notifyForDescendents:如果该参数设置为true,假如注册监听的Uri为content://abc,那么Uri为content://abc/xyz,
content://abc/xyz/foo的数据改变时也会触发该监听器;如果设置为false,
假如注册监听的Uri为content://abc,那么只有
content://abc的数据发生改变时会触发该监听器。
observer:监听器实例。
public final static short T_VideoSetting_IDX = 0x22;
private TVObserver observer_VideoSetting = new TVObserver(handler,
DataBaseDesk.T_VideoSetting_IDX);
private class TVObserver extends ContentObserver
{
private int matchIdx = 0;
public TVObserver(Handler handler, int observerIdx)
{
super(handler);
matchIdx = observerIdx;
}
public void onChange(boolean selfChange)
{
Log.e("DataBaseDeskImpl", "===========>>>> now change Index = "
+ matchIdx);
switch (matchIdx)
{
case DataBaseDesk.T_VideoSetting_IDX:
queryAllVideoPara(CommonDeskImpl.getInstance()
.GetCurrentInputSource().ordinal());
break;
case DataBaseDesk.T_SystemSetting_IDX:
queryUserSysSetting();
break;
case DataBaseDesk.T_SubtitleSetting_IDX:
queryUserSubtitleSetting();
break;
case DataBaseDesk.T_USER_COLORTEMP_EX_IDX:
queryUsrColorTmpExData();
break;
case DataBaseDesk.T_BackLightSetting_IDX:
queryFactoryBackLightSettingData();
break;
case DataBaseDesk.T_FacrotyColorTempEx_IDX:
queryFactoryColorTempExData();
break;
}
}
}
getContentResolver().registerContentObserver(
Uri.parse("content://mstar.tv.usersetting/videosetting/"), true,
observer_VideoSetting);
public class TvSystemBackupProvider extends ContentProvider {
private final String TAG = "TvSystemBackupProvider";
private SQLiteDatabase SystemBackupDB;
private HandlerThread systemBackupThread = new HandlerThread(
"com.mstar.android.tv.system.backup.handler");
private Handler systemBackupHandler = null;
public static final String AUTHORITY_SYSTEM_BACKUP = "mstar.tv.system.backup";
private static final UriMatcher system_backup_urlMatcher = new UriMatcher(
UriMatcher.NO_MATCH);
private static final int dbRefreshCNT = 30;
private static final int URL_BACKUP_BackLightSetting = 0;
private static final int URL_BACKUP_BackLightSetting_ID = 1;
private static final int URL_BACKUP_FactoryColorTemp = 4;
private String BackLightSetting = "tbl_BackLightSetting";
static {
system_backup_urlMatcher.addURI(AUTHORITY_SYSTEM_BACKUP,
"backlightsetting", URL_BACKUP_BackLightSetting);
system_backup_urlMatcher.addURI(AUTHORITY_SYSTEM_BACKUP,
"backlightsetting/panelid/#", URL_BACKUP_BackLightSetting_ID);
}
@Override
public boolean onCreate() {
openDB();
systemBackupThread.start();
systemBackupHandler = new Handler(systemBackupThread.getLooper());
return (SystemBackupDB == null) ? false : true;
}
@Override
public Cursor query(Uri uri, String[] projection, String selection,
String[] selectionArgs, String sortOrder) {
SQLiteQueryBuilder qb = new SQLiteQueryBuilder();
int match = system_backup_urlMatcher.match(uri);
switch (match) {
case URL_BACKUP_BackLightSetting: {
qb.setTables(BackLightSetting);
break;
}
case URL_BACKUP_BackLightSetting_ID: {
qb.setTables(BackLightSetting);
qb.appendWhere("PanelID = " + uri.getLastPathSegment());
break;
}
}
Cursor c = qb.query(SystemBackupDB, projection, selection, null, null,
null, sortOrder);
c.setNotificationUri(getContext().getContentResolver(), uri);
return c;
}
@Override
public int delete(Uri uri, String where, String[] whereArgs) {
return -1;
}
@Override
public String getType(Uri uri) {
return null;
}
@Override
public Uri insert(Uri uri, ContentValues values) {
return null;
}
@Override
public int update(Uri uri, ContentValues values, String where,
String[] whereArgs) {
return 0;
}
private void openDB() {
int retry = 0;
if ((SystemBackupDB == null) || (!SystemBackupDB.isOpen())) {
while (retry < 20) {
try {
SystemBackupDB = SQLiteDatabase.openDatabase(
"/svtfilesystem/SysDatabaseBackup/system.db", null,
SQLiteDatabase.OPEN_READONLY
| SQLiteDatabase.NO_LOCALIZED_COLLATORS);
} catch (SQLiteException e) {
Log.e(TAG, "================>>>>>> open db fail,retry ...");
retry++;
SystemBackupDB = null;
if (retry >= 20) {
Log.e("SystemProvider",
"!!!!!!!!!!open db fail,Please check sw bug!!!!!!!!");
}
} finally {
if (SystemBackupDB != null) {
Log.e("SystemProvider",
"================>>>>>> open db success");
retry = 20;
}
}
}
}
}
private void closeDB() {
SystemBackupDB.close();
}
@Override
public void shutdown() {
super.shutdown();
closeDB();
}
}
<provider android:name="com.mstar.android.providers.tvbackup.TvSystemBackupProvider"
android:authorities="mstar.tv.system.backup"
android:syncable="false" android:multiprocess="false"
android:exported="true"
android:permission="com.mstar.android.permissionn.ACCESS_TV_DATA"/>