学习笔记-Android之ContentProvider实现Notepad

  第一个类用来定义Notepad中的权限AUTHORIT、表名、列名、Uri以及MIME。此类中定义一个内部类Notes实现BaseColumns借口;BaseColumns接口中没有其余方法之定义了两个常量:
public static final String _ID = "_id";
public static final String _COUNT = "_count";


ContentProvider中的增删改查操做与数据库 有很大的关系.provider 不须要一个主键或是做为主键的_id列名,可是若是要把provider提供的内容与ListView绑定则必定要用到_idjava


/*
 * 一、定义权限
 * 二、定义表名列名
 * 三、定义Uri
 * 四、定义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的步骤:一、继承ContentProvider。二、实现数据库代码,建立内部类继承SQliteOpenHelper。三、声明UriMatcher  定义多拿钱provider能处理的Uri ,之后用来uri匹配。四、在onCreat方法中建立数据库。五、实现CRUD功能代码
  1. 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) {
         /**
          * 一、构建SQliteQueryBuidler,方便查询使用
          * 二、进URI匹配,两种状况一是查全部,二是查询一条记录
          * 三、SQliteQueryBuidler的query方法进行查询
          * 四、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) {
     /**
      * 一、判断URI是否匹配,若是匹配抛出异常
      * 二、构建ContentValues,保证插入数据库是不出现异常
      * 三、SqliteDatabase的insert方法进行数据插入
      * 四、根据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) {
     //一、获取sqlitedatabase
     SQLiteDatabase db=dbHelper.getWritableDatabase();
     int count=0;
     final String finalWhere;
     //二、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) {
     //一、获取sqlitedatabase
     SQLiteDatabase db=dbHelper.getWritableDatabase();
     int count=0;
     final String finalWhere;
     //二、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();
      }
  }
}
更新及删除笔记:
  1. 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中注册 及添加权限。

  1. <!-- 注册cp authorities属性必须与代码中一致-->
  2.         <provider android:name=".MyContentProvider"
  3.                   android:authorities="com.example.lessiontwentytwo"
  4.             />
相关文章
相关标签/搜索