android ContextProvider
来源:互联网 发布:mac截图后存在哪了 编辑:程序博客网 时间:2024/06/08 20:05
1.content provider简介
在andorid 中要实现不同进程间的数据共享,除了可以使用sharedPreferences,File...这外,最重要的还有content provider.通过Content provider应用程序可以把自己私有的数据暴露给别的应用程序,让别的应用程序可以对自己私有的数据库实现增删改查。
2 如何使用
如果没有现存需要的content provider需要自己写一个类extends ContentProvider
例如: 现有一个Account 管理类,需要提供给其它app 以crud操作的方法 .
步骤:
1.写一个类继承ContentProvider
2. 清单文件中配置authorities 比如,android:authorities="com.example"
3. 训练内容提供者的匹配器 UriMatcher
4. 根据需求实现内容提供者的增删改查的方法
public class AccountProvider extends ContentProvider{private static final int ACCOUNT=1;private static final int SINGLE_ACCOUNT=2;private DbHelper helper;private String table="account";private static UriMatcher matcher=new UriMatcher(UriMatcher.NO_MATCH);static{matcher.addURI("com.example","account",ACCOUNT);matcher.addURI("com.example","account/#",SINGLE_ACCOUNT);}@Overridepublic boolean onCreate() {helper=new DbHelper(getContext());return true;}@Overridepublic Cursor query(Uri uri, String[] projection, String selection,String[] selectionArgs, String sortOrder) {int code=matcher.match(uri);if(code==ACCOUNT){SQLiteDatabase db = helper.getReadableDatabase();return db.query(table, projection, selection, selectionArgs, null, null,null);}else if(code==SINGLE_ACCOUNT){}return null;}@Overridepublic String getType(Uri uri) {// TODO Auto-generated method stubreturn null;}@Overridepublic Uri insert(Uri uri, ContentValues values) {int code=matcher.match(uri);if(code==ACCOUNT){SQLiteDatabase db = helper.getReadableDatabase();long id= db.insert(table, null, values);db.close();return Uri.parse("content://com.example/account/"+id);} return null;}@Overridepublic int delete(Uri uri, String selection, String[] selectionArgs) {int code = matcher.match(uri);if (code == ACCOUNT) {SQLiteDatabase db = helper.getWritableDatabase();int result = db.delete("account", selection, selectionArgs);db.close();//后面程序,通知这个uri的数据变化了getContext().getContentResolver().notifyChange(uri, null);return result;} else {throw new IllegalArgumentException("无权删除数据。");}}@Overridepublic int update(Uri uri, ContentValues values, String selection,String[] selectionArgs) {int code = matcher.match(uri);if (code == ACCOUNT) {SQLiteDatabase db = helper.getWritableDatabase();int result = db.update("account", values, selection, selectionArgs);db.close();//后面程序,通知这个uri的数据变化了getContext().getContentResolver().notifyChange(uri, null);return result;} else {throw new IllegalArgumentException("无权修改数据。");}}}
在AndroidManifest.xml中配置
<provider android:name="com.example.ap.AccountProvider" android:authorities="com.example"> </provider>这样就写好了一个ContentProvider.
另外一个app 里使用 getContentResolver 去解析,注意Uri 必须得合法
public class MainActivity extends Activity {@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);}//查询public void query(View view){//得到内容提供者的解析器ContentResolver resolver = getContentResolver();Uri uri = Uri.parse("content://com.example/account");Cursor cursor = resolver.query(uri, null, null, null, null);while(cursor.moveToNext()){String id = cursor.getString(0);String name = cursor.getString(1);String money = cursor.getString(2);System.out.println(id);System.out.println(name);System.out.println(money);}cursor.close();}/** * 添加一条记录 * @param view */public void add(View view){ContentResolver resolver = getContentResolver();Uri uri = Uri.parse("content://com.example/account");ContentValues values = new ContentValues();values.put("name", "王五");values.put("money", 1000000.23f);Uri result = resolver.insert(uri, values);Toast.makeText(this, result.toString(), 0).show();}//删除某个记录public void delete(View view){ContentResolver resolver = getContentResolver();Uri uri = Uri.parse("content://com.example/account");int result = resolver.delete(uri, "name=?", new String[]{"王五"});if(result>0){Toast.makeText(this, "删除成功", 0).show();}else{Toast.makeText(this, "删除失败", 0).show();}}//更新一下public void update(View view){ContentResolver resolver = getContentResolver();Uri uri = Uri.parse("content://com.example/account");ContentValues values = new ContentValues();values.put("money", 0.05f);int result = resolver.update(uri, values, "name=?", new String[]{"王五"});if(result>0){Toast.makeText(this, "修改成功", 0).show();}else{Toast.makeText(this, "修改失败", 0).show();}}}
如果有,需在应用的Context 中使用ContentResolver对象作为客户端与provider 进行通讯.ContentResolver resolver = getContentResolver();
Android自己包含了管理音频,视频,图像,个人通讯录,短信等数据的content providers;
例如现存需要备份短信:
就可以直接使用这个uri去获取Uri uri = Uri.parse("content://sms/");
注意需要声明<uses-permission android:name="android.permission.READ_SMS"/> 的权限
/** * 短信的备份 * * @param view */public void backup(View view) {try {// 利用内容提供者获取短信私有的数据ContentResolver resovler = getContentResolver();Uri uri = Uri.parse("content://sms/");Cursor cursor = resovler.query(uri, new String[] { "address","date", "type", "body" }, null, null, null);XmlSerializer serializer = Xml.newSerializer();File file = new File(Environment.getExternalStorageDirectory(),"backup.xml");FileOutputStream os = new FileOutputStream(file);serializer.setOutput(os, "utf-8");// 写xml文件的头serializer.startDocument("utf-8", true);serializer.startTag(null, "root");while (cursor.moveToNext()) {String address = cursor.getString(0);serializer.startTag(null, "sms");serializer.startTag(null, "address");serializer.text(address);serializer.endTag(null, "address");serializer.startTag(null, "date");String date = cursor.getString(1);serializer.text(date);serializer.endTag(null, "date");serializer.startTag(null, "type");String type = cursor.getString(2);serializer.text(type);serializer.endTag(null, "type");serializer.startTag(null, "body");String body = cursor.getString(3);serializer.text(body);serializer.endTag(null, "body");serializer.endTag(null, "sms");}cursor.close();serializer.endTag(null, "root");serializer.endDocument();os.close();Toast.makeText(this, "备份成功", 0).show();} catch (Exception e) {e.printStackTrace();Toast.makeText(this, "备份失败", 0).show();}}
读取系统的联系人列表:
需要的权限: <uses-permission android:name="android.permission.READ_CONTACTS"/>
public static List<ContactInfo> getAllContactInfos(Context context) {List<ContactInfo> infos = new ArrayList<ContactInfo>();ContentResolver resolver = context.getContentResolver();Uri uri = Uri.parse("content://com.android.contacts/raw_contacts");Uri datauri = Uri.parse("content://com.android.contacts/data");Cursor cursor = resolver.query(uri, new String[] { "contact_id" },null, null, null);while (cursor.moveToNext()) {String id = cursor.getString(0);ContactInfo info = new ContactInfo();info.setId(id);System.out.println("id:" + id);if (id != null) {// 根据id查询data表,把这个联系人的数据获取出来。Cursor dataCursor = resolver.query(datauri, new String[] {"data1", "mimetype" }, "raw_contact_id=?",new String[] { id }, null);while (dataCursor.moveToNext()) {String data1 = dataCursor.getString(0);String mimetype = dataCursor.getString(1);if ("vnd.android.cursor.item/email_v2".equals(mimetype)) {// emailinfo.setEmail(data1);} else if ("vnd.android.cursor.item/im".equals(mimetype)) {// qqinfo.setQq(data1);} else if ("vnd.android.cursor.item/name".equals(mimetype)) {// nameinfo.setName(data1);} else if ("vnd.android.cursor.item/phone_v2".equals(mimetype)) {// nameinfo.setPhone(data1);}}infos.add(info);dataCursor.close();}}cursor.close();return infos;}使用contentProvider 添加联系人:
ui的xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context=".MainActivity" android:orientation="vertical" > <EditText android:id="@+id/et_phone" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="123456789999" android:hint="电话号码" /> <EditText android:id="@+id/et_name" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="haha" android:hint="姓名" /> <EditText android:id="@+id/et_email" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="aa@aa.com" android:hint="邮箱" /> <Button android:id="@+id/bt_save" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="保存" android:onClick="save"/></LinearLayout>
<pre name="code" class="java" style="font-size: 14px; line-height: 26px;">MainActivity 里实现添加联系的功能,注意权限
public class MainActivity extends Activity {EditText et_phone;EditText et_name;EditText et_email; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); et_phone=(EditText) findViewById(R.id.et_phone); et_name=(EditText) findViewById(R.id.et_name); et_email=(EditText) findViewById(R.id.et_email); } public void save(View v){ String phone=et_phone.getText().toString(); String name=et_name.getText().toString(); String email=et_email.getText().toString(); ContentResolver resolver = this.getContentResolver(); Uri uri_raw_contacts=Uri.parse("content://com.android.contacts/raw_contacts"); Uri uri_data=Uri.parse("content://com.android.contacts/data"); Cursor cursor=resolver.query(uri_raw_contacts, new String[]{"_id"},null,null,"_id desc"); int id=1; if(cursor.moveToFirst()){ id=cursor.getInt(0)+1; } ContentValues val=new ContentValues(); val.put(Contactables.RAW_CONTACT_ID, id); val.put(Contactables.MIMETYPE,"vnd.android.cursor.item/phone_v2"); val.put("data1",phone);resolver.insert(uri_data,val); val=new ContentValues(); val.put(Contactables.RAW_CONTACT_ID, id); val.put(Contactables.MIMETYPE,"vnd.android.cursor.item/name"); val.put("data1",name);resolver.insert(uri_data,val);val=new ContentValues(); val.put(Contactables.RAW_CONTACT_ID, id); val.put(Contactables.MIMETYPE,"vnd.android.cursor.item/email_v2"); val.put("data1",email);resolver.insert(uri_data,val); Toast.makeText(this, "添加数据成功", 0).show(); } }
3.内容观察者
使用ContentObserver定向"监听" ContentProvider 内部事件:
例如,可以为短信的contentProvider 注册一个监听器来监听短信的变化
public class MainActivity extends Activity {@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);getContentResolver().registerContentObserver(Uri.parse("content://sms"), true, new MyObserver(new Handler()));}private class MyObserver extends ContentObserver{public MyObserver(Handler handler) {super(handler);}@Overridepublic void onChange(boolean selfChange) {super.onChange(selfChange);System.out.println("短信的数据库变化了。");//查询数据库。....}}}
//如果自定义的ContentProvider需要发送通知.
getContext().getContentResolver().notifyChange(uri, null);
- android ContextProvider
- android Contextprovider 对外共享数据
- Android实现异步机制的工具和ContextProvider的特点
- Android
- android
- Android
- android
- android
- Android
- Android
- android
- android
- android
- Android
- Android
- android!!!
- android
- android
- RFID理论基础知识要点
- 不用算术运算符实现两个数的加法操作
- 使用jquery-validationEngine框架,4步实现前端JS校验
- HDU 1285 确定比赛名次(拓扑排序)
- 第十一章 Linux包过滤防火墙-netfilter--基于Linux3.10
- android ContextProvider
- Android requires compiler compliance level 5.0 or 6.0. Found '1.7' instead. Please use Android Tools
- php——ajax技术
- 【Java并发编程】之二:线程中断(含代码)
- CentOS网络唤醒设置说明
- 背景差法(background subtraction)计算前景图
- php大型门户网站核心技术
- UnicodeToAscii &# c#转中文
- 远程唤醒电脑