使用contentprovider实现的日记(转)
目录结构:
MyDiaryActivity.java
package com.zhang.myDiary; import com.zhang.myDiary.DiaryColumn.DiaryClmn; import android.app.Activity; import android.app.ListActivity; import android.content.ContentUris; import android.content.ContentValues; import android.content.Intent; import android.database.Cursor; import android.net.Uri; import android.os.Bundle; import android.view.Menu; import android.view.MenuItem; import android.view.View; import android.widget.ListView; import android.widget.SimpleCursorAdapter; import android.widget.Toast; public class MyDiaryActivity extends ListActivity { /** Called when the activity is first created. */ public static final int MENU_ITEM_INSERT = Menu.FIRST; public static final int MENU_ITEM_EDIT = Menu.FIRST + 1; public static final int MENU_ITEM_DELETE = Menu.FIRST + 2; private static final String PROJECTION[] = new String[] { DiaryClmn._ID, DiaryClmn.TITLE, DiaryClmn.CREATED }; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); setTitle("wyl的diary"); getWindow().setBackgroundDrawableResource(R.drawable.diarybg); //getIntent(): Return the intent that started this activity. Intent intent = getIntent(); if (intent.getData() == null) { intent.setData(DiaryClmn.CONTENT_URI); } Cursor cursor = managedQuery(getIntent().getData(), PROJECTION, null, null, DiaryClmn.DEFAULT_SORT_ORDER); SimpleCursorAdapter adapter = new SimpleCursorAdapter( MyDiaryActivity.this, R.layout.mydiary_row, cursor, new String[] { DiaryClmn.TITLE, DiaryClmn.CREATED }, new int[] { R.id.text1, R.id.created }); setListAdapter(adapter); } public boolean onCreateOptionsMenu(Menu menu) { super.onCreateOptionsMenu(menu); menu.add(0, MENU_ITEM_INSERT, 0, R.string.menu_insert); menu.add(0, android.view.Menu.NONE, 1, R.string.menu_insert_2); return true; } /** * This is called right before the menu is shown, every time it is shown */ public boolean onPrepareOptionsMenu(Menu menu) { super.onPrepareOptionsMenu(menu); System.out.println("public boolean onPrepareOptionsMenu(Menu menu)"); myToast("public boolean onPrepareOptionsMenu(Menu menu) "); /* * getListAdapter():Get the ListAdapter associated with this activity's * ListView. getCount():How many items are in the data set represented * by this Adapter. */ final boolean haveItems = getListAdapter().getCount() > 0; myToast("getListAdapter().getCount()一共有" + getListAdapter().getCount() + "个"); if (haveItems) { // getListView():Get the activity's list view widget. if (getListView().getSelectedItemId() > 0) { menu.removeGroup(1); Uri uri = ContentUris.withAppendedId(getIntent().getData(), getListView().getSelectedItemId()); Intent intent = new Intent(null, uri); // TODO 下面这行代码还不知道到底怎么用 menu.add(1, MENU_ITEM_EDIT, 1, "编辑内容").setIntent(intent); menu.add(1, MENU_ITEM_DELETE, 1, "删除当前日记"); } } else { menu.removeGroup(1); } return true; } /** * 封装 Toast()方法 * * @param string * 要显示的内容 */ private void myToast(String string) { Toast.makeText(this, string, 1000).show(); } public boolean onOptionsItemSelected(MenuItem item) { switch (item.getItemId()) { case MENU_ITEM_INSERT: Intent intent0 = new Intent(this, MyDiaryEdit.class); intent0.setAction(MyDiaryEdit.INSERT_TEXT_ACTION);//设置action, /* * getIntent().getData(): Returns,The URI of the data this * intent is targeting or null. */ intent0.setData(getIntent().getData());//intent设置URI startActivity(intent0); return true; case MENU_ITEM_EDIT: Intent intent1 = new Intent(this, MyDiaryEdit.class); intent1.setAction(MyDiaryEdit.EDIT_TEXT_ACTION); intent1.setData(item.getIntent().getData()); startActivity(intent1); return true; case MENU_ITEM_DELETE: Uri uri = ContentUris.withAppendedId(getIntent().getData(), getListView().getSelectedItemId()); getContentResolver().delete(uri, null, null); rewindView(); } return super.onOptionsItemSelected(item); } protected void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); } @Override protected void onListItemClick(ListView l, View v, int position, long id) { //重要 //Returns: a new URI with the given ID appended to the end of the path Uri uri = ContentUris.withAppendedId(getIntent().getData(), id); /* * new Intent.Intent(String action, Uri uri)这种用法还不太熟悉 * 系统会根据第一个参数(action)在清单文件中找对应的activity,如果对应为多个activity, * 此时就会弹出一个dailog选择Activity */ startActivity(new Intent(MyDiaryEdit.EDIT_TEXT_ACTION, uri)); } private void rewindView() { // TODO Auto-generated method stub Cursor cursor = managedQuery(getIntent().getData(), PROJECTION, null, null, DiaryClmn.DEFAULT_SORT_ORDER); SimpleCursorAdapter adapter = new SimpleCursorAdapter( MyDiaryActivity.this, R.layout.mydiary_row, cursor, new String[] { DiaryClmn.TITLE, DiaryClmn.CREATED }, new int[] { R.id.text1, R.id.created }); setListAdapter(adapter); } }
MyDiaryEdit.java
package com.zhang.myDiary; import com.zhang.myDiary.DiaryColumn.DiaryClmn; import android.app.Activity; import android.content.ContentValues; import android.content.Intent; import android.database.Cursor; import android.graphics.Paint; import android.net.Uri; import android.os.Bundle; import android.util.Log; import android.view.View; import android.widget.Button; import android.widget.EditText; import android.widget.TextView; import android.widget.Toast; public class MyDiaryEdit extends Activity { private static final String TAG = "Diary"; public static final String EDIT_TEXT_ACTION = "com.zhang.myDiary.MyDiaryEdit.EDIT_DIARY"; public static final String INSERT_TEXT_ACTION = "com.zhang.myDiary.MyDiaryEdit.action.INSERT_DIARY"; private static final String[] projection = new String[] { DiaryClmn._ID, DiaryClmn.TITLE, DiaryClmn.BODY }; private static final int STATE_EDIT = 0; private static final int STATE_INSERT = 1; private int mState; private Uri mUri; private Cursor mCursor; private EditText mTitleText; private EditText mBodyText; private Button confirmButton, modifyButton; protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setTheme(android.R.style.Theme_Black); //Return the intent that started this activity. final Intent intent = getIntent(); final String action = intent.getAction(); setContentView(R.layout.mydiaryedit);//添加对应的layout System.out.println("intent.getAction():"+intent.getAction()); myToast("intent.getAction():"+intent.getAction()); TextView wyl_tv = (TextView) findViewById(R.id.wyl_txt); wyl_tv.setText("intent.getAction():"+intent.getAction()+", URI uri = intent.getData(): "+intent.getData()); mTitleText = (EditText) findViewById(R.id.title); mBodyText = (EditText) findViewById(R.id.body); confirmButton = (Button) findViewById(R.id.confirm); modifyButton = (Button) findViewById(R.id.modified); if (EDIT_TEXT_ACTION.equals(action)) { mState = STATE_EDIT; mTitleText.setEnabled(false); mBodyText.setEnabled(false);//设置不可编辑 modifyButton.setVisibility(View.VISIBLE); mUri = intent.getData(); mCursor = managedQuery(mUri, projection, null, null, null); mCursor.moveToFirst(); String title = mCursor.getString(1); mTitleText.setTextKeepState(title); String body = mCursor.getString(2); mBodyText.setTextKeepState(body); setResult(RESULT_OK, new Intent(MyDiaryEdit.EDIT_TEXT_ACTION, mUri)); setTitle("编辑日记"); } else if (INSERT_TEXT_ACTION.equals(action)) { mState = STATE_INSERT; setTitle("新建日记"); } else { Log.e(TAG, "no such action error"); MyDiaryEdit.this.finish(); return; } confirmButton.setOnClickListener(new MyBtnOnClickListen()); modifyButton.setOnClickListener(new MyBtnOnClickListen()); } /** * 封装 Toast()方法 * * @param string 要显示的内容 */ private void myToast(String string) { Toast.makeText(this, string, 1000).show(); } private class MyBtnOnClickListen implements Button.OnClickListener { @Override public void onClick(View v) { // TODO Auto-generated method stub switch (v.getId()) { case R.id.confirm: if (mState == STATE_INSERT) { insertDiary(); } else { // mTitleText.setEnabled(true); // mBodyText.setEnabled(true); updataDiary(); } Intent intent = new Intent(); setResult(RESULT_OK, intent); finish(); break; case R.id.modified: mTitleText.setEnabled(true); mBodyText.setEnabled(true); break; } } private void insertDiary() { // TODO Auto-generated method stub ContentValues values = new ContentValues(); String title = mTitleText.getText().toString(); String body = mBodyText.getText().toString(); values.put(DiaryClmn.CREATED, MyDiaryContentProvider.getFormateCreatedDate()); values.put(DiaryClmn.TITLE, title); values.put(DiaryClmn.BODY, body); getContentResolver().insert(DiaryClmn.CONTENT_URI, values); } private void updataDiary() { // TODO Auto-generated method stub ContentValues values = new ContentValues(); String title = mTitleText.getText().toString(); String body = mBodyText.getText().toString(); values.put(DiaryClmn.CREATED, MyDiaryContentProvider.getFormateCreatedDate()); values.put(DiaryClmn.TITLE, title); values.put(DiaryClmn.BODY, body); getContentResolver().update(mUri, values, null, null); } } }
DiaryColumn.java
package com.zhang.myDiary; import java.net.URI; import android.net.Uri; import android.provider.BaseColumns; import android.text.StaticLayout; public class DiaryColumn { public static final String AUTHORITY = "com.zhang.myDiary.Myprovider"; public DiaryColumn() { } public static final class DiaryClmn implements BaseColumns { private DiaryClmn(){}; public static final Uri CONTENT_URI = Uri.parse("content://" + AUTHORITY + "/diarias"); public static final String CONTENT_TYPE = "vnd.android.cursor.dir/vnd.google.diary"; public static final String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/vnd.google.diary"; public static final String DEFAULT_SORT_ORDER = "created DESC"; public static final String TITLE = "title"; public static final String BODY = "body"; public static final String CREATED = "created"; } }
MyDiaryContentProvider.java
package com.zhang.myDiary; import java.util.Calendar; import java.util.HashMap; import com.zhang.myDiary.DiaryColumn.DiaryClmn; import android.content.ContentProvider; import android.content.ContentUris; import android.content.ContentValues; import android.content.Context; import android.content.UriMatcher; import android.database.Cursor; import android.database.SQLException; import android.database.sqlite.SQLiteDatabase; import android.database.sqlite.SQLiteDatabase.CursorFactory; import android.database.sqlite.SQLiteOpenHelper; import android.database.sqlite.SQLiteQueryBuilder; import android.net.Uri; import android.text.TextUtils; import android.widget.TextView; public class MyDiaryContentProvider extends ContentProvider { private static final String DATABASE_NAME = "Diarydatabase"; private static final int DATABASE_VERSION = 1; private static final String DIARY_TABLE_NAME = "diary"; private static final int DIARIES = 1; private static final int DIARY_ID = 2; private MyDiaryBaseHalper myDiaryBaseHalper; private Context context; private static UriMatcher sUriMatcher; private static HashMap<String,String>mHashMap; static{ sUriMatcher=new UriMatcher(UriMatcher.NO_MATCH); sUriMatcher.addURI(DiaryColumn.AUTHORITY,"diarias",DIARIES); sUriMatcher.addURI(DiaryColumn.AUTHORITY, "diarias/#",DIARY_ID); mHashMap=new HashMap<String, String>(); mHashMap.put(DiaryClmn._ID, DiaryClmn._ID); mHashMap.put(DiaryClmn.TITLE, DiaryClmn.TITLE); mHashMap.put(DiaryClmn.BODY,DiaryClmn.BODY); mHashMap.put(DiaryClmn.CREATED, DiaryClmn.CREATED); } public static class MyDiaryBaseHalper extends SQLiteOpenHelper{ public MyDiaryBaseHalper(Context context, String name, CursorFactory factory, int version) { super(context, name, factory, version); // TODO Auto-generated constructor stub } @Override public void onCreate(SQLiteDatabase db) { // TODO Auto-generated method stub String sql="CREATE TABLE diary("+DiaryClmn._ID+" INTEGER PRIMARY KEY,"+DiaryClmn.TITLE+" TEXT,"+DiaryClmn.BODY+" TEXT,"+DiaryClmn.CREATED+" TEXT"+");"; db.execSQL(sql); } @Override public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { // TODO Auto-generated method stub db.execSQL("DROP TABLE IF EXISTS diary"); onCreate(db); } } @Override public boolean onCreate() { // TODO Auto-generated method stub myDiaryBaseHalper=new MyDiaryBaseHalper(getContext(), DATABASE_NAME, null,DATABASE_VERSION); return true; } @Override public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) { // TODO Auto-generated method stub SQLiteQueryBuilder dp=new SQLiteQueryBuilder(); switch (sUriMatcher.match(uri)) { case DIARIES : dp.setTables(DIARY_TABLE_NAME); dp.setProjectionMap(mHashMap); break; case DIARY_ID: dp.setTables(DIARY_TABLE_NAME); dp.setProjectionMap(mHashMap); dp.appendWhere(DiaryClmn._ID+"="+uri.getPathSegments().get(1)); break; default: throw new IllegalArgumentException("错误 的uri:"+uri); } String olderBY; if (TextUtils.isEmpty(sortOrder)) { olderBY=DiaryClmn.DEFAULT_SORT_ORDER; }else { olderBY=sortOrder; } SQLiteDatabase db=myDiaryBaseHalper.getReadableDatabase(); Cursor cursor=dp.query(db, projection, selection, selectionArgs, null,null, olderBY); cursor.setNotificationUri(getContext().getContentResolver(), uri); return cursor; } @Override public String getType(Uri uri) { // TODO Auto-generated method stub switch (sUriMatcher.match(uri)) { case DIARIES: return DiaryClmn.CONTENT_ITEM_TYPE; case DIARY_ID: return DiaryClmn.CONTENT_ITEM_TYPE; default: throw new IllegalArgumentException("Unknown URI " + uri); } } @Override public Uri insert(Uri uri, ContentValues values) { // TODO Auto-generated method stub SQLiteDatabase db=myDiaryBaseHalper.getWritableDatabase(); long rwId=db.insert(DIARY_TABLE_NAME, DiaryClmn.BODY, values); if (rwId>0) { Uri rwIdUri=ContentUris.withAppendedId(DiaryClmn.CONTENT_URI, rwId); getContext().getContentResolver().notifyChange(rwIdUri,null); return rwIdUri; } throw new SQLException("Failed to insert row into " + uri); } @Override public int delete(Uri uri, String selection, String[] selectionArgs) { // TODO Auto-generated method stub SQLiteDatabase db=myDiaryBaseHalper.getWritableDatabase(); String rwId=uri.getPathSegments().get(1); return db.delete(DIARY_TABLE_NAME, selection+"="+rwId,null); } @Override public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) { // TODO Auto-generated method stub SQLiteDatabase db=myDiaryBaseHalper.getWritableDatabase(); String rwId=uri.getPathSegments().get(1); return db.update(DIARY_TABLE_NAME, values, DiaryClmn._ID+"="+rwId,null); } public static String getFormateCreatedDate() { Calendar calendar = Calendar.getInstance(); String created = calendar.get(Calendar.YEAR) + "年" + calendar.get(Calendar.MONTH) + "月" + calendar.get(Calendar.DAY_OF_MONTH) + "日" + calendar.get(Calendar.HOUR_OF_DAY) + "时" + calendar.get(Calendar.MINUTE) + "分"; return created; } }
main.xml
1 <?xml version="1.0" encoding="utf-8"?> 2 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 3 android:layout_width="fill_parent" 4 android:layout_height="fill_parent" 5 android:layout_gravity="center_vertical" 6 android:orientation="vertical" > 7 8 <ListView 9 android:id="@+id/android:list" 10 android:layout_width="wrap_content" 11 android:layout_height="wrap_content" 12 android:smoothScrollbar="true" /> 13 14 <TextView 15 android:id="@+id/android:empty" 16 android:layout_width="wrap_content" 17 android:layout_height="wrap_content" 18 android:textColor="#000000" 19 android:textStyle="bold" 20 android:text="您还没有开始写日记呢!点击下边的Menu按钮开始写日记吧:)" /> 21 22 </LinearLayout>
mydiary_row.xml
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/row" android:layout_width="fill_parent" android:layout_height="fill_parent" > <TextView android:id="@+id/text1" android:layout_width="wrap_content" android:layout_height="30px" android:layout_marginTop="10dip" android:maxWidth="200dip" android:text="第一组第一项" android:textColor="#000000" android:textSize="22sp" /> <TextView android:id="@+id/created" android:layout_width="wrap_content" android:layout_height="35px" android:layout_alignParentRight="true" android:layout_marginLeft="10dip" android:layout_marginTop="10dip" android:text="2012年4月2号" android:textColor="#000000" /> </RelativeLayout>
mydiaryedit.xml
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="fill_parent" android:orientation="vertical" > <LinearLayout android:layout_width="0dip" android:layout_height="0dip" android:focusable="true" android:focusableInTouchMode="true" /> <LinearLayout android:layout_width="fill_parent" android:layout_height="wrap_content" android:orientation="vertical" > <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:padding="2px" android:text="@string/title" /> <EditText android:id="@+id/title" android:layout_width="fill_parent" android:layout_height="wrap_content" android:textColor="#000000" /> </LinearLayout> <LinearLayout android:layout_width="fill_parent" android:layout_height="fill_parent" android:orientation="vertical" > <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/body" /> <EditText android:id="@+id/body" android:layout_width="fill_parent" android:layout_height="wrap_content" android:singleLine="false" android:textColor="#000000" /> <RelativeLayout android:layout_width="fill_parent" android:layout_height="wrap_content" > <Button android:id="@+id/modified" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentBottom="true" android:text="click me!编辑" android:visibility="invisible" > </Button> <Button android:id="@+id/confirm" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentRight="true" android:layout_alignTop="@+id/modified" android:text=" 确定 " /> </RelativeLayout> </LinearLayout> </LinearLayout>
strings.xml
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="fill_parent" android:orientation="vertical" > <LinearLayout android:layout_width="0dip" android:layout_height="0dip" android:focusable="true" android:focusableInTouchMode="true" /> <LinearLayout android:layout_width="fill_parent" android:layout_height="wrap_content" android:orientation="vertical" > <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:padding="2px" android:text="@string/title" /> <EditText android:id="@+id/title" android:layout_width="fill_parent" android:layout_height="wrap_content" android:textColor="#000000" /> </LinearLayout> <LinearLayout android:layout_width="fill_parent" android:layout_height="fill_parent" android:orientation="vertical" > <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/body" /> <EditText android:id="@+id/body" android:layout_width="fill_parent" android:layout_height="wrap_content" android:singleLine="false" android:textColor="#000000" /> <RelativeLayout android:layout_width="fill_parent" android:layout_height="wrap_content" > <Button android:id="@+id/modified" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentBottom="true" android:text="click me!编辑" android:visibility="invisible" > </Button> <Button android:id="@+id/confirm" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentRight="true" android:layout_alignTop="@+id/modified" android:text=" 确定 " /> </RelativeLayout> </LinearLayout> </LinearLayout>
清单文件
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.zhang.myDiary" android:versionCode="1" android:versionName="1.0" > <uses-sdk android:minSdkVersion="7" /> <application android:icon="@drawable/ic_launcher" android:label="@string/app_name" > <provider android:name="MyDiaryContentProvider" android:authorities="com.zhang.myDiary.Myprovider" /> <activity android:name=".MyDiaryActivity" > <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> <activity android:name="com.zhang.myDiary.MyDiaryEdit" android:label="@string/title_diary" android:theme="@android:style/Theme.Light" > <intent-filter> <action android:name="com.zhang.myDiary.MyDiaryEdit.EDIT_DIARY" /> <category android:name="android.intent.category.DEFAULT" /> <data android:mimeType="vnd.android.cursor.item/vnd.google.diary"/> </intent-filter> <intent-filter> <action android:name="com.zhang.myDiary.MyDiaryEdit.action.INSERT_DIARY" /> <category android:name="android.intent.category.DEFAULT" /> <data android:mimeType="vnd.android.cursor.dir/vnd.google.diary" /> </intent-filter> </activity> </application> </manifest>