學習筆記-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.             />
相關文章
相關標籤/搜索