Android 四大应用组件之ContentProvider
2016-11-10 11:02
363 查看
Android 四大应用组件之ContentProvider
1、理解
1)什么是ContentProviderContentProvider是四大应用组件之一
当前应用使用ContentProvider将数据库表数据操作暴露给其它应用访问
其它应用需要使用ContentResolver来调用ContentProvider的方法
它们之间的调用是通过Uri来进行交流的
2) 为什么需要ContentProvider
功能需求:一个应用需要访问另一个应用的数据库表数据data/data/应用包名、databases/xxx.db
实际情况:一个应用数据库文件是该是应用私有的,其它应用不能直接访问
2、相关API
1)ContentProvider : 内容提供者类//provider对象创建后调用(应用安装成功或手机启动完成)
public abstract boolean onCreate();
//查询表数据
Cursor query(Uri uri, String[] projection,String selection, String[] selectionArgs)
//插入表数据
Uri insert(Uri uri, ContentValues values);
//删除表数据
int delete(Uri uri, String selection, String[] selectionArgs)
//更新表数据
update(Uri uri, ContentValues values, String selection,String[] selectionArgs);
2)ContentResolver: 内容提供者的解析类
//得到它的对象
context.getContentResolver()
//调用provider进行数据库CRUD操作
insert()、delete()、update()、query()
//注册uri的监听
registerContentObserver(Uri uri, boolean notify,ContentObserver observer)
//解注册uri的监听
unregisterContentObserver(ContentObserver observer)
//通知监听器
notifyChange(Uri uri, ContentObserver observer)
3)Uri: 包含请求地址数据的类
//得到其对象
Uri static parse(String uriString) “tel:”+ number
url: http://192.168.10.165:8080/Web_Demo/index.jsp
Uri: content://com.atguigu.pro.contentprovider1/user/
A : 是一个前缀,表示是由ContentProvider提供,固定不变
B : authority, 标识是哪个Provider,不同的Provider此部分必须不同。
C : 对应于哪张表 student
D : id值, 对应表中的哪条记录(可选的)
4)UriMatcher : 用于匹配Uri的容器
//添加一个合法的URI
void addURI(String authority, String path, int code)
//匹配指定的uri, 返回匹配码
int match(Uri uri)
5)ContentUris : 解析uri的工具类
//解析uri, 得到其中的id
long parseId(Uri contentUri)
//添加id到指定的uri中
Uri withAppendedId(Uri contentUri, long id)
3 使用基本步骤
1)编写ContentProvider子类class PersonProvide extends ContentProvider {
//实现inert、delete、update和query等方法
}
/** * Created by Jin on 2016/9/13. */ public class PersonProvide extends ContentProvider { //得到数据库帮助类对象 private DBHelper dbHelper; //提供一个盛放uri的容器 UriMatcher.NO_MATCH 什么意思? private static final UriMatcher matcher = new UriMatcher(UriMatcher.NO_MATCH); static { //参数1:指明authority、参数2:指明访问路径、参数3:给当前的uri赋一个唯一的id。 matcher.addURI("com.atguigu.l9_provider.PersonProvide", "person/", 1); matcher.addURI("com.atguigu.l9_provider.PersonProvide", "person/#", 2); } @Override public boolean onCreate() { dbHelper = new DBHelper(getContext(), 1); //ContentProvider 有一个getContext()方法 return true; //表示正确加载了 } /** * 提供对外查询的操作 * * @param uri * @param projection * @param selection * @param selectionArgs * @param sortOrder * @return */ @Override public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) { //根据ContentResolver发送过来的uri,获取其id,判断是容器中的哪个id int code = matcher.match(uri); //获取一个数据连接 SQLiteDatabase database = dbHelper.getReadableDatabase(); Cursor cursor = null; try { if (code == 1) { cursor = database.query("person", projection, selection, selectionArgs, null, null, sortOrder); return cursor; } else if (code == 2) { //解析Uri 得到其中id long id = ContentUris.parseId(uri); cursor = database.query("person", projection, "_id = ?", new String[]{id + ""}, null, null, sortOrder); return cursor; } else { throw new RuntimeException("输入的uri不合法"); } } finally { //关闭操作 // cursor.close();; // database.close(); } } @Override public String getType(Uri uri) { return null; } /** * 提供对外添加的操作 * * @param uri * @param values * @return */ @Override public Uri insert(Uri uri, ContentValues values) { int code = matcher.match(uri); SQLiteDatabase database = dbHelper.getReadableDatabase(); try { if (code == 1) { long newID = database.insert("person", null, values); //将发送过来的uri追加插入成功返回的id后返回。 Uri newUri = ContentUris.withAppendedId(uri, newID); return newUri; } else { throw new RuntimeException("输入的uri不合法"); } } finally { if (database != null) { database.close(); } } } /** * 提供对外删除的操作 * * @param uri * @param selection * @param selectionArgs * @return */ @Override public int delete(Uri uri, String selection, String[] selectionArgs) { int code = matcher.match(uri); SQLiteDatabase database = dbHelper.getReadableDatabase(); try { if (code == 1) { int deleteCount = database.delete("person",selection,selectionArgs); return deleteCount; } else if (code == 2) { long id = ContentUris.parseId(uri); int deleteCount = database.delete("person", "_id = ?", new String[]{id + ""}); return deleteCount; } else{ throw new RuntimeException("输入的uri不合法"); } } finally { database.close(); } } @Override public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) { int code = matcher.match(uri); SQLiteDatabase database = dbHelper.getReadableDatabase(); try { if (code == 1) { int updateCount = database.update("person",values,selection,selectionArgs); return updateCount; } else if (code == 2) { long id = ContentUris.parseId(uri); int updateCount = database.update("person",values, "_id = ?", new String[]{id + ""}); return updateCount; } else{ throw new RuntimeException("输入的uri不合法"); } } finally { database.close(); } } }
2)在manifest.xml中注册
ContentResolver resolver = getContentResolver();
4)使用其对象
inert()、delete()、update()和query()
系统自动找到匹配的ContentProvider对象来操作数据
registerContentObserver(Uri uri, boolean notify,ContentObserver
observer) 注册uri的监听
unregisterContentObserver(ContentObserver observer) 解注册uri的监听
notifyChange(Uri uri, ContentObserver observer) 通知监听器
/** * 测试使用ContentResolver调用ContentProvider的主界面 * @author shkstart * */ public class MainActivity extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); } /* * 通过ContentResolver调用ContentProvider插入一条记录 */ public void insert(View v) { ContentResolver resolver = getContentResolver(); Uri uri = Uri.parse("content://com.atguigu.l9_provider.PersonProvide/person/"); ContentValues values = new ContentValues(); values.put("name","dongdong"); Uri newUri = resolver.insert(uri, values); Log.e("TAG",newUri.toString()); } /* * 通过ContentResolver调用ContentProvider更新一条记录 */ public void update(View v) { ContentResolver resolver = getContentResolver(); Uri uri = Uri.parse("content://com.atguigu.l9_provider.PersonProvide/person/2"); ContentValues values = new ContentValues(); values.put("name", "jinxiaodong"); int updateCount = resolver.update(uri, values, null, null); Log.e("TAG","修改了"+updateCount+"条数据"); } /* * 通过ContentResolver调用ContentProvider删除一条记录 */ public void delete(View v) { ContentResolver resolver = getContentResolver(); Uri uri = Uri.parse("content://com.atguigu.l9_provider.PersonProvide/person/2"); int deleteCount = resolver.delete(uri, null, null); Log.e("TAG","删除了"+deleteCount+"条数据"); } /* * 通过ContentResolver调用ContentProvider查询所有记录 */ public void query(View v) { //获取ContentResolver的对象 ContentResolver resolver = getContentResolver(); //提供查询需要的参数 Uri uri = Uri.parse("content://com.atguigu.l9_provider.PersonProvide/person/"); //3.进行查询:调用ContentResolver的query(),实际上就会触发对ContentProvider的query()方法的调用 //ContentProvider的query()方法的返回值即为如下的ContentResolver的query()的返回值 Cursor cursor = resolver.query(uri, null, null, null, null); //4.从cursor中读取数据 while (cursor.moveToNext()){ int id = cursor.getInt(0); String name = cursor.getString(1); Log.e("TAG","id = "+id+",name = "+name); } //关闭资源 cursor.close(); } }
4 贴一个小demo
//调用系统联系人 public class MainActivity extends Activity { private EditText tv_main_number; private static final int requestCode = 1; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); tv_main_number = (EditText) findViewById(R.id.tv_main_number); } public void selectContacts(View v) { Intent intent = new Intent(this, ContactsActivity.class); startActivityForResult(intent, requestCode); } @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { if (requestCode == 1 && resultCode == RESULT_OK) { String number = data.getStringExtra("number"); tv_main_number.setText(number); } } }
//listview/adapter/list/itemlayout public class ContactsActivity extends Activity implements AdapterView.OnItemClickListener { private ListView lv_contacts; private ContactsAdapter adapter; List<Map<String, String>> list; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_contacts); //初始化listView lv_contacts = (ListView) findViewById(R.id.lv_contacts); //初始化数据 initdata(); //初始化adapter adapter = new ContactsAdapter(); lv_contacts.setAdapter(adapter); lv_contacts.setOnItemClickListener(this); } //初始化集合数据 private List<Map<String, String>> initdata() { list = new ArrayList<>(); //得到ContentResolver对象 ContentResolver resolver = this.getContentResolver(); Uri uri = ContactsContract.CommonDataKinds.Phone.CONTENT_URI; String name = ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME; String number = ContactsContract.CommonDataKinds.Phone.NUMBER; //第二个参数什么意思?查询表中的那几个字段 Cursor cursor = resolver.query(uri, new String[]{name, number}, null, null, null); while (cursor.moveToNext()) { Map<String, String> map = new HashMap<>(); String namevalue = cursor.getString(cursor.getColumnIndex(name)); String numbervalue = cursor.getString(cursor.getColumnIndex(number)); map.put("name", namevalue); map.put("number", numbervalue); list.add(map); } cursor.close(); return list; } @Override public void onItemClick(AdapterView<?> parent, View view, int position, long id) { String number = list.get(position).get("number"); Intent intent = getIntent(); intent.putExtra("number", number); setResult(RESULT_OK, intent); finish(); } class ContactsAdapter extends BaseAdapter { @Override public int getCount() { return list == null ? 0 : list.size(); } @Override public Object getItem(int position) { return list == null ? null : list.get(position); } @Override public long getItemId(int position) { return position; } @Override public View getView(int position, View convertView, ViewGroup parent) { ViewHolder viewHolder; if (convertView == null) { convertView = View.inflate(ContactsActivity.this, R.layout.item_contacts, null); viewHolder = new ViewHolder(); convertView.setTag(viewHolder); viewHolder.tv_item_name = (TextView) convertView.findViewById(R.id.tv_item_name); viewHolder.tv_item_number = (TextView) convertView.findViewById(R.id.tv_item_number); } else { viewHolder = (ViewHolder) convertView.getTag(); } //装配数据 Map<String, String> map = list.get(position); viewHolder.tv_item_name.setText(map.get("name")); viewHolder.tv_item_number.setText(map.get("number")); return convertView; } } class ViewHolder { TextView tv_item_name; TextView tv_item_number; } }
配置文件:
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.atguigu.l09_app_contacts"> <uses-permission android:name="android.permission.READ_CONTACTS"></uses-permission> <application android:allowBackup="true" android:icon="@mipmap/ic_launcher" android:label="@string/app_name" android:supportsRtl="true" android:theme="@style/AppTheme"> <activity android:name=".MainActivity"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> <activity android:name=".ContactsActivity"></activity> </application> </manifest>
刚开始学Android,有错误的还请指出~~
相关文章推荐
- 四大应用组件之ContentProvider【Android】
- Android四大组件应用系列——使用ContentProvider实现跨进程通讯
- Android核心技术之(9)---四大应用组件之ContentProvider
- Android四大组件之ContentProvider实现多应用之间传递数据实例
- 【Android基础入门〖6〗】四大组件之ContentProvider
- android 四大重要的组件之ContentProvider
- android 四大组件之ContentProvider
- Android 四大组件(Activity、Service、BroadCastReceiver、ContentProvider)
- android四大组件--ContentProvider具体解释
- Android应用基础及原理概要,四大组件
- 四,android四大组件基础介绍及打电话,发短信简单应用 &单元测试
- 01 Android应用的构成 四大组件 Activity, Intent Receiver , Service , Content Provider
- Android四大应用构件之ContentProvider解析
- Android 四大组件之一 ContentProvider
- Android学习日志13__四大组件04__ContentProvider
- Android四大组件之一之内容提供者ContentProvider
- android四大组件之ContentProvider
- Android四大组件之一ContentProvider(内容提供者)
- 【Android基础入门〖6〗】四大组件之ContentProvider
- Android的四大组件之ContentProvider总结