第一个类用来定义Notepad中的权限AUTHORIT、表名、列名、Uri以及MIME。此类中定义一个内部类Notes实现BaseColumns借口;BaseColumns接口中没有其他方法之定义了两个常量:
public static final String _ID = "_id";
public static final String _COUNT = "_count";
ContentProvider中的增删改查操作与数据库 有很大的关系.provider 不需要一个主键或是作为主键的_id列名,但是如果要把provider提供的内容与ListView绑定则一定要用到_id
/*
* 1、定义权限
* 2、定义表名列名
* 3、定义Uri
* 4、定义MIME
*
* */
public class Notepad {
public static final String AUTHORIT ="com.example.cp_notepad";
static final class Notes implements BaseColumns{
//定义表名
public static final String TABLE_NAME = "notes";
//定义列明
//声明note的列名
public static final String COLUMN_NAME_NOTE = "note";
//声明 note列的创建时间
public static final String COLUMN_NAME_CREATE_DATE = "created";
//声明note列的修改时间
public static final String COLUMN_NAME_MODIFICATION_DATE = "modified";
//声明note表默认排序
public static final String DEFAULT_SORT_ORDER = "modified DESC";
//声明Uri的scheme
private static final String SCHEME = "content://";
//声明note集合的路径
private static final String PATH_NOTES = "/notes";
//声明一个note id的路径
private static final String PATH_NOTE_ID = "/notes/";
//声明note集合的Uri
public static final Uri CONTENT_URI=Uri.parse(SCHEME+AUTHORIT+PATH_NOTES);
//声明单一note的Uri
public static final Uri CONTENT_ID_URI_BASE=Uri.parse(SCHEME+AUTHORIT+PATH_NOTE_ID);
//声明noteUri _id片段
public static final int NOTE_ID_PATH_POSITION = 1;
// //声明MIME
// //声明返回类型---集合
// public static final String CONTENT_TYPE = "vnd.android.cursor.dir/vnd.google.note";
// //声明返回类型--单个
// public static final String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/vnd.google.note";
}
}
之后创建一个类,提供ContentProvider服务。创建一个ContentProvider的步骤:1、继承ContentProvider。2、实现数据库代码,创建内部类继承SQliteOpenHelper。3、声明UriMatcher 定义多拿钱provider能处理的Uri ,以后用来uri匹配。4、在onCreat方法中创建数据库。5、实现CRUD功能代码
public class MyContentProvider extends ContentProvider{ private static final String TAG = "NotePadProvider"; private static final String DATABASE_NAME = "note_pad.db";//数据库名字 private static final int DATABASE_VERSION = 1; //数据库版本 private MyDbHelper dbHelper=null; // The incoming URI matches the Notes URI pattern private static final int NOTES = 1; // The incoming URI matches the Note ID URI pattern private static final int NOTE_ID = 2; /** * A projection map used to select columns from the database * 定义map存放列的集合,方便查询。在使用SqliteQueryBuilder查询时需要该类型作为参数。 */ private static HashMap<String, String> sNotesProjectionMap; /** * A UriMatcher instance */ private static final UriMatcher sUriMatcher; //静态块初始化UriMatcher static { // Create a new instance sUriMatcher = new UriMatcher(UriMatcher.NO_MATCH); sUriMatcher.addURI(NotePad.AUTHORITY,"notes",NOTES); sUriMatcher.addURI(NotePad.AUTHORITY,"notes/#", NOTE_ID); //如果查询不使用SQliteQueryBuilder,以下步骤可以省略,但是推荐使用QB,方便构建查询语句。 // Creates a new projection map instance. The map returns a column name // given a string. The two are usually equal. sNotesProjectionMap = new HashMap<String, String>(); // Maps the string "_ID" to the column name "_ID" sNotesProjectionMap.put(NotePad.Notes._ID, NotePad.Notes._ID); // Maps "note" to "note" sNotesProjectionMap.put(NotePad.Notes.COLUMN_NAME_NOTE, NotePad.Notes.COLUMN_NAME_NOTE); // Maps "created" to "created" sNotesProjectionMap.put(NotePad.Notes.COLUMN_NAME_CREATE_DATE, NotePad.Notes.COLUMN_NAME_CREATE_DATE); // Maps "modified" to "modified" sNotesProjectionMap.put( NotePad.Notes.COLUMN_NAME_MODIFICATION_DATE, NotePad.Notes.COLUMN_NAME_MODIFICATION_DATE); } @Override public boolean onCreate() { Log.d(TAG,"onCreate is called!"); dbHelper=new MyDbHelper(getContext()); return true; } @Override public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) { /** * 1、构建SQliteQueryBuidler,方便查询使用 * 2、进URI匹配,两种情况一是查所有,二是查询一条记录 * 3、SQliteQueryBuidler的query方法进行查询 * 4、query方法返回cursor,需要对cursor进行通知设置 * */ //构建SqliteQueryBuidler SQLiteQueryBuilder qb=new SQLiteQueryBuilder(); qb.setTables(NotePad.Notes.TABLE_NAME);//设置查询的表名 //进行uri匹配处理 switch (sUriMatcher.match(uri)) { case NOTES: qb.setProjectionMap(sNotesProjectionMap);//设置查询的列数 break; case NOTE_ID: qb.setProjectionMap(sNotesProjectionMap); qb.appendWhere(NotePad.Notes._ID+" ="+uri.getPathSegments().get(NotePad.Notes.NOTE_ID_PATH_POSITION)); break; default: throw new IllegalArgumentException("URI异常!"); } SQLiteDatabase db=dbHelper.getReadableDatabase(); String orderBy=null; //判断排序字段是否为空 if(TextUtils.isEmpty(sortOrder)){ orderBy=NotePad.Notes.DEFAULT_SORT_ORDER; }else{ orderBy=sortOrder; } Cursor c=qb.query(db,projection,selection,selectionArgs,null,null, orderBy); //非常重要的一句能使MainActivity中的ListView自动更新 c.setNotificationUri(getContext().getContentResolver(), uri); return c; } //该方法中进行传入的uri与定义的uri进行匹配。匹配合适后,根据不同的uri返回不同的MIME类型 //主要就是两种类型,一种是集合,一种一条数据。 //?????此方法在程序运行时没发现它运行 但是在继承Contentprovider时必须重写,不知此方法何时调用! @Override public String getType(Uri uri) { switch (sUriMatcher.match(uri)) { case NOTES://如果查询所有返回MIME是一个集合 return NotePad.Notes.CONTENT_TYPE; case NOTE_ID: return NotePad.Notes.CONTENT_ITEM_TYPE; default: throw new IllegalArgumentException("uri参数异常"); } } @Override public Uri insert(Uri uri, ContentValues values) { /** * 1、判断URI是否匹配,如果匹配抛出异常 * 2、构建ContentValues,保证插入数据库是不出现异常 * 3、SqliteDatabase的insert方法进行数据插入 * 4、根据insert方法返回的id,构建返回的uri。最后将uri返回。 * */ if(sUriMatcher.match(uri)!=NOTES){//需要向集合中插入数据,故必须需要一个有集合uri throw new IllegalArgumentException("uri不正确"); } ContentValues mValues=null;//保证values参数为null时,数据库插入能够正常进行。 if(values!=null){//当用户传递参数不为null mValues=new ContentValues(values);//将用户传递参数重新构建 }else{ mValues=new ContentValues();//当用户传递参数为null,构建一个新的contentvalues。 } //获取当前系统时间作为默认的创建时间 Long now=Long.valueOf(System.currentTimeMillis()); //以下3句if语句设置默认值的,保证插入数据不出错。 //判断values中是否有创建时间列key if(mValues.containsKey(NotePad.Notes.COLUMN_NAME_CREATE_DATE)==false){ mValues.put(NotePad.Notes.COLUMN_NAME_CREATE_DATE, now); } //修改时间 if(mValues.containsKey(NotePad.Notes.COLUMN_NAME_MODIFICATION_DATE)==false){ mValues.put(NotePad.Notes.COLUMN_NAME_MODIFICATION_DATE, now); } //内容 if(mValues.containsKey(NotePad.Notes.COLUMN_NAME_NOTE)==false){ mValues.put(NotePad.Notes.COLUMN_NAME_NOTE, ""); } //获取SQLiteDatabase SQLiteDatabase db=dbHelper.getWritableDatabase(); //调用insert方法,返回插入列的id long row=db.insert(NotePad.Notes.TABLE_NAME,NotePad.Notes.COLUMN_NAME_NOTE, mValues); //根据插入列的id获取uri if(row>0){ Uri mUri=ContentUris.withAppendedId(NotePad.Notes.CONTENT_ID_URI_BASE, row); //通知所有的ContentResolver,uri发生改变。可以将数据进行同步。 getContext().getContentResolver().notifyChange(mUri,null); return mUri; } throw new SQLException("Failed to insert row into " + uri); } @Override public int delete(Uri uri, String selection, String[] selectionArgs) { //1、获取sqlitedatabase SQLiteDatabase db=dbHelper.getWritableDatabase(); int count=0; final String finalWhere; //2、uri匹配,不同uri不同处理 Log.d(TAG,uri.toString()); switch (sUriMatcher.match(uri)) { case NOTES: count=db.delete(NotePad.Notes.TABLE_NAME, selection, selectionArgs); break; case NOTE_ID: Log.d(TAG,uri.getPathSegments().get(NotePad.Notes.NOTE_ID_PATH_POSITION)); finalWhere=NotePad.Notes._ID+" = "+uri.getPathSegments().get(NotePad.Notes.NOTE_ID_PATH_POSITION); count=db.delete(NotePad.Notes.TABLE_NAME,finalWhere, selectionArgs); break; default: throw new IllegalArgumentException("URI不匹配"); } //通知 getContext().getContentResolver().notifyChange(uri, null); return count; } @Override public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) { //1、获取sqlitedatabase SQLiteDatabase db=dbHelper.getWritableDatabase(); int count=0; final String finalWhere; //2、uri匹配,不同uri不同处理 Log.d(TAG,uri.toString()); switch (sUriMatcher.match(uri)) { case NOTES: count=db.update(NotePad.Notes.TABLE_NAME, values, selection,selectionArgs); break; case NOTE_ID: Log.d(TAG,uri.getPathSegments().get(NotePad.Notes.NOTE_ID_PATH_POSITION)); finalWhere=NotePad.Notes._ID+" = "+uri.getPathSegments().get(NotePad.Notes.NOTE_ID_PATH_POSITION); count=db.update(NotePad.Notes.TABLE_NAME, values,finalWhere, selectionArgs); break; default: throw new IllegalArgumentException("URI不匹配"); } //通知 getContext().getContentResolver().notifyChange(uri, null); return count; } //定义数据库工具类,需要数据库的名字,数据库的版本 static class MyDbHelper extends SQLiteOpenHelper{ public MyDbHelper(Context context) { super(context,DATABASE_NAME,null, DATABASE_VERSION); // TODO Auto-generated constructor stub } //创建表 @Override public void onCreate(SQLiteDatabase db) { db.execSQL("CREATE TABLE " + NotePad.Notes.TABLE_NAME + " (" + NotePad.Notes._ID + " INTEGER PRIMARY KEY," + NotePad.Notes.COLUMN_NAME_NOTE + " TEXT," + NotePad.Notes.COLUMN_NAME_CREATE_DATE + " INTEGER," + NotePad.Notes.COLUMN_NAME_MODIFICATION_DATE + " INTEGER" + ");"); } //数据库版本更新 @Override public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { // Kills the table and existing data db.execSQL("DROP TABLE IF EXISTS notes"); // Recreates the database with a new version onCreate(db); } } }
完成上述类之后就可以创建Notepad中的添加笔记类 更改以及删除笔记类
MainActivity:
public class MainActivity extends ListActivity {
private ContentResolver cr;
private Cursor c;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
cr=getContentResolver();
initListView();
}
private void initListView(){
c=cr.query(NotePad.Notes.CONTENT_URI,null,null,null,null);
SimpleCursorAdapter sca=new SimpleCursorAdapter(getApplicationContext(), android.R.layout.simple_list_item_1, c,new String[]{NotePad.Notes.COLUMN_NAME_NOTE},new int[]{android.R.id.text1});
setListAdapter(sca);
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.activity_main, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
// TODO Auto-generated method stub
switch (item.getItemId()) {
case R.id.add:
Intent intent=new Intent(MainActivity.this,AddActivity.class);
startActivity(intent);
break;
default:
break;
}
return super.onOptionsItemSelected(item);
}
@Override
protected void onListItemClick(ListView l, View v, int position, long id) {
// TODO Auto-generated method stub
super.onListItemClick(l, v, position, id);
//需要将id,note传递到updateactivity
Intent intent=new Intent(MainActivity.this,UpdateActivity.class);
intent.putExtra("note",((TextView)v).getText().toString());
intent.putExtra("id",id);
startActivity(intent);
}
}
添加笔记:AddActivity.class
public class AddActivity extends Activity{
protected EditText txtNote=null;
protected ContentResolver cr;
@Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_add);
txtNote=(EditText)findViewById(R.id.editText1);
cr=getContentResolver();
}
public void addNote(View view){
ContentValues values=new ContentValues();
values.put(NotePad.Notes.COLUMN_NAME_NOTE,txtNote.getText().toString().trim());
Uri uri=cr.insert(NotePad.Notes.CONTENT_URI, values);
if(uri!=null){
Toast.makeText(getApplicationContext(),"ok",Toast.LENGTH_SHORT).show();
finish();
}else{
Toast.makeText(getApplicationContext(),"error",Toast.LENGTH_SHORT).show();
}
}
}
更新及删除笔记:
public class UpdateActivity extends AddActivity{ private Intent intent=null; private static final int MENU_ID=Menu.FIRST; @Override protected void onResume() { // TODO Auto-generated method stub super.onResume(); txtNote.setText("updateNote"); intent=getIntent(); if(intent!=null){ txtNote.setText(intent.getStringExtra("note")); } } public void addNote(View view){ ContentValues values=new ContentValues(); values.put(NotePad.Notes.COLUMN_NAME_NOTE,txtNote.getText().toString().trim()); Uri uri=ContentUris.withAppendedId(NotePad.Notes.CONTENT_ID_URI_BASE,intent.getLongExtra("id",0)); int count=cr.update(uri, values,null,null); if(count>0){ Toast.makeText(getApplicationContext(),"ok",Toast.LENGTH_SHORT).show(); finish(); }else{ Toast.makeText(getApplicationContext(),"failed",Toast.LENGTH_SHORT).show(); } } @Override public boolean onCreateOptionsMenu(Menu menu) { // TODO Auto-generated method stub menu.add(0,MENU_ID,0,"delete"); return super.onCreateOptionsMenu(menu); } @Override public boolean onOptionsItemSelected(MenuItem item) { // TODO Auto-generated method stub if(item.getItemId()==MENU_ID){ Uri uri=ContentUris.withAppendedId(NotePad.Notes.CONTENT_ID_URI_BASE,intent.getLongExtra("id",0)); cr.delete(uri,null,null); finish(); } return super.onOptionsItemSelected(item); } }
以上简单的实现NotePad功能,ContentProvider的实现,不要忘了在清单文件AndroidManifest中注册 及添加权限。