Android 内容提供者(ContentProvider)的简单实用
Android 中的数据库是对应用私有的,自己是无法使用别的应用的数据库的。但是往往有需求要我们使用另外一个应用或者系统应用的数据,这时候就彰显了内容提供者,ContentPrivider的作用,他就是两个应用数据的桥梁,通过内容提供者和内容接受者我们可以在不同应用间传递数据。
ContentPrivider也可以视为一种数据存储。它存储数据的方式和使用它的应用程序无关,重要的是应用如何以一致的编程接口,来访问存储其中的数据。内容提供者与数据库的使用差不多,也可以增删改查。而且数据可以存储于数据库,文件中,也可以网络上。
简单的定义自己的内容提供者:
首先使用ContentPrivider像使用Activity一样,要再清单文件中注册,注册方法也很简单,在<application></application>节点下注册即可
1 <provider 2 android:name="com.tai.provider.PersonDBProvider" 3 android:authorities="com.tai.mylistview.personProvider"/>
android:nameContentProvider的类的全类明名,
android:authorities 可以理解为ContentProvioder的名字,主机名。
还可以制定上权限:android:permission="android.permission.WRITE_SYNC_SETTINGS" 。
Add a URI to match, and the code to return when this URI is matched. URI nodes may be exact match string, the token "*" that matches any text, or the token "#" that matches only numbers.
Starting from API level
android.os.Build.VERSION_CODES.JELLY_BEAN_MR2
,
this method will accept leading slash in the path.
- Parameters:
- authority the authority to match
- path the path to match. * may be used as a wild card for any text, and # may be used as a wild card for numbers.
- code the code that is returned when a URI is matched against the given components. Must be positive.
再声明一个继承自ContentProvider的类,来制定内容提供者的方法。
1 package com.tai.provider; 2 3 import com.tai.db.PersonDBOpenHelper; 4 5 import android.content.ContentProvider; 6 import android.content.ContentUris; 7 import android.content.ContentValues; 8 import android.content.UriMatcher; 9 import android.database.Cursor; 10 import android.database.sqlite.SQLiteDatabase; 11 import android.net.Uri; 12 13 public class PersonDBProvider extends ContentProvider { 14 /** 15 * 使用contentProvider必须要再清单文件中注册 16 * content://com.tai.mylistview.personProvider/insert 17 * content://com.tai.mylistview.personProvider/query 18 * content://com.tai.mylistview.personProvider/delete 19 * content://com.tai.mylistview.personProvider/update 20 */ 21 22 private static final int INSERT= 1; 23 private static final int DELETE= 2; 24 private static final int UPDATE= 3; 25 private static final int QUERY= 4; 26 private static final int QUERYONE = 5; 27 //定义一个Uri的匹配器,用于匹配Uri,如果路径不满足条件 返回-1 UriMatcher.NO_MATCH =-1 28 private static UriMatcher matcher = new UriMatcher(UriMatcher.NO_MATCH); 29 private PersonDBOpenHelper helper; 30 static{ 31 //添加一组匹配规则 32 //第一个参数是主机名 再清单文件中注册的时候的 authority 33 matcher.addURI("com.tai.mylistview.personProvider", "insert", INSERT); 34 matcher.addURI("com.tai.mylistview.personProvider", "delete", DELETE); 35 matcher.addURI("com.tai.mylistview.personProvider", "update", UPDATE); 36 matcher.addURI("com.tai.mylistview.personProvider", "query", QUERY); 37 matcher.addURI("com.tai.mylistview.personProvider", "query/#", QUERYONE); 38 } 39 40 //在内容提供者创建的额时候 41 @Override 42 public boolean onCreate() { 43 helper = new PersonDBOpenHelper(getContext()); 44 return false; 45 } 46 47 48 @Override 49 public Cursor query(Uri uri, String[] projection, String selection, 50 String[] selectionArgs, String sortOrder) { 51 Cursor cursor; 52 if( matcher.match(uri) == QUERY) 53 {//返回查询结果集 54 SQLiteDatabase database = helper.getReadableDatabase(); 55 cursor = database.query("person",projection , selection, selectionArgs, null, null, sortOrder); 56 } 57 else if (matcher.match(uri)==QUERYONE) 58 { 59 long id = ContentUris.parseId(uri);//取出rui的最后位的ID 60 SQLiteDatabase database = helper.getReadableDatabase(); 61 cursor = database.query("person",projection, "id = ?", new String[]{id+""}, null, null, sortOrder); 62 } 63 else 64 { 65 throw new IllegalArgumentException("路径不匹配,不能执行查询操作"); 66 } 67 //这里的数据库不能关闭了,关闭之后Cursor就拿不到数据了 68 return cursor; 69 } 70 71 @Override 72 public String getType(Uri uri) { 73 if( matcher.match(uri) == QUERY) 74 {//查询的是多条数据 75 76 return "vnd.android.cursor.dir/persons"; 77 } 78 else if (matcher.match(uri)==QUERYONE) 79 {//查询的是一条具体的数据 80 return "vnd.android.cursor.item"; 81 } 82 return null; 83 } 84 85 @Override 86 public Uri insert(Uri uri, ContentValues values) { 87 if( matcher.match(uri) == INSERT) 88 { 89 SQLiteDatabase database = helper.getWritableDatabase(); 90 long id = database.insert("person", null, values); 91 } 92 else 93 { 94 throw new IllegalArgumentException("路径不匹配,不能执行查询操作"); 95 } 96 return null; 97 } 98 99 @Override 100 public int delete(Uri uri, String selection, String[] selectionArgs) { 101 long id ; 102 if( matcher.match(uri) == DELETE) 103 { 104 SQLiteDatabase database = helper.getWritableDatabase(); 105 id = database.delete("person", selection, selectionArgs); 106 } 107 else 108 { 109 throw new IllegalArgumentException("路径不匹配,不能执行查询操作"); 110 } 111 return (int) id; 112 } 113 114 @Override 115 public int update(Uri uri, ContentValues values, String selection, 116 String[] selectionArgs) { 117 long id; 118 if( matcher.match(uri) == UPDATE) 119 { 120 SQLiteDatabase database = helper.getWritableDatabase(); 121 id = database.update("person", values, selection, selectionArgs); 122 } 123 else 124 { 125 throw new IllegalArgumentException("路径不匹配,不能执行查询操作"); 126 } 127 return (int) id; 128 } 129 130 }
ok,这样就定义好了自己的内容提供者,也就向外部应用提供了正删改查自己数据库的接口。现在就可以新建一个类来使用这个内容提供者了。
如果在定义的时候加上了权限那么在使用的时候也要加上相应的权限,否则无法使用。
针对上面的内容提供者的使用方法:
1 package com.tai.other; 2 3 import android.net.Uri; 4 import android.os.Bundle; 5 import android.app.Activity; 6 import android.content.ContentResolver; 7 import android.content.ContentValues; 8 import android.database.Cursor; 9 import android.util.Log; 10 import android.view.Menu; 11 import android.view.View; 12 import android.view.View.OnClickListener; 13 import android.view.Window; 14 import android.widget.Button; 15 16 public class MainActivity extends Activity implements OnClickListener { 17 18 private Button button; 19 private Button button2; 20 private Button button3; 21 private Button button4; 22 @Override 23 protected void onCreate(Bundle savedInstanceState) { 24 super.onCreate(savedInstanceState); 25 requestWindowFeature(Window.FEATURE_NO_TITLE); 26 setContentView(R.layout.activity_main); 27 initview(); 28 initData(); 29 } 30 //查 增 修改 删除 31 32 private void initData() { 33 // TODO Auto-generated method stub 34 button = (Button) findViewById(R.id.button); 35 button2 = (Button) findViewById(R.id.button2); 36 button3 = (Button) findViewById(R.id.button3); 37 button4 = (Button) findViewById(R.id.button4); 38 39 button.setOnClickListener(this); 40 button2.setOnClickListener(this); 41 button3.setOnClickListener(this); 42 button4.setOnClickListener(this); 43 } 44 45 private void initview() { 46 // TODO Auto-generated method stub 47 48 } 49 50 @Override 51 public void onClick(View v) { 52 // TODO Auto-generated method stub 53 ContentResolver contentResolver = getContentResolver(); 54 switch (v.getId()) { 55 56 case R.id.button: 57 Uri uri = Uri.parse("content://com.tai.mylistview.personProvider/query"); 58 Cursor cursor = contentResolver.query(uri, null, null, 59 null, null); 60 while(cursor.moveToNext()) 61 { 62 Log.i("MyTag", cursor.getString(cursor.getColumnIndex("name"))); 63 } 64 cursor.close(); 65 break; 66 case R.id.button2: 67 Uri uri2 = Uri.parse("content://com.tai.mylistview.personProvider/insert"); 68 ContentValues contentValues = new ContentValues(); 69 contentValues.put("name", "zhangsan"); 70 contentValues.put("phone", "15203703331"); 71 contentResolver.insert(uri2, contentValues); 72 break; 73 case R.id.button3: 74 Uri uri3 = Uri.parse("content://com.tai.mylistview.personProvider/update"); 75 ContentValues contentValues2 = new ContentValues(); 76 contentValues2.put("phone", "1520370123"); 77 int id = contentResolver.update(uri3, contentValues2, "name=?", new String[]{"zhangsan"}); 78 Log.i("MyTag", id +"新增后的id"); 79 break; 80 case R.id.button4: 81 Uri uri4 = Uri.parse("content://com.tai.mylistview.personProvider/delete"); 82 int id2 = contentResolver.delete(uri4, "name=?", new String[]{"zhangsan"}); 83 Log.i("MyTag", id2 +"删除后的id"); 84 break; 85 default: 86 break; 87 } 88 } 89 90 }
Ok 这就是内容提供者的简单创建以及使用。