Android--简单开发和使用ContentProvider数据共享
今天学习的时候学到了ContentProvider数据共享这个东东,所以自己写了个小例子:
我们要开发ContentProvider的话,需要创建一个类去继承ContentProvider,里面会让你重写四个方法,这四个方法就是数据共享用到的方法
包括SQLite的插入、查询、删除。。
所以,如何共享我们的数据,就看你如何重写这几个方法。
下面是操作步骤,我是用Android studio写的
1、先看工程结构
2、我们建立一个继承ContentProvider的类,创建步骤(右键→new→othet→Provider)
3、ContentProvider共享的数据是SQLite里面的数据,为了方便我把创建SQLite的数据库和创建表的操作也写在了ContentProvider的onCreate()方法里面了
代码
package provider; import android.content.ContentProvider; import android.content.ContentUris; import android.content.ContentValues; import android.content.UriMatcher; import android.database.Cursor; import android.database.sqlite.SQLiteDatabase; import android.net.Uri; import toolclass.MySQLiteOpenHelper; public class MyContentProvider extends ContentProvider { private static final String AUTHORITY = "com.example.fanlei.mycontentprovider";//地址 private static final String DB_FILE = "friends.db";//数据库名称 private static final String DB_TABLE = "friends"; //表名 private static final int URI_ROOT = -1; private static final int DB_TABLE_FRIENDS = 1; public static final Uri CONTENT_URI = Uri.parse("content://" + AUTHORITY + "/" + DB_TABLE);//Uri所对应的资源 private static final UriMatcher uriMatcher = new UriMatcher(URI_ROOT);//检查传过来的Uri static { uriMatcher.addURI(AUTHORITY,DB_TABLE,DB_TABLE_FRIENDS); } private MySQLiteOpenHelper helper; private SQLiteDatabase db; public MyContentProvider() { } @Override public int delete(Uri uri, String selection, String[] selectionArgs) { // Implement this to handle requests to delete one or more rows. throw new UnsupportedOperationException("Not yet implemented"); } @Override public String getType(Uri uri) { // TODO: Implement this to handle requests for the MIME type of the data // at the given URI. throw new UnsupportedOperationException("Not yet implemented"); } @Override public Uri insert(Uri uri, ContentValues values) { //检查传过来的Uri是否是正确的,若不正确,则抛出异常 if (uriMatcher.match(uri) != DB_TABLE_FRIENDS){ throw new IllegalArgumentException("Unknown URI:" + uri); } Long rawId = db.insert(DB_TABLE,null,values); Uri returnUri = ContentUris.withAppendedId(CONTENT_URI,rawId); getContext().getContentResolver().notifyChange(returnUri,null); return returnUri; } @Override public boolean onCreate() { helper = new MySQLiteOpenHelper(getContext(),DB_FILE,null,1); db = helper.getWritableDatabase(); String sql = "CREATE TABLE IF NOT EXISTS " + DB_TABLE +"(" + "_id primary key," + "name text," + "sexId text," + "address text);"; db.execSQL(sql); return true; } @Override public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) { //检查传过来的Uri是否是正确的,若不正确,则抛出异常 if (uriMatcher.match(uri) != DB_TABLE_FRIENDS){ throw new IllegalArgumentException("Unknown URI:" + uri); } Cursor cursor = db.query(true,DB_TABLE,projection,selection,selectionArgs,null,null,sortOrder,null); cursor.setNotificationUri(getContext().getContentResolver(),uri); return cursor; } @Override public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) { // TODO: Implement this to handle requests to update one or more rows. throw new UnsupportedOperationException("Not yet implemented"); } }
其实,ContentProvider里面重写的方法也是封装了SQLiteDataBase的方法的操作,只不过他需要一个具体的Uri去指向我们具体的资源。
ContentProvider开发完成后,我在主函数里面调用了我们写的这个ContentProvider里面的方法,布局什么的都很简单。
我只是插入了数据,查询数据
下面是主函数:
package com.example.fanlei.mycontentproviderdemo; import android.annotation.TargetApi; import android.content.ContentResolver; import android.content.ContentValues; import android.database.Cursor; import android.net.Uri; import android.os.Build; import android.os.Bundle; import android.support.v7.app.ActionBarActivity; import android.util.Log; import android.view.View; import android.widget.Button; import android.widget.EditText; import android.widget.Toast; import provider.MyContentProvider; public class MainActivity2 extends ActionBarActivity { private ContentResolver contentResolver; private Uri uri; private EditText et_1,et_2,et_3; private Button btn_1,btn_2; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main_activity2); contentResolver = getContentResolver(); uri = MyContentProvider.CONTENT_URI; et_1 = (EditText) findViewById(R.id.et_1); et_2 = (EditText) findViewById(R.id.et_2); et_3 = (EditText) findViewById(R.id.et_3); btn_1 = (Button) findViewById(R.id.btn_1); btn_2 = (Button) findViewById(R.id.btn_2); //加入 btn_1.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { ContentValues cv = new ContentValues();//键值 就是 列名 cv.put("name",et_1.getText().toString()); cv.put("sexId",et_2.getText().toString()); cv.put("address",et_3.getText().toString()); contentResolver.insert(uri,cv); Toast.makeText(MainActivity2.this,"加入成功",Toast.LENGTH_SHORT).show(); } }); //查询 btn_2.setOnClickListener(new View.OnClickListener() { @TargetApi(Build.VERSION_CODES.JELLY_BEAN) @Override public void onClick(View v) { Cursor cursor = contentResolver.query(uri,null,"name like ?",new String[]{"%23%"},null,null); while (cursor.moveToNext()){ String name = cursor.getString(cursor.getColumnIndex("name")); String sexId = cursor.getString(cursor.getColumnIndex("sexId")); String address = cursor.getString(cursor.getColumnIndex("address")); Log.d("asdasd",name+"^^"+sexId+"^^"+address); } } }); } }
====================================以上是简单的开发=======================================
下面是使用我们上面的工程创建的ContentProvider
先看工程结构:
我这里建立了一个工具类去存放上一个工程Uri。
布局什么的都很简单,就一个TextView和Button,就不放了。
下面是主函数的代码
package com.example.fanlei.textmycontentproviderdemo; import android.content.ContentResolver; import android.database.ContentObserver; import android.database.Cursor; import android.os.Bundle; import android.os.Handler; import android.support.v7.app.ActionBarActivity; import android.util.Log; import android.view.View; import android.widget.Button; import android.widget.TextView; import provider.PeopleInfoProvider; public class MainActivity extends ActionBarActivity { private TextView tv_show; private Button button; private ContentResolver contentResolver; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); contentResolver = getContentResolver(); tv_show = (TextView) findViewById(R.id.tv_show); button = (Button) findViewById(R.id.btn); button.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { Cursor cursor = contentResolver.query(PeopleInfoProvider.CONTENT_URI,null,null,null,null); StringBuilder sb = new StringBuilder(); while (cursor.moveToNext()){ String name = cursor.getString(cursor.getColumnIndex("name")); String sexId = cursor.getString(cursor.getColumnIndex("sexId")); String address = cursor.getString(cursor.getColumnIndex("address")); sb.append(name).append(sexId).append(address); } tv_show.setText(sb.toString()); } }); contentResolver.registerContentObserver(PeopleInfoProvider.CONTENT_URI,true,new MyObserver(new Handler())); } private class MyObserver extends ContentObserver{ /** * Creates a content observer. * @param handler The handler to run {@link #onChange} on, or null if none. */ public MyObserver(Handler handler) { super(handler); } @Override public void onChange(boolean selfChange) { super.onChange(selfChange); Cursor cursor = contentResolver.query(PeopleInfoProvider.CONTENT_URI,null,null,null,null); StringBuilder sb = new StringBuilder(); while (cursor.moveToNext()){ String name = cursor.getString(cursor.getColumnIndex("name")); String sexId = cursor.getString(cursor.getColumnIndex("sexId")); String address = cursor.getString(cursor.getColumnIndex("address")); sb.append(name).append(sexId).append(address); Log.d("-----update----",sb.toString()); } tv_show.setText(sb.toString()); } } }
对了,这里我写了一个内部类去继承了ContentObserver这个类,它的作用就是当共享的数据发生改变时,就会触发这个方法。