学习笔记-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绑定则一定要用到_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功能代码
  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) {
         /**
          * 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();
      }
  }
}
更新及删除笔记:
  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中注册 及添加权限。

<!-- 注册cp authorities属性必须与代码中一致-->         <provider android:name=".MyContentProvider"                   android:authorities="com.example.lessiontwentytwo"             />

转载于:https://my.oschina.net/chaosWL/blog/78226

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值