android基础之五——内容提供者
来源:互联网 发布:php 检验日期格式 编辑:程序博客网 时间:2024/05/21 21:50
内容提供者
01_为什么需要内容提供者
为了能够让其他应用程序访问本地应用程序中数据库,使用内容提供者对外开放几个接口,让其他应用程序调用这些接口。
02_编写内容提供者(重点)
步骤:1、在工程中添加一个内容提供者的类,继承ContentProvider,重写其中的方法;2、在配置文件中配置一个provider,指定主机名唯一标示内容提供者(android4.1.2之后的版本中,需要指定exported=true,否则其他应程序没有权限访问该内容提供者);3、在内容提供者类里面,创建一个uriMather(柜员),然后做岗前培训,添加增删改查的uri;4、在内容提供者的增删改查的方法判断uri是否匹配正确,再调用数据库的增删改查的方法访问数据库;
03_内容提供者工作的原理(重点)
在其他应用程序中,通过内容提供者的解析器,操作内容提供者。通过一个uri唯一的匹配内容提供者,在uri中指定了操作的路径(内容提供者已经匹配过的路径),内容提供者接收到这个uri后就可以做相应的操作;uri urlhttp://www.baidu.com:80/i.htmlcontentftp://uri组成:schemel,主机名、端口、路径http://www.baidu.com/i.htmlcontent://com.itheima.dbapp.accountcontentprovider/delete
04_内容提供者的增删改查的实现
代码:package com.itheima.dbapp;import android.content.ContentProvider;import android.content.ContentValues;import android.content.UriMatcher;import android.database.Cursor;import android.database.sqlite.SQLiteDatabase;import android.net.Uri;public class AccountContentProvider extends ContentProvider { private AccountDBHelper helper; private static String INSERT = "insert"; private static String DELETE = "delete"; private static String UPDATE = "update"; private static String QUERY = "query"; //创建一个银行的柜员 private static UriMatcher mUriMatcher = new UriMatcher(UriMatcher.NO_MATCH); //柜员的岗前培训 static{// content://com.itheima.dbapp.accountcontentprovider/insert// content://com.itheima.dbapp.accountcontentprovider/delete mUriMatcher.addURI("com.itheima.dbapp.accountcontentprovider", INSERT, 1); mUriMatcher.addURI("com.itheima.dbapp.accountcontentprovider", DELETE, 2);** mUriMatcher.addURI("com.itheima.dbapp.accountcontentprovider", UPDATE, 3); mUriMatcher.addURI("com.itheima.dbapp.accountcontentprovider", QUERY, 4); } /** * 初始化实例对象 * 通常是创建一个数据库帮助类的对象 */ @Override public boolean onCreate(){ helper = new AccountDBHelper(getContext()); return false; } @Override public Uri insert(Uri uri, ContentValues values) { //匹配用户的相应操作,匹配码与柜员培训的匹配吗一致 if(mUriMatcher.match(uri) == 1){ SQLiteDatabase db = helper.getWritableDatabase(); db.insert("account", null, values); } return null; } @Override public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) { if(mUriMatcher.match(uri) == 4){ SQLiteDatabase db = helper.getWritableDatabase(); return db.query("account", projection, selection, selectionArgs, null, null, sortOrder); }else{ return null; } } @Override public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) { if(mUriMatcher.match(uri) == 3){ SQLiteDatabase db = helper.getWritableDatabase(); db.update("account", values, selection, selectionArgs); } return 0; } @Override public int delete(Uri uri, String selection, String[] selectionArgs) { if(mUriMatcher.match(uri) == 2){ SQLiteDatabase db = helper.getWritableDatabase(); db.delete("account", selection, selectionArgs); } return 0; } @Override public String getType(Uri uri) { return null; }}
05_内容提供者的使用场景
为了能够让其他应用程序访问本地应用程序中数据库,使用内容提供者对外开放几个接口,让其他应用程序调用这些接口。
步骤:1、在工程中添加一个内容提供者的类,继承ContentProvider,重写其中的方法;2、在配置文件中配置一个provider,指定主机名唯一标示内容提供者(android4.1.2之后的版本中,需要指定exported=true,否则其他应程序没有权限访问该内容提供者);3、在内容提供者类里面,创建一个uriMather(柜员),然后做岗前培训,添加增删改查的uri;4、在内容提供者的增删改查的方法判断uri是否匹配正确,再调用数据库的增删改查的方法访问数据库;
在其他应用程序中,通过内容提供者的解析器,操作内容提供者。通过一个uri唯一的匹配内容提供者,在uri中指定了操作的路径(内容提供者已经匹配过的路径),内容提供者接收到这个uri后就可以做相应的操作;uri urlhttp://www.baidu.com:80/i.htmlcontentftp://uri组成:schemel,主机名、端口、路径http://www.baidu.com/i.htmlcontent://com.itheima.dbapp.accountcontentprovider/delete
代码:package com.itheima.dbapp;import android.content.ContentProvider;import android.content.ContentValues;import android.content.UriMatcher;import android.database.Cursor;import android.database.sqlite.SQLiteDatabase;import android.net.Uri;public class AccountContentProvider extends ContentProvider { private AccountDBHelper helper; private static String INSERT = "insert"; private static String DELETE = "delete"; private static String UPDATE = "update"; private static String QUERY = "query"; //创建一个银行的柜员 private static UriMatcher mUriMatcher = new UriMatcher(UriMatcher.NO_MATCH); //柜员的岗前培训 static{// content://com.itheima.dbapp.accountcontentprovider/insert// content://com.itheima.dbapp.accountcontentprovider/delete mUriMatcher.addURI("com.itheima.dbapp.accountcontentprovider", INSERT, 1); mUriMatcher.addURI("com.itheima.dbapp.accountcontentprovider", DELETE, 2);** mUriMatcher.addURI("com.itheima.dbapp.accountcontentprovider", UPDATE, 3); mUriMatcher.addURI("com.itheima.dbapp.accountcontentprovider", QUERY, 4); } /** * 初始化实例对象 * 通常是创建一个数据库帮助类的对象 */ @Override public boolean onCreate(){ helper = new AccountDBHelper(getContext()); return false; } @Override public Uri insert(Uri uri, ContentValues values) { //匹配用户的相应操作,匹配码与柜员培训的匹配吗一致 if(mUriMatcher.match(uri) == 1){ SQLiteDatabase db = helper.getWritableDatabase(); db.insert("account", null, values); } return null; } @Override public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) { if(mUriMatcher.match(uri) == 4){ SQLiteDatabase db = helper.getWritableDatabase(); return db.query("account", projection, selection, selectionArgs, null, null, sortOrder); }else{ return null; } } @Override public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) { if(mUriMatcher.match(uri) == 3){ SQLiteDatabase db = helper.getWritableDatabase(); db.update("account", values, selection, selectionArgs); } return 0; } @Override public int delete(Uri uri, String selection, String[] selectionArgs) { if(mUriMatcher.match(uri) == 2){ SQLiteDatabase db = helper.getWritableDatabase(); db.delete("account", selection, selectionArgs); } return 0; } @Override public String getType(Uri uri) { return null; }}
场景:
写内容提供者的场景:让其他应用程序访问自己应用程序数据库中的数据;写内容提供者的解析器场景:访问别的应用程序中的内容提供者时;
06_插入短信(重点)
在自己的工程里访问手机上短信应用程序里面短信列表。1、需要访问短信应用提供的内容提供者;2、需要知道uri:content://sms/; 3、分析数据库表:sms;address,date,type,body;
代码:
package com.itheima.insertsms;import android.app.Activity;import android.content.ContentResolver;import android.content.ContentValues;import android.net.Uri;import android.os.Bundle;import android.view.View;import android.widget.Toast;public class MainActivity extends Activity {@Overrideprotected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main);}public void insert(View view){ //得到内容提供者的解析器 ContentResolver resolver = getContentResolver(); Uri uri = Uri.parse("content://sms/"); ContentValues values = new ContentValues(); values.put("address", "18910903535"); values.put("date",System.currentTimeMillis()); values.put("type", 1);//type为表示接收到短信 values.put("body", "上次从我这里借的500万还没还我呢"); resolver.insert(uri, values); Toast.makeText(this, "插入完成", 0).show();}}
07_内容提供者uri的写法
content://sms/;1、需要访问短信应用提供的内容提供者;2、需要知道uri:content://sms/; 3、分析数据库表:sms;address,date,type,body;
08_短信的备份(重点)
第一步:通过内容提供者查询短信列表:
1、需要访问短信应用提供的内容提供者;2、需要知道uri:content://sms/; 3、分析数据库表:sms;address,date,type,body;
第二步:把短信列表序列化到xml的文件上:
4、把备份的文件写到SD卡上;5、使用xml格式的文件存数短信;
代码:
package com.itheima.copysms;import java.io.File;import java.io.FileNotFoundException;import java.io.FileOutputStream;import java.io.IOException;import org.xmlpull.v1.XmlSerializer;import android.app.Activity;import android.content.ContentResolver;import android.database.Cursor;import android.net.Uri;import android.os.Bundle;import android.os.Environment;import android.util.Xml;import android.view.View;import android.widget.Toast;public class MainActivity extends Activity {@Overrideprotected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main);}public void backup(View view){ try { //1、访问短信应用的内容提供者 ContentResolver resolver = getContentResolver(); Uri uri = Uri.parse("content://sms/"); Cursor cursor = resolver.query(uri, new String[]{"address","date","type","body"}, null, null, "date desc"); //得到xml序列化器 XmlSerializer s = Xml.newSerializer(); FileOutputStream os = new FileOutputStream(new File(Environment.getExternalStorageDirectory()+"/backup.xml")); //初始化序列器 s.setOutput(os, "UTF-8"); s.startDocument("UTF-8", true); s.startTag(null, "info"); while(cursor.moveToNext()){ String address = cursor.getString(0); long date = cursor.getLong(1); int type = cursor.getInt(2); String body = cursor.getString(3); s.startTag(null, "sms"); s.startTag(null, "address"); s.text(address); s.endTag(null, "address"); s.startTag(null, "date"); s.text(date+""); s.endTag(null, "date"); s.startTag(null, "type"); s.text(type+""); s.endTag(null, "type"); s.startTag(null, "body"); s.text(body); s.endTag(null, "body"); s.endTag(null, "sms"); } s.endTag(null, "info"); s.endDocument(); cursor.close(); os.close(); Toast.makeText(this, "备份成功", 0).show(); } catch (Exception e) { e.printStackTrace(); }}}
09_短信的还原操作(重点)
把已经备份的xml短信数据插入到短信应用的数据库表中。1、解析xml的短信数据:2、通过短信应用程序的内容提供者把数据插入到数据库表中:
代码:
package com.itheima.restoresms;import java.io.File;import java.io.FileInputStream;import org.xmlpull.v1.XmlPullParser;import android.app.Activity;import android.app.AlertDialog;import android.app.AlertDialog.Builder;import android.content.ContentResolver;import android.content.ContentValues;import android.content.DialogInterface;import android.content.DialogInterface.OnClickListener;import android.net.Uri;import android.os.Bundle;import android.os.Environment;import android.util.Xml;import android.view.View;import android.widget.Toast;import com.itheima.restoresms.domain.SmsInfo;public class MainActivity extends Activity { private SmsInfo sms; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); } public void restore(View view) { // 创建一个对话框的构造器 AlertDialog.Builder builder = new Builder(this); builder.setTitle("提醒"); builder.setMessage("是否删除所有短信并重新还原?"); builder.setPositiveButton("是", new OnClickListener() { /** * 单击按钮时调用这个方法 */ @Override public void onClick(DialogInterface dialog, int which) { //删除短信 deleteSms(); //还原短信 insertSms(); } }); builder.setNegativeButton("否", new OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { } }); // 使用构造器创建出一个对话框对象 AlertDialog ad = builder.create(); ad.show(); } public void insertSms() { try { ContentResolver resolver = getContentResolver(); Uri uri = Uri.parse("content://sms/"); resolver.delete(uri, null, null); // 解析xml文件 XmlPullParser parser = Xml.newPullParser(); FileInputStream fis = new FileInputStream(new File( Environment.getExternalStorageDirectory() + "/backup.xml")); parser.setInput(fis, "UTF-8"); // 得到解析的事件类型 int type = parser.getEventType(); while (type != XmlPullParser.END_DOCUMENT) { switch (type) { case XmlPullParser.START_TAG:// 开始标签的事件类型 if ("sms".equals(parser.getName())) { sms = new SmsInfo(); } else if ("address".equals(parser.getName())) { String address = parser.nextText(); sms.setAddress(address); } else if ("date".equals(parser.getName())) { String date = parser.nextText(); sms.setDate(date); } else if ("type".equals(parser.getName())) { String smsType = parser.nextText(); sms.setType(smsType); } else if ("body".equals(parser.getName())) { String body = parser.nextText(); sms.setBody(body); } break; case XmlPullParser.END_TAG:// 结束标签的事件类型 if ("sms".equals(parser.getName())) { // 把短信还原到数据库 // address,date,type,body; ContentValues values = new ContentValues(); values.put("address", sms.getAddress()); values.put("date", sms.getDate()); values.put("type", sms.getType()); values.put("body", sms.getBody()); resolver.insert(uri, values); sms = null; } break; } // 解析到下一个标签 parser.next(); type = parser.getEventType(); } fis.close(); } catch (Exception e) { e.printStackTrace(); } } public void deleteSms(){ ContentResolver resolver = getContentResolver(); Uri uri = Uri.parse("content://sms/"); resolver.delete(uri, null, null); }}
10_联系人数据库的表结构
联系人相关的表:1、raw_contacts:存储了联系人的contact_id;2、data:存储了联系人信息字段的值;3、mimetypes:存储了联系人信息字段的类型;读取联系的信息的逻辑:1、查询raw_contacts:得到contact_id;2、根据contact_id查询data表;content://com.android.contacts/raw_contactscontent://com.android.contacts/data代码:package com.itheima.readcontacts;import android.app.Activity;import android.content.ContentResolver;import android.database.Cursor;import android.net.Uri;import android.os.Bundle;import android.view.View;public class MainActivity extends Activity {@Overrideprotected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main);}public void readContacts(View view){ System.out.println("======="); ContentResolver resolver = getContentResolver(); Uri uri = Uri.parse("content://com.android.contacts/raw_contacts"); Cursor cursor = resolver.query(uri, new String[]{"contact_id"}, null, null, null); while(cursor.moveToNext()){ long contact_id = cursor.getLong(0); System.out.println("contact_id===="+contact_id); Uri dataUri = Uri.parse("content://com.android.contacts/data"); Cursor dataCursor = resolver.query(dataUri, new String[]{"mimetype","raw_contact_id","data1"}, "raw_contact_id=?", new String[]{contact_id+""}, null); while(dataCursor.moveToNext()){ String mimetype = dataCursor.getString(0); long raw_contact_id = dataCursor.getLong(1); String data1 = dataCursor.getString(2); System.out.println("mimetype===="+mimetype); System.out.println("data1===="+data1); } dataCursor.close(); System.out.println("========================================="); } cursor.close();}}
11_联系人的还原(重点)
联系人相关的表:1、raw_contacts:存储了联系人的contact_id :记录数加1;2、data:存储了联系人信息字段的值;3、mimetypes:存储了联系人信息字段的类型;content://com.android.contacts/raw_contactscontent://com.android.contacts/data
代码:
package com.itheima.readcontacts;import android.app.Activity;import android.content.ContentResolver;import android.content.ContentValues;import android.database.Cursor;import android.net.Uri;import android.os.Bundle;import android.view.View;public class MainActivity extends Activity {@Overrideprotected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main);}public void restoreContacts(View view) { ContentResolver resolver = getContentResolver(); Uri uri = Uri.parse("content://com.android.contacts/raw_contacts"); Cursor cursor = resolver.query(uri, null, null, null, null); int rownum = cursor.getCount(); cursor.close(); int contact_id = rownum + 1; // 在raw_contacts表中加入一点条数据 ContentValues values = new ContentValues(); values.put("contact_id", contact_id); resolver.insert(uri, values); Uri dataUri = Uri.parse("content://com.android.contacts/data"); // 姓名 ContentValues nameValues = new ContentValues(); nameValues.put("mimetype", "vnd.android.cursor.item/name"); nameValues.put("raw_contact_id", contact_id); nameValues.put("data1", "wangwu"); resolver.insert(dataUri, nameValues); // 手机号码 ContentValues phoneValues = new ContentValues(); phoneValues.put("mimetype", "vnd.android.cursor.item/phone_v2"); phoneValues.put("raw_contact_id", contact_id); phoneValues.put("data1", "18910903535"); resolver.insert(dataUri, phoneValues); // email ContentValues emailValues = new ContentValues(); emailValues.put("mimetype", "vnd.android.cursor.item/email_v2"); emailValues.put("raw_contact_id", contact_id); emailValues.put("data1", "wangwu@itcat.cn"); resolver.insert(dataUri, emailValues);}}
12_内容观察者
内容观察者(ContentObserver):可以监听到内容提供者中数据变化的情况;
13_短信窃听器(重点)
代码:
package com.itheima.smslistener;import android.app.Activity;import android.content.ContentResolver;import android.database.ContentObserver;import android.database.Cursor;import android.net.Uri;import android.os.Bundle;import android.os.Handler;public class MainActivity extends Activity {@Overrideprotected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); ContentResolver resolver = getContentResolver(); Uri uri = Uri.parse("content://sms/"); //注册一个内容观察者 resolver.registerContentObserver(uri, true, new MyObserver(new Handler()));}private class MyObserver extends ContentObserver{ public MyObserver(Handler handler) { super(handler); } /** * 内容提供者中数据发生变化时调用这个方法 */ @Override public void onChange(boolean selfChange) { super.onChange(selfChange); //查询短信应用 ContentResolver resolver = getContentResolver(); Uri uri = Uri.parse("content://sms/"); Cursor cursor = resolver.query(uri, new String[]{"address", "date" , "type", "body"}, null, null, "date desc"); cursor.moveToNext(); String address = cursor.getString(0); long date = cursor.getLong(1); long type = cursor.getLong(2); String body = cursor.getString(3); System.out.println("address==="+address); System.out.println("date==="+date); System.out.println("type==="+type); System.out.println("body==="+body); }}}
0 0
- android基础之五——内容提供者
- android基础--内容提供者
- Android基础--内容提供者
- Android App开发从零开始之基础—四大组件(四)—内容提供者ContentProvider
- Android开发基础——内容提供者(ContentProvider)小结
- Android——内容提供者
- Android——内容提供者
- Android——ContentProvide 内容提供者+四大组件之三
- Android——ContentProvide 内容提供者+四大组件之三
- android ContentProvider(内容提供者)基础
- Android基础:内容提供者简介
- 基础学习day09——内容提供者
- android之内容提供者解析
- android之内容提供者解析
- android之内容提供者解析
- Android之ContentProvide(内容提供者)
- Android开发之内容提供者
- Android开发之内容提供者
- jQuery中的DOM操作
- The mook jong (HDU 5366)
- android基础之四——广播与服务(二)
- WebSocket 实战
- URL之好资源整理(看云平台)
- android基础之五——内容提供者
- Android利用Fragment实现Tab布局
- iscsi 挂载网络存储及存储访问
- Android Studio中导入Vitamio框架
- android基础之六——多媒体编程
- Android 5.0/5.1 HOOK技术探究
- 深入理解JVM
- hdoj 2080 夹角有多大II
- am335x嵌入式开发-bootloader启动流程