04Android学习从零单排之ContentProvider
2016-05-05 00:38
429 查看
04Android学习从零单排之ContentProvider
读了那么多年的书让我明白一个道理。人要稳重,不要想到啥就做啥。做一行越久即使你不会,几年之后慢慢的你也会了,加上一点努力你或许你能成为别人眼中的专家。ContentProvider简介
ContentProvider 在android中的作用是对外共享数据,也就是说你可以通过ContentProvider把应用中的数据共享给其他应用访问,其他应用可以通过ContentProvider 对你应用中的数据进行添删改查。ContentProvider实际应用场景
ContentProvider实际应用场景,主要是通过getContentResolver来获取安卓系统中已经通过ContentProvider共享好的数据。例如,读取短信数据、获取联系人信息,它们都是通过ContentProvider把数据库对外提供好的,一般我们很少会ContentProvider把自己的应用程序数据暴露出去。ContentProvider共享数据的使用步骤
1、定义一个类继承ContentProvider,并在清单文件中配置provider和android:authorities节点。2、定义路径匹配规则
3、添加路径匹配规则,以供其他应用程序访问。
4、判断匹配规则,和定义的匹配规则是否相同。相同数据即可不其他应用操作。
public class AccountProvider extends ContentProvider { private static final int QUERYSUCESS = 1; //ctrl+shift+x 变成大些 ctrl+shift小写加Y private static final int ADDSUCESS = 2; private static final int DELSUCESS = 3; private static final int UPDATESUCESS = 4; //(1) 定义路径匹配规则 static UriMatcher matcher = new UriMatcher(UriMatcher.NO_MATCH); private MyOpenHelper helper; //(2) 添加路径匹配规则 static{ /** * authority 主机名 自己定义 * path 路径 * */ matcher.addURI("com.itheima.account.provider", "query", QUERYSUCESS); //添加 query方法的匹配规则 matcher.addURI("com.itheima.account.provider", "add", ADDSUCESS); //添加 add方法的匹配规则 matcher.addURI("com.itheima.account.provider", "delete", DELSUCESS); //添加 add方法的匹配规则 matcher.addURI("com.itheima.account.provider", "update", UPDATESUCESS); //添加 add方法的匹配规则 } @Override public boolean onCreate() { helper = new MyOpenHelper(getContext()); return false; } @Override public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) { //(3)获取匹配code int code = matcher.match(uri); if (code == QUERYSUCESS) { //说明匹配成功 SQLiteDatabase db = helper.getReadableDatabase(); Cursor cursor = db.query("info", projection, selection, selectionArgs, null, null, sortOrder); return cursor; }else { throw new IllegalArgumentException("路径不匹配 请检查"); } } @Override public String getType(Uri uri) { // TODO Auto-generated method stub return null; } @Override public Uri insert(Uri uri, ContentValues values) { int code = matcher.match(uri); if (code == ADDSUCESS ) { //匹配成功 SQLiteDatabase db = helper.getReadableDatabase(); //代表插入到了多少行 long insert = db.insert("info", null, values); return Uri.parse("com.itheima.account.provider"+insert); }else { throw new IllegalArgumentException("路径不匹配 请检查"); } } @Override public int delete(Uri uri, String selection, String[] selectionArgs) { int code = matcher.match(uri); if (code == DELSUCESS) { SQLiteDatabase db = helper.getReadableDatabase(); int delete = db.delete("info", selection, selectionArgs); //删除了多少行 return delete; }else { throw new IllegalArgumentException("路径不匹配 请检查"); } } @Override public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) { int code = matcher.match(uri); if (code == UPDATESUCESS) { SQLiteDatabase db = helper.getReadableDatabase(); int update = db.update("info", values, selection, selectionArgs); //删除了多少行 return update; }else { throw new IllegalArgumentException("路径不匹配 请检查"); } } }
清单文件中配置provider
<provider android:name="com.itheima.transation.AccountProvider" android:authorities="com.itheima.account.provider" ></provider>
以上内容在实际开发中一般不常见。下面通过案例的方式,学习并使用ContentProvider共享数据的共享的数据。
ContentProvider之短信备份案例
1、通过内容解析者getContentResolver()查询短信数据库。2、把查询出来的结果通过xml文件保存起来。
public void backsms(View view){ //写入到xml文件中 XmlSerializer serializer = Xml.newSerializer(); File file = new File(Environment.getExternalStorageDirectory().getPath()+"/Download", "smsback.xml"); try { FileOutputStream fos = new FileOutputStream(file); serializer.setOutput(fos,"utf-8"); //文档开始 serializer.startDocument("utf-8",true); //开始节点 serializer.startTag(null,"smss"); //循环写 xml sms body address date //1、利用内容解析者 获取我们关心列 //content://sms 是短信的匹配规则 Uri uri = Uri.parse("content://sms"); Cursor cursor = getContentResolver().query(uri, new String[]{"address", "date", "body"}, null, null, null); if (cursor != null&&cursor.getCount()>0) { while(cursor.moveToNext()){ String address = cursor.getString(0); String date = cursor.getString(1); String body = cursor.getString(2); String datef = formatDate(date); //开始写 xml 的 sms节点 serializer.startTag(null,"sms"); serializer.startTag(null,"address"); //如果不做这个判断,读取到是草稿短信,就会报空指针异常。 if (TextUtils.isEmpty(address)){ serializer.text("草稿箱"); }else{ serializer.text(address); } serializer.endTag(null,"address"); serializer.startTag(null,"date"); serializer.text(datef); serializer.endTag(null,"date"); serializer.startTag(null,"body"); serializer.text(body); serializer.endTag(null,"body"); serializer.endTag(null,"sms"); } } serializer.endTag(null,"smss"); serializer.endDocument(); //关闭数据库查询 cursor.close(); fos.close();//释放资源 Toast.makeText(getApplicationContext(),"短信备份完成。",Toast.LENGTH_SHORT).show(); } catch (Exception e) { Toast.makeText(getApplicationContext(),"短信备份失败。",Toast.LENGTH_SHORT).show(); e.printStackTrace(); } //不要忘记添加短信权限 } /** * 时间格式转换 * @param date * @return */ private String formatDate(String date){ long l = System.currentTimeMillis(); SimpleDateFormat format = new SimpleDateFormat("yyyy年MM月dd日 HH:mm:ss"); String format1 = format.format(new Date(new Long(date))); return format1; }
ContentProvider之短信插入案例
public void insertSms(View view){ //通过内容解析者,插入数据到短信数据库中 ContentResolver resolver = getContentResolver(); Uri uri = Uri.parse("content://sms"); String phoneNumber = mTvPhone.getText().toString().trim(); String context = mTvPhone.getText().toString().trim(); long l = System.currentTimeMillis(); ContentValues values = new ContentValues(); values.put("address",context); values.put("date",l); values.put("body",phoneNumber); //从这里插入你添加的短信数据 resolver.insert(uri,values); } //不要忘记添加短信权限
ContentProvider之读取联系人案例
由于读取联系人是实际开发中比较常用的功能,因此在这里我把读取联系人抽取成了工具类,方便以后再开发中,直接哪来用。这个读取联系人的工具类,只是最简单的实现功能,代码还有很多需要完善的地方,在此不做修改了,等用到的时候在优化。
public class ReadContactUtils { public List<ContactsBean> readContacts(Context context){ //自定义一个javabean,用于存储短信格式,javabean在此就不贴出来了,根据实际需求自己定义。 List<ContactsBean> contactsBeanList = new ArrayList<>(); //(1)去raw_contacts表查询 contact_id列,contact_id记录了联系人的数目 Uri contactsUri = Uri.parse("content://com.android.contacts/raw_contacts"); Uri dataUri = Uri.parse("content://com.android.contacts/data"); Cursor contactsCursor = context.getContentResolver().query(contactsUri, new String[]{"contact_id"}, null, null, null); if (contactsCursor!= null&&contactsCursor.getCount()>0) { while(contactsCursor.moveToNext()){ String contactsID = contactsCursor.getString(0); //判断contactsID不为null说明联系人存在 if (contactsID != null) { ContactsBean contactsBean = new ContactsBean(); contactsBean.setId(contactsID); //(2)根据 contact_id 去查 data表 查询data1列 和 mimetype_id 列 Cursor dataCursor = context.getContentResolver().query(dataUri, new String[]{"data1","mimetype"}, "raw_contact_id=?", new String[]{contactsID}, null); if (dataCursor != null&&dataCursor.getCount()>0) { while (dataCursor.moveToNext()){ if (dataCursor!=null){ String data1 = dataCursor.getString(0);//获取data1列的数据,就是联系人的详情数据 String mimetype = dataCursor.getString(1);//获取mimetype列数据 //(3)拿mimetype 数据做一下对比,然后取出联系人号码或者其他信息 if("vnd.android.cursor.item/name".equals(mimetype)){ System.out.println("姓名data1:"+data1); contactsBean.setName(data1); }else if("vnd.android.cursor.item/phone_v2".equals(mimetype)){ System.out.println("电话号码data1:"+data1); contactsBean.setPhone(data1); } } } } contactsBeanList.add(contactsBean); } } // System.out.println("一共有"+contactsID+"个联系人"); } return contactsBeanList; }
ContentProvider之插入联系人案例
public void addContact(View view){ String name = mTvName.getText().toString().trim(); String number = mTvNumber.getText().toString().trim(); //添加联系人之前先查询联系的contact_id Uri contactsUri = Uri.parse("content://com.android.contacts/raw_contacts"); Uri dataUri = Uri.parse("content://com.android.contacts/data"); Cursor cursor = getContentResolver().query(contactsUri, null, null, null, null); int contact_id = cursor.getCount(); // System.out.println("contact_id"+contact_id); //2现在开始插入联系人id ContentValues Values = new ContentValues(); //3为什么加1,是在原来的基础上+1 int newContact_id = contact_id+1; Values.put("contact_id",newContact_id); getContentResolver().insert(contactsUri,Values); //4开始插入联系人姓名 ContentValues nameValues = new ContentValues(); nameValues.put("raw_contact_id",newContact_id); nameValues.put("mimetype","vnd.android.cursor.item/name"); nameValues.put("data1",name); getContentResolver().insert(dataUri,nameValues); //5插入联系人手机号码 ContentValues numberValues = new ContentValues(); numberValues.put("raw_contact_id", newContact_id); numberValues.put("mimetype", "vnd.android.cursor.item/phone_v2"); numberValues.put("data1",number); getContentResolver().insert(dataUri,numberValues); Toast.makeText(getApplicationContext(),"联系人插入成功",Toast.LENGTH_SHORT).show(); }
关于作者
- Email:xiaweifeng@live.cn
- 项目地址:https://github.com/swordman20/Hsia04ContentProviderDemo.git
相关文章推荐
- 使用C++实现JNI接口需要注意的事项
- Android IPC进程间通讯机制
- Android Manifest 用法
- [转载]Activity中ConfigChanges属性的用法
- Android之获取手机上的图片和视频缩略图thumbnails
- Android之使用Http协议实现文件上传功能
- Android学习笔记(二九):嵌入浏览器
- android string.xml文件中的整型和string型代替
- i-jetty环境搭配与编译
- android之定时器AlarmManager
- android wifi 无线调试
- Android Native 绘图方法
- Android java 与 javascript互访(相互调用)的方法例子
- android 代码实现控件之间的间距
- android FragmentPagerAdapter的“标准”配置
- Android"解决"onTouch和onClick的冲突问题
- android:installLocation简析
- android searchView的关闭事件
- SourceProvider.getJniDirectories