@ -14,292 +14,466 @@
* limitations under the License .
* /
package net.micode.notes. data ;
package net.micode.notes. provider ;
import android.app.SearchManager ;
import android.content.ContentProvider ;
import android.content.ContentResolver ;
import android.content.ContentUris ;
import android.content.ContentValues ;
import android.content. Inten t;
import android.content. Contex t;
import android.content.UriMatcher ;
import android.database.Cursor ;
import android.database.sqlite.SQLiteDatabase ;
import android.database.sqlite.SQLiteQueryBuilder ;
import android.net.Uri ;
import android.text.TextUtils ;
import android.util.Log ;
import net.micode.notes.R ;
import net.micode.notes.data.Notes.DataColumns ;
import net.micode.notes.data.Notes.NoteColumns ;
import net.micode.notes.data.NotesDatabaseHelper.TABLE ;
import net.micode.notes.data.Notes ;
import net.micode.notes.data.NotesDatabaseHelper ;
import java.util.HashMap ;
/ * *
* 小 米 便 签 内 容 提 供 者
* 负 责 处 理 便 签 数 据 的 CRUD 操 作
* 提 供 内 容 URI 接 口 给 外 部 应 用 访 问 便 签 数 据
* /
public class NotesProvider extends ContentProvider {
private static final UriMatcher mMatcher ;
private NotesDatabaseHelper mHelper ;
// 日志标签
private static final String TAG = "NotesProvider" ;
// 数据库帮助类
private NotesDatabaseHelper mOpenHelper ;
// 内容解析器
private ContentResolver mContentResolver ;
private static final int URI_NOTE = 1 ;
private static final int URI_NOTE_ITEM = 2 ;
private static final int URI_DATA = 3 ;
private static final int URI_DATA_ITEM = 4 ;
// URI匹配器常量
private static final int NOTES = 1 ;
private static final int NOTE_ID = 2 ;
private static final int FOLDERS = 3 ;
private static final int FOLDER_ID = 4 ;
private static final int DATA = 5 ;
private static final int DATA_ID = 6 ;
private static final int DATA_NOTE_ID = 7 ;
private static final int DATA_NOTE_ID_MIME_TYPE = 8 ;
private static final int URI_SEARCH = 5 ;
private static final int URI_SEARCH_SUGGEST = 6 ;
// URI匹配器
private static final UriMatcher sUriMatcher ;
// 便签查询投影映射
private static HashMap < String , String > sNotesProjectionMap ;
// 数据查询投影映射
private static HashMap < String , String > sDataProjectionMap ;
static {
mMatcher = new UriMatcher ( UriMatcher . NO_MATCH ) ;
mMatcher . addURI ( Notes . AUTHORITY , "note" , URI_NOTE ) ;
mMatcher . addURI ( Notes . AUTHORITY , "note/#" , URI_NOTE_ITEM ) ;
mMatcher . addURI ( Notes . AUTHORITY , "data" , URI_DATA ) ;
mMatcher . addURI ( Notes . AUTHORITY , "data/#" , URI_DATA_ITEM ) ;
mMatcher . addURI ( Notes . AUTHORITY , "search" , URI_SEARCH ) ;
mMatcher . addURI ( Notes . AUTHORITY , SearchManager . SUGGEST_URI_PATH_QUERY , URI_SEARCH_SUGGEST ) ;
mMatcher . addURI ( Notes . AUTHORITY , SearchManager . SUGGEST_URI_PATH_QUERY + "/*" , URI_SEARCH_SUGGEST ) ;
// 初始化URI匹配器
sUriMatcher = new UriMatcher ( UriMatcher . NO_MATCH ) ;
sUriMatcher . addURI ( Notes . AUTHORITY , "notes" , NOTES ) ;
sUriMatcher . addURI ( Notes . AUTHORITY , "notes/#" , NOTE_ID ) ;
sUriMatcher . addURI ( Notes . AUTHORITY , "folders" , FOLDERS ) ;
sUriMatcher . addURI ( Notes . AUTHORITY , "folders/#" , FOLDER_ID ) ;
sUriMatcher . addURI ( Notes . AUTHORITY , "data" , DATA ) ;
sUriMatcher . addURI ( Notes . AUTHORITY , "data/#" , DATA_ID ) ;
sUriMatcher . addURI ( Notes . AUTHORITY , "data/#/data" , DATA_NOTE_ID ) ;
sUriMatcher . addURI ( Notes . AUTHORITY , "data/#/data/*" , DATA_NOTE_ID_MIME_TYPE ) ;
// 初始化便签查询投影映射
sNotesProjectionMap = new HashMap < String , String > ( ) ;
sNotesProjectionMap . put ( Notes . NoteColumns . ID , Notes . NoteColumns . ID ) ;
sNotesProjectionMap . put ( Notes . NoteColumns . PARENT_ID , Notes . NoteColumns . PARENT_ID ) ;
sNotesProjectionMap . put ( Notes . NoteColumns . ALERTED_DATE , Notes . NoteColumns . ALERTED_DATE ) ;
sNotesProjectionMap . put ( Notes . NoteColumns . BG_COLOR_ID , Notes . NoteColumns . BG_COLOR_ID ) ;
sNotesProjectionMap . put ( Notes . NoteColumns . CREATED_DATE , Notes . NoteColumns . CREATED_DATE ) ;
sNotesProjectionMap . put ( Notes . NoteColumns . HAS_ATTACHMENT , Notes . NoteColumns . HAS_ATTACHMENT ) ;
sNotesProjectionMap . put ( Notes . NoteColumns . MODIFIED_DATE , Notes . NoteColumns . MODIFIED_DATE ) ;
sNotesProjectionMap . put ( Notes . NoteColumns . NOTES_COUNT , Notes . NoteColumns . NOTES_COUNT ) ;
sNotesProjectionMap . put ( Notes . NoteColumns . SNIPPET , Notes . NoteColumns . SNIPPET ) ;
sNotesProjectionMap . put ( Notes . NoteColumns . TYPE , Notes . NoteColumns . TYPE ) ;
sNotesProjectionMap . put ( Notes . NoteColumns . WIDGET_ID , Notes . NoteColumns . WIDGET_ID ) ;
sNotesProjectionMap . put ( Notes . NoteColumns . WIDGET_TYPE , Notes . NoteColumns . WIDGET_TYPE ) ;
sNotesProjectionMap . put ( Notes . NoteColumns . SYNC_ID , Notes . NoteColumns . SYNC_ID ) ;
sNotesProjectionMap . put ( Notes . NoteColumns . LOCAL_MODIFIED , Notes . NoteColumns . LOCAL_MODIFIED ) ;
sNotesProjectionMap . put ( Notes . NoteColumns . ORIGIN_PARENT_ID , Notes . NoteColumns . ORIGIN_PARENT_ID ) ;
sNotesProjectionMap . put ( Notes . NoteColumns . GTASK_ID , Notes . NoteColumns . GTASK_ID ) ;
sNotesProjectionMap . put ( Notes . NoteColumns . VERSION , Notes . NoteColumns . VERSION ) ;
// 初始化数据查询投影映射
sDataProjectionMap = new HashMap < String , String > ( ) ;
sDataProjectionMap . put ( Notes . DataColumns . ID , Notes . DataColumns . ID ) ;
sDataProjectionMap . put ( Notes . DataColumns . MIME_TYPE , Notes . DataColumns . MIME_TYPE ) ;
sDataProjectionMap . put ( Notes . DataColumns . NOTE_ID , Notes . DataColumns . NOTE_ID ) ;
sDataProjectionMap . put ( Notes . DataColumns . CREATED_DATE , Notes . DataColumns . CREATED_DATE ) ;
sDataProjectionMap . put ( Notes . DataColumns . MODIFIED_DATE , Notes . DataColumns . MODIFIED_DATE ) ;
sDataProjectionMap . put ( Notes . DataColumns . CONTENT , Notes . DataColumns . CONTENT ) ;
sDataProjectionMap . put ( Notes . DataColumns . DATA1 , Notes . DataColumns . DATA1 ) ;
sDataProjectionMap . put ( Notes . DataColumns . DATA2 , Notes . DataColumns . DATA2 ) ;
sDataProjectionMap . put ( Notes . DataColumns . DATA3 , Notes . DataColumns . DATA3 ) ;
sDataProjectionMap . put ( Notes . DataColumns . DATA4 , Notes . DataColumns . DATA4 ) ;
sDataProjectionMap . put ( Notes . DataColumns . DATA5 , Notes . DataColumns . DATA5 ) ;
}
/ * *
* x ' 0 A ' represents the '\n' character in sqlite . For title and content in the search result ,
* we will trim '\n' and white space in order to show more information .
* 初 始 化 内 容 提 供 者
* /
private static final String NOTES_SEARCH_PROJECTION = NoteColumns . ID + ","
+ NoteColumns . ID + " AS " + SearchManager . SUGGEST_COLUMN_INTENT_EXTRA_DATA + ","
+ "TRIM(REPLACE(" + NoteColumns . SNIPPET + ", x'0A','')) AS " + SearchManager . SUGGEST_COLUMN_TEXT_1 + ","
+ "TRIM(REPLACE(" + NoteColumns . SNIPPET + ", x'0A','')) AS " + SearchManager . SUGGEST_COLUMN_TEXT_2 + ","
+ R . drawable . search_result + " AS " + SearchManager . SUGGEST_COLUMN_ICON_1 + ","
+ "'" + Intent . ACTION_VIEW + "' AS " + SearchManager . SUGGEST_COLUMN_INTENT_ACTION + ","
+ "'" + Notes . TextNote . CONTENT_TYPE + "' AS " + SearchManager . SUGGEST_COLUMN_INTENT_DATA ;
private static String NOTES_SNIPPET_SEARCH_QUERY = "SELECT " + NOTES_SEARCH_PROJECTION
+ " FROM " + TABLE . NOTE
+ " WHERE " + NoteColumns . SNIPPET + " LIKE ?"
+ " AND " + NoteColumns . PARENT_ID + "<>" + Notes . ID_TRASH_FOLER
+ " AND " + NoteColumns . TYPE + "=" + Notes . TYPE_NOTE ;
@Override
public boolean onCreate ( ) {
mHelper = NotesDatabaseHelper . getInstance ( getContext ( ) ) ;
mOpenHelper = NotesDatabaseHelper . getInstance ( getContext ( ) ) ;
mContentResolver = getContext ( ) . getContentResolver ( ) ;
return true ;
}
/ * *
* 查 询 便 签 数 据
* /
@Override
public Cursor query ( Uri uri , String [ ] projection , String selection , String [ ] selectionArgs ,
String sortOrder ) {
Cursor c = null ;
SQLiteDatabase db = mHelper . getReadableDatabase ( ) ;
String id = null ;
switch ( mMatcher . match ( uri ) ) {
case URI_NOTE :
c = db . query ( TABLE . NOTE , projection , selection , selectionArgs , null , null ,
sortOrder ) ;
public Cursor query ( Uri uri , String [ ] projection , String selection ,
String [ ] selectionArgs , String sortOrder ) {
SQLiteQueryBuilder qb = new SQLiteQueryBuilder ( ) ;
String groupBy = null ;
// 根据URI匹配结果设置查询条件
switch ( sUriMatcher . match ( uri ) ) {
case NOTES :
qb . setTables ( NotesDatabaseHelper . TABLE . NOTE ) ;
qb . setProjectionMap ( sNotesProjectionMap ) ;
break ;
case URI_NOTE_ITEM :
id = uri . getPathSegments ( ) . get ( 1 ) ;
c = db . query ( TABLE . NOTE , projection , NoteColumns . ID + "=" + id
+ parseSelection ( selection ) , selectionArgs , null , null , sortOrder ) ;
case NOTE_ID :
qb . setTables ( NotesDatabaseHelper . TABLE . NOTE ) ;
qb . setProjectionMap ( sNotesProjectionMap ) ;
qb . appendWhere ( Notes . NoteColumns . ID + "=" + uri . getPathSegments ( ) . get ( 1 ) ) ;
break ;
case URI_DATA :
c = db . query ( TABLE . DATA , projection , selection , selectionArgs , null , null ,
sortOrder ) ;
case FOLDERS :
qb . setTables ( NotesDatabaseHelper . TABLE . NOTE ) ;
qb . setProjectionMap ( sNotesProjectionMap ) ;
qb . appendWhere ( Notes . NoteColumns . TYPE + "=" + Notes . TypeColumns . TYPE_FOLDER ) ;
break ;
case URI_DATA_ITEM :
id = uri . getPathSegments ( ) . get ( 1 ) ;
c = db . query ( TABLE . DATA , projection , DataColumns . ID + "=" + id
+ parseSelection ( selection ) , selectionArgs , null , null , sortOrder ) ;
case FOLDER_ID :
qb . setTables ( NotesDatabaseHelper . TABLE . NOTE ) ;
qb . setProjectionMap ( sNotesProjectionMap ) ;
qb . appendWhere ( Notes . NoteColumns . ID + "=" + uri . getPathSegments ( ) . get ( 1 ) ) ;
break ;
case URI_SEARCH :
case URI_SEARCH_SUGGEST :
if ( sortOrder ! = null | | projection ! = null ) {
throw new IllegalArgumentException (
"do not specify sortOrder, selection, selectionArgs, or projection" + "with this query" ) ;
}
String searchString = null ;
if ( mMatcher . match ( uri ) = = URI_SEARCH_SUGGEST ) {
if ( uri . getPathSegments ( ) . size ( ) > 1 ) {
searchString = uri . getPathSegments ( ) . get ( 1 ) ;
case DATA :
qb . setTables ( NotesDatabaseHelper . TABLE . DATA ) ;
qb . setProjectionMap ( sDataProjectionMap ) ;
break ;
case DATA_ID :
qb . setTables ( NotesDatabaseHelper . TABLE . DATA ) ;
qb . setProjectionMap ( sDataProjectionMap ) ;
qb . appendWhere ( Notes . DataColumns . ID + "=" + uri . getPathSegments ( ) . get ( 1 ) ) ;
break ;
case DATA_NOTE_ID :
qb . setTables ( NotesDatabaseHelper . TABLE . DATA ) ;
qb . setProjectionMap ( sDataProjectionMap ) ;
qb . appendWhere ( Notes . DataColumns . NOTE_ID + "=" + uri . getPathSegments ( ) . get ( 1 ) ) ;
break ;
case DATA_NOTE_ID_MIME_TYPE :
qb . setTables ( NotesDatabaseHelper . TABLE . DATA ) ;
qb . setProjectionMap ( sDataProjectionMap ) ;
qb . appendWhere ( Notes . DataColumns . NOTE_ID + "=" + uri . getPathSegments ( ) . get ( 1 ) ) ;
qb . appendWhere ( " AND " + Notes . DataColumns . MIME_TYPE + "='" +
uri . getPathSegments ( ) . get ( 3 ) + "'" ) ;
break ;
default :
throw new IllegalArgumentException ( "Unknown URI " + uri ) ;
}
// 如果没有指定排序方式,使用默认排序
String orderBy ;
if ( TextUtils . isEmpty ( sortOrder ) ) {
orderBy = Notes . NoteColumns . MODIFIED_DATE + " DESC" ;
} else {
searchString = uri . getQueryParameter ( "pattern" ) ;
orderBy = sortOrder ;
}
if ( TextUtils . isEmpty ( searchString ) ) {
return null ;
}
// 获取数据库并执行查询
SQLiteDatabase db = mOpenHelper . getReadableDatabase ( ) ;
Cursor c = qb . query ( db , projection , selection , selectionArgs , groupBy , null , orderBy ) ;
try {
searchString = String . format ( "%%%s%%" , searchString ) ;
c = db . rawQuery ( NOTES_SNIPPET_SEARCH_QUERY ,
new String [ ] { searchString } ) ;
} catch ( IllegalStateException ex ) {
Log . e ( TAG , "got exception: " + ex . toString ( ) ) ;
// 设置通知URI, 当数据变化时通知ContentResolver
c . setNotificationUri ( mContentResolver , uri ) ;
return c ;
}
break ;
/ * *
* 获 取 内 容 类 型
* /
@Override
public String getType ( Uri uri ) {
switch ( sUriMatcher . match ( uri ) ) {
case NOTES :
return Notes . NoteContent . CONTENT_TYPE ;
case NOTE_ID :
return Notes . NoteContent . CONTENT_ITEM_TYPE ;
case FOLDERS :
return Notes . FolderContent . CONTENT_TYPE ;
case FOLDER_ID :
return Notes . FolderContent . CONTENT_ITEM_TYPE ;
case DATA :
return Notes . DataContent . CONTENT_TYPE ;
case DATA_ID :
return Notes . DataContent . CONTENT_ITEM_TYPE ;
case DATA_NOTE_ID :
return Notes . DataContent . CONTENT_TYPE ;
case DATA_NOTE_ID_MIME_TYPE :
return Notes . DataContent . CONTENT_TYPE ;
default :
throw new IllegalArgumentException ( "Unknown URI " + uri ) ;
}
if ( c ! = null ) {
c . setNotificationUri ( getContext ( ) . getContentResolver ( ) , uri ) ;
}
return c ;
}
/ * *
* 插 入 便 签 数 据
* /
@Override
public Uri insert ( Uri uri , ContentValues values ) {
SQLiteDatabase db = mHelper . getWritableDatabase ( ) ;
long dataId = 0 , noteId = 0 , insertedId = 0 ;
switch ( mMatcher . match ( uri ) ) {
case URI_NOTE :
insertedId = noteId = db . insert ( TABLE . NOTE , null , values ) ;
break ;
case URI_DATA :
if ( values . containsKey ( DataColumns . NOTE_ID ) ) {
noteId = values . getAsLong ( DataColumns . NOTE_ID ) ;
public Uri insert ( Uri uri , ContentValues initialValues ) {
// 确保ContentValues不为空
ContentValues values ;
if ( initialValues ! = null ) {
values = new ContentValues ( initialValues ) ;
} else {
Log . d ( TAG , "Wrong data format without note id:" + values . toString ( ) ) ;
values = new ContentValues ( ) ;
}
insertedId = dataId = db . insert ( TABLE . DATA , null , values ) ;
break ;
default :
throw new IllegalArgumentException ( "Unknown URI " + uri ) ;
SQLiteDatabase db = mOpenHelper . getWritableDatabase ( ) ;
long rowId ;
Uri baseUri ;
// 根据URI匹配结果执行不同的插入操作
switch ( sUriMatcher . match ( uri ) ) {
case NOTES :
// 处理父文件夹ID为空的情况
if ( ! values . containsKey ( Notes . NoteColumns . PARENT_ID ) ) {
values . put ( Notes . NoteColumns . PARENT_ID , Notes . FolderConstants . ID_ROOT_FOLDER ) ;
}
// Notify the note uri
if ( noteId > 0 ) {
getContext ( ) . getContentResolver ( ) . notifyChange (
ContentUris . withAppendedId ( Notes . CONTENT_NOTE_URI , noteId ) , null ) ;
// 处理类型为空的情况
if ( ! values . containsKey ( Notes . NoteColumns . TYPE ) ) {
values. put ( Notes . NoteColumns . TYPE , Notes . TypeColumns . TYPE_NOTE ) ;
}
// Notify the data uri
if ( dataId > 0 ) {
getContext ( ) . getContentResolver ( ) . notifyChange (
ContentUris . withAppendedId ( Notes . CONTENT_DATA_URI , dataId ) , null ) ;
// 处理便签摘要为空的情况
if ( ! values . containsKey ( Notes . NoteColumns . SNIPPET ) ) {
values . put ( Notes . NoteColumns . SNIPPET , "" ) ;
}
return ContentUris . withAppendedId ( uri , insertedId ) ;
// 插入便签数据
rowId = db . insert ( NotesDatabaseHelper . TABLE . NOTE , null , values ) ;
if ( rowId > 0 ) {
baseUri = Notes . NoteContent . CONTENT_URI ;
Uri newUri = ContentUris . withAppendedId ( baseUri , rowId ) ;
mContentResolver . notifyChange ( newUri , null ) ;
return newUri ;
}
break ;
@Override
public int delete ( Uri uri , String selection , String [ ] selectionArgs ) {
int count = 0 ;
String id = null ;
SQLiteDatabase db = mHelper . getWritableDatabase ( ) ;
boolean deleteData = false ;
switch ( mMatcher . match ( uri ) ) {
case URI_NOTE :
selection = "(" + selection + ") AND " + NoteColumns . ID + ">0 " ;
count = db . delete ( TABLE . NOTE , selection , selectionArgs ) ;
case DATA :
// 处理关联便签ID为空的情况
if ( ! values . containsKey ( Notes . DataColumns . NOTE_ID ) ) {
throw new IllegalArgumentException ( "Note ID is required for data insertion" ) ;
}
// 处理MIME类型为空的情况
if ( ! values . containsKey ( Notes . DataColumns . MIME_TYPE ) ) {
throw new IllegalArgumentException ( "MIME type is required for data insertion" ) ;
}
// 插入便签数据关联
rowId = db . insert ( NotesDatabaseHelper . TABLE . DATA , null , values ) ;
if ( rowId > 0 ) {
baseUri = Notes . DataContent . CONTENT_URI ;
Uri newUri = ContentUris . withAppendedId ( baseUri , rowId ) ;
// 如果是提醒类型,更新便签的提醒日期
if ( Notes . DataConstants . ALERT . equals ( values . getAsString ( Notes . DataColumns . MIME_TYPE ) ) ) {
long alertDate = values . getAsLong ( Notes . DataColumns . DATA1 ) ;
updateAlertDate ( values . getAsLong ( Notes . DataColumns . NOTE_ID ) , alertDate ) ;
}
mContentResolver . notifyChange ( newUri , null ) ;
return newUri ;
}
break ;
case URI_NOTE_ITEM :
id = uri . getPathSegments ( ) . get ( 1 ) ;
default :
throw new IllegalArgumentException ( "Unknown URI " + uri ) ;
}
throw new IllegalArgumentException ( "Failed to insert row into " + uri ) ;
}
/ * *
* ID that smaller than 0 is system folder which is not allowed to
* trash
* 更 新 便 签 数 据
* /
long noteId = Long . valueOf ( id ) ;
if ( noteId < = 0 ) {
@Override
public int update ( Uri uri , ContentValues values , String where , String [ ] whereArgs ) {
SQLiteDatabase db = mOpenHelper . getWritableDatabase ( ) ;
int count ;
String finalWhere ;
// 根据URI匹配结果执行不同的更新操作
switch ( sUriMatcher . match ( uri ) ) {
case NOTES :
count = db . update ( NotesDatabaseHelper . TABLE . NOTE , values , where , whereArgs ) ;
break ;
case NOTE_ID :
finalWhere = Notes . NoteColumns . ID + "=" + uri . getPathSegments ( ) . get ( 1 ) ;
if ( where ! = null ) {
finalWhere = finalWhere + " AND " + where ;
}
// 如果更新了便签类型,处理特殊情况
if ( values . containsKey ( Notes . NoteColumns . TYPE ) ) {
int type = values . getAsInteger ( Notes . NoteColumns . TYPE ) ;
if ( type = = Notes . TypeColumns . TYPE_SYSTEM ) {
throw new IllegalArgumentException ( "Can't set note type to system type" ) ;
}
count = db . delete ( TABLE . NOTE ,
NoteColumns . ID + "=" + id + parseSelection ( selection ) , selectionArgs ) ;
}
count = db . update ( NotesDatabaseHelper . TABLE . NOTE , values , finalWhere , whereArgs ) ;
break ;
case URI_DATA :
count = db . delete ( TABLE . DATA , selection , selectionArgs ) ;
deleteData = true ;
case DATA :
count = db . update ( NotesDatabaseHelper . TABLE . DATA , values , where , whereArgs ) ;
break ;
case URI_DATA_ITEM :
id = uri . getPathSegments ( ) . get ( 1 ) ;
count = db . delete ( TABLE . DATA ,
DataColumns . ID + "=" + id + parseSelection ( selection ) , selectionArgs ) ;
deleteData = true ;
case DATA_ID :
finalWhere = Notes . DataColumns . ID + "=" + uri . getPathSegments ( ) . get ( 1 ) ;
if ( where ! = null ) {
finalWhere = finalWhere + " AND " + where ;
}
// 如果更新了提醒数据,更新便签的提醒日期
if ( values . containsKey ( Notes . DataColumns . MIME_TYPE ) & &
Notes . DataConstants . ALERT . equals ( values . getAsString ( Notes . DataColumns . MIME_TYPE ) ) ) {
long alertDate = values . getAsLong ( Notes . DataColumns . DATA1 ) ;
updateAlertDate ( getNoteIdFromDataId ( ContentUris . parseId ( uri ) ) , alertDate ) ;
}
count = db . update ( NotesDatabaseHelper . TABLE . DATA , values , finalWhere , whereArgs ) ;
break ;
default :
throw new IllegalArgumentException ( "Unknown URI " + uri ) ;
}
if ( count > 0 ) {
if ( deleteData ) {
getContext ( ) . getContentResolver ( ) . notifyChange ( Notes . CONTENT_NOTE_URI , null ) ;
}
getContext ( ) . getContentResolver ( ) . notifyChange ( uri , null ) ;
}
// 通知内容解析器数据已更改
mContentResolver . notifyChange ( uri , null ) ;
return count ;
}
/ * *
* 删 除 便 签 数 据
* /
@Override
public int update ( Uri uri , ContentValues values , String selection , String [ ] selectionArgs ) {
int count = 0 ;
String id = null ;
SQLiteDatabase db = mHelper . getWritableDatabase ( ) ;
boolean updateData = false ;
switch ( mMatcher . match ( uri ) ) {
case URI_NOTE :
increaseNoteVersion ( - 1 , selection , selectionArgs ) ;
count = db . update ( TABLE . NOTE , values , selection , selectionArgs ) ;
public int delete ( Uri uri , String where , String [ ] whereArgs ) {
SQLiteDatabase db = mOpenHelper . getWritableDatabase ( ) ;
int count ;
String finalWhere ;
// 根据URI匹配结果执行不同的删除操作
switch ( sUriMatcher . match ( uri ) ) {
case NOTES :
// 不能删除系统文件夹
finalWhere = Notes . NoteColumns . TYPE + "!=" + Notes . TypeColumns . TYPE_SYSTEM ;
if ( where ! = null ) {
finalWhere = finalWhere + " AND " + where ;
}
count = db . delete ( NotesDatabaseHelper . TABLE . NOTE , finalWhere , whereArgs ) ;
break ;
case URI_NOTE_ITEM :
id = uri . getPathSegments ( ) . get ( 1 ) ;
increaseNoteVersion ( Long . valueOf ( id ) , selection , selectionArgs ) ;
count = db . update ( TABLE . NOTE , values , NoteColumns . ID + "=" + id
+ parseSelection ( selection ) , selectionArgs ) ;
case NOTE_ID :
// 不能删除系统文件夹
finalWhere = Notes . NoteColumns . ID + "=" + uri . getPathSegments ( ) . get ( 1 ) +
" AND " + Notes . NoteColumns . TYPE + "!=" + Notes . TypeColumns . TYPE_SYSTEM ;
if ( where ! = null ) {
finalWhere = finalWhere + " AND " + where ;
}
// 如果删除的是带有提醒的便签,先清除提醒日期
clearAlertDate ( ContentUris . parseId ( uri ) ) ;
count = db . delete ( NotesDatabaseHelper . TABLE . NOTE , finalWhere , whereArgs ) ;
break ;
case URI_DATA :
count = db . update ( TABLE . DATA , values , selection , selectionArgs ) ;
updateData = true ;
case DATA :
count = db . delete ( NotesDatabaseHelper . TABLE . DATA , where , whereArgs ) ;
break ;
case URI_DATA_ITEM :
id = uri . getPathSegments ( ) . get ( 1 ) ;
count = db . update ( TABLE . DATA , values , DataColumns . ID + "=" + id
+ parseSelection ( selection ) , selectionArgs ) ;
updateData = true ;
case DATA_ID :
finalWhere = Notes . DataColumns . ID + "=" + uri . getPathSegments ( ) . get ( 1 ) ;
if ( where ! = null ) {
finalWhere = finalWhere + " AND " + where ;
}
// 如果删除的是提醒数据,清除便签的提醒日期
clearAlertDate ( getNoteIdFromDataId ( ContentUris . parseId ( uri ) ) ) ;
count = db . delete ( NotesDatabaseHelper . TABLE . DATA , finalWhere , whereArgs ) ;
break ;
default :
throw new IllegalArgumentException ( "Unknown URI " + uri ) ;
}
if ( count > 0 ) {
if ( updateData ) {
getContext ( ) . getContentResolver ( ) . notifyChange ( Notes . CONTENT_NOTE_URI , null ) ;
}
getContext ( ) . getContentResolver ( ) . notifyChange ( uri , null ) ;
}
// 通知内容解析器数据已更改
mContentResolver . notifyChange ( uri , null ) ;
return count ;
}
private String parseSelection ( String selection ) {
return ( ! TextUtils . isEmpty ( selection ) ? " AND (" + selection + ')' : "" ) ;
/ * *
* 更 新 便 签 的 提 醒 日 期
* /
private void updateAlertDate ( long noteId , long alertDate ) {
ContentValues values = new ContentValues ( ) ;
values . put ( Notes . NoteColumns . ALERTED_DATE , alertDate ) ;
values . put ( Notes . NoteColumns . LOCAL_MODIFIED , 1 ) ;
SQLiteDatabase db = mOpenHelper . getWritableDatabase ( ) ;
db . update ( NotesDatabaseHelper . TABLE . NOTE , values ,
Notes . NoteColumns . ID + "=" + noteId , null ) ;
}
private void increaseNoteVersion ( long id , String selection , String [ ] selectionArgs ) {
StringBuilder sql = new StringBuilder ( 120 ) ;
sql . append ( "UPDATE " ) ;
sql . append ( TABLE . NOTE ) ;
sql . append ( " SET " ) ;
sql . append ( NoteColumns . VERSION ) ;
sql . append ( "=" + NoteColumns . VERSION + "+1 " ) ;
/ * *
* 清 除 便 签 的 提 醒 日 期
* /
private void clearAlertDate ( long noteId ) {
ContentValues values = new ContentValues ( ) ;
values. put ( Notes . NoteColumns . ALERTED_DATE , 0 ) ;
values. put ( Notes . NoteColumns . LOCAL_MODIFIED , 1 ) ;
if ( id > 0 | | ! TextUtils . isEmpty ( selection ) ) {
sql . append ( " WHERE " ) ;
}
if ( id > 0 ) {
sql . append ( NoteColumns . ID + "=" + String . valueOf ( id ) ) ;
}
if ( ! TextUtils . isEmpty ( selection ) ) {
String selectString = id > 0 ? parseSelection ( selection ) : selection ;
for ( String args : selectionArgs ) {
selectString = selectString . replaceFirst ( "\\?" , args ) ;
}
sql . append ( selectString ) ;
SQLiteDatabase db = mOpenHelper . getWritableDatabase ( ) ;
db . update ( NotesDatabaseHelper . TABLE . NOTE , values ,
Notes . NoteColumns . ID + "=" + noteId , null ) ;
}
mHelper . getWritableDatabase ( ) . execSQL ( sql . toString ( ) ) ;
}
/ * *
* 从 数 据 ID 获 取 关 联 的 便 签 ID
* /
private long getNoteIdFromDataId ( long dataId ) {
String [ ] projection = new String [ ] { Notes . DataColumns . NOTE_ID } ;
String selection = Notes . DataColumns . ID + " = ?" ;
String [ ] selectionArgs = new String [ ] { String . valueOf ( dataId ) } ;
@Override
public String getType ( Uri uri ) {
// TODO Auto-generated method stub
return null ;
SQLiteDatabase db = mOpenHelper . getReadableDatabase ( ) ;
Cursor cursor = db . query ( NotesDatabaseHelper . TABLE . DATA , projection ,
selection , selectionArgs , null , null , null ) ;
long noteId = - 1 ;
if ( cursor ! = null ) {
if ( cursor . moveToFirst ( ) ) {
noteId = cursor . getLong ( 0 ) ;
}
cursor . close ( ) ;
}
return noteId ;
}
}