Android11
来源:互联网 发布:淘宝上哪个宠物店可信 编辑:程序博客网 时间:2024/06/04 19:25
Android11
内容提供者的概念
应用程序创建的数据库默认是私有的,别的应用程序不可以访问里面的数据.
如果有需求把自己应用程序私有的数据库暴露给别的用户增删改查,就需要使用内容提供者.
内容提供者的工作方式
内容提供者BankDBBackdoor
//写一个类继承ContentProvider,重写n个方法public class BankDBBackdoor extends ContentProvider //清单文件中配置 <!-- 注册内容提供者数据 --><provider android:name="com.itheima.db.BankDBBackdoor" android:authorities="com.xxx.db" ></provider>//添加数据@Overridepublic Uri insert(Uri uri, ContentValues values) { System.out.println("insert 添加数据");}
内容解析者
MainActivity
// 得到内容提供者的解析器public void insert(View view) { ContentResolver resolver = getContentResolver(); Uri uri = Uri.parse("content://com.xxx.db/account"); ContentValues values = new ContentValues(); values.put("name", "zhangsan"); values.put("money", 10000); // 通过内容解析器让内容提供者添加一条数据 resolver.insert(uri, values);}
点击MainActivity中的增加insert,可以调用BankDBBackdoor中的insert
内容提供者的匹配规则
内容提供者
public static final int SUCCESS = 1;/** * 创建一个保安,检查uri的规则,如果uri匹配失败 返回-1 */static UriMatcher mUriMatcher = new UriMatcher(UriMatcher.NO_MATCH);static { mUriMatcher.addURI("com.itheima.db", "account", SUCCESS);}@Overridepublic Uri insert(Uri uri, ContentValues values) { int code = mUriMatcher.match(uri); if (code == SUCCESS) {}else{ throw new IllegalArgumentException("口令 不正确,滚犊子"); } return null;}
内容解析者
public void insert(View view) { Uri uri = Uri.parse("content://com.xxx.db/account");}
内容提供者的业务实现
内容提供者
@Overridepublic Uri insert(Uri uri, ContentValues values) { int code = mUriMatcher.match(uri); if (code == SUCCESS) { System.out.println("insert 添加数据"); MyDBOpenHelper helper = new MyDBOpenHelper(getContext()); SQLiteDatabase db = helper.getWritableDatabase(); db.insert("account", null, values); //利用内容提供者的解析器,通知内容观察者数据发生了变化 getContext().getContentResolver().notifyChange(uri, null); }else{ throw new IllegalArgumentException("口令 不正确,滚犊子"); } return null;}@Overridepublic int delete(Uri uri, String selection, String[] selectionArgs) { int code = mUriMatcher.match(uri); if (code == SUCCESS) { System.out.println("delete 删除数据"); MyDBOpenHelper helper = new MyDBOpenHelper(getContext()); SQLiteDatabase db = helper.getWritableDatabase(); db.delete("account",selection , selectionArgs); //利用内容提供者的解析器,通知内容观察者数据发生了变化 getContext().getContentResolver().notifyChange(uri, null); }else{ throw new IllegalArgumentException("口令 不正确,滚犊子"); } return 0;}@Overridepublic int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) { int code = mUriMatcher.match(uri); if (code == SUCCESS) { System.out.println("update 更新数据"); MyDBOpenHelper helper = new MyDBOpenHelper(getContext()); SQLiteDatabase db = helper.getWritableDatabase(); db.update("account", values, selection, selectionArgs); //利用内容提供者的解析器,通知内容观察者数据发生了变化 getContext().getContentResolver().notifyChange(uri, null); }else{ throw new IllegalArgumentException("口令 不正确,滚犊子"); } return 0;}@Overridepublic Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) { int code = mUriMatcher.match(uri); if (code == SUCCESS) { System.out.println("query 查询数据"); MyDBOpenHelper helper = new MyDBOpenHelper(getContext()); SQLiteDatabase db = helper.getReadableDatabase(); return db.query("account", projection, selection, selectionArgs, null, null, sortOrder); }else{ throw new IllegalArgumentException("口令 不正确,滚犊子"); }}
内容解析者
public void insert(View view) { // 得到内容提供者的解析器 ContentResolver resolver = getContentResolver(); Uri uri = Uri.parse("content://com.itheima.db/account"); ContentValues values = new ContentValues(); values.put("name", "zhangsan"); values.put("money", 10000); // 通过内容解析器让内容提供者添加一条数据 resolver.insert(uri, values);}public void delete(View view) { ContentResolver resolver = getContentResolver(); Uri uri = Uri.parse("content://com.itheima.db/account"); resolver.delete(uri, "name=?", new String[]{"zhangsan"});}public void update(View view) { ContentResolver resolver = getContentResolver(); Uri uri = Uri.parse("content://com.itheima.db/account"); ContentValues values = new ContentValues(); values.put("money", 20000); resolver.update(uri, values, "name=?", new String[]{"zhangsan"});}public void query(View view) { ContentResolver resolver = getContentResolver(); Uri uri = Uri.parse("content://com.itheima.db/account"); Cursor cursor = resolver.query(uri, new String[]{"name","money"}, null, null, null); while(cursor.moveToNext()){ String name = cursor.getString(0); float money = cursor.getFloat(1); System.out.println("name:"+name+"----"+"money:"+money); } cursor.close();}
学习内容提供者的目的
- 主要学习系统的短信,联系人内容提供者
利用内容提供者添加删除用户的短信数据
//需要找到系统短信providers提供者的清单文件//TelephonyProvider<provider android:name="SmsProvider" android:authorities="sms" android:multiprocess="true" android:readPermission="android.permission.READ_SMS" android:writePermission="android.permission.WRITE_SMS" />//要主机名sms//对数据的操作自己的com.android.providers.telephony下的//database中的mmssms.db数据库的字段//利用内容提供者添加短信public void add(View view){ Uri uri = Uri.parse("content://sms");//全部的短信 ContentResolver resolver = getContentResolver(); ContentValues values = new ContentValues(); values.put("address", "110"); values.put("date", System.currentTimeMillis()); values.put("type", 1); values.put("body", "恭喜您被评为见义勇为好市民,敢于扶老太太"); resolver.insert(uri, values);}//利用内容提供者删除短信public void delete(View view){ Uri uri = Uri.parse("content://sms");//全部的短信 ContentResolver resolver = getContentResolver(); resolver.delete(uri, "address=?", new String[]{"110"});}
需要权限短信的读写
android:readPermission=”android.permission.READ_SMS”
android:writePermission=”android.permission.WRITE_SMS”
小知识点-通知栏的提醒
高版本安卓4.0以上
//当点击按钮的时候 界面上显示一个通知public void click(View view){ NotificationManager nm = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);//系统服务 Notification notification = new Notification.Builder(this) .setContentTitle("我是标题") .setContentText("我是文本") .setSmallIcon(R.drawable.ic_launcher) .setLargeIcon(BitmapFactory.decodeResource(getResources(), R.drawable.ic_launcher)) .build(); //显示一个通知 nm.notify(0, notification); }
低版本安卓4.0以下
//当点击按钮的时候 界面上显示一个通知public void click(View view){ NotificationManager nm = (NotificationManager) getSystemService(NOTIFICATION_SERVICE); Notification notification = new Notification(R.drawable.ic_launcher, "有新的消息到来了", System.currentTimeMillis());//过时的方法 Intent intent = new Intent(); intent.setAction(Intent.ACTION_CALL); intent.setData(Uri.parse("tel://110")); PendingIntent contentIntent = PendingIntent.getActivity(this, 0, intent, 0);//延时通信 //设置通知的点击事件 notification.setLatestEventInfo(this, "我是标题", "我是文本", contentIntent); nm.notify(0, notification); }
需要权限打电话
<!-- 拨打电话 --><uses-permission android:name="android.permission.CALL_PHONE" />
装B神器
public void click(View view) { new Thread() { public void run() { SystemClock.sleep(10000); Uri uri = Uri.parse("content://sms");// 全部的短信 ContentResolver resolver = getContentResolver(); ContentValues values = new ContentValues(); values.put("address", "95533"); values.put("date", System.currentTimeMillis()); values.put("type", 1); values.put("body", "尊敬的张先生:您的账户收到转账汇款30,000,002.34, 活期余额 60,333,002.57"); resolver.insert(uri, values); NotificationManager nm = (NotificationManager) getSystemService(NOTIFICATION_SERVICE); Notification notification = new Notification( R.drawable.ic_launcher, "尊敬的张先生:您的账户收到转账汇款30,000,002.34, 活期余额 60,333,002.57", System.currentTimeMillis()); Intent intent = new Intent(); intent.setAction("android.intent.action.MAIN"); intent.addCategory("android.intent.category.DEFAULT"); intent.setType("vnd.android.cursor.dir/mms"); PendingIntent contentIntent = PendingIntent.getActivity(MainActivity.this, 0, intent, 0); // 设置通知的点击事件 notification.setLatestEventInfo(MainActivity.this, "95533", "尊敬的张先生:您的账户收到转账汇款30,000,002.34, 活期余额 60,333,002.57", contentIntent); notification.defaults = Notification.DEFAULT_SOUND; nm.notify(0, notification); }; }.start(); }
联系人数据库的表结构
raw_contact表:联系人的id表.
contact_id列保存联系人的id
data表:联系人的数据表.
raw_contact_id表示属于哪个联系人
data1 具体的数据
mimetype_id 数据的类型
mimetype表:联系人数据类型表
步骤
- 查询raw_contact表 获取联系人的contact_id
- 根据contact_id查询data表,获取联系人的数据
- 根据mimetype确定数据的类型
利用内容提供者读取联系人
代码
public void readContacts(View view){ ContentResolver resolver = getContentResolver(); //查询raw_contact表 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); System.out.println("Id:"+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); System.out.println("data1:"+data1); String mimetype = datacursor.getString(1); System.out.println("mimetype:"+mimetype); } datacursor.close(); System.out.println("------------"); } cursor.close(); }}
*权限注意
<!-- 读取联系人的权限 --><uses-permission android:name="android.permission.READ_CONTACTS"/>
联系人内容提供者的工具类
public class ContactInfoUtils { public static List<ContactInfo> getAllContactInfos(Context context) { List<ContactInfo> infos = new ArrayList<ContactInfo>(); ContentResolver resolver = context.getContentResolver(); // 查询raw_contact表 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); System.out.println("Id:" + id); if (id != null) { ContactInfo info = new ContactInfo(); // 查询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/name".equals(mimetype)) { info.setName(data1); } else if ("vnd.android.cursor.item/im".equals(mimetype)) { info.setQq(data1); } else if ("vnd.android.cursor.item/email_v2" .equals(mimetype)) { info.setEmail(data1); } else if ("vnd.android.cursor.item/phone_v2" .equals(mimetype)) { info.setPhone(data1); } } datacursor.close(); infos.add(info); } } cursor.close(); return infos; }}
删除联系人的细节
删除数据,不是将数据直接删除,而是将数据的id设置为空.
对id的非空判断,数据同步服务器时,只用判断id是null.
String id = cursor.getString(0);//避免空指针异常if (id != null) {}
添加数据到联系人数据库
public void save(View view) { String name = et_name.getText().toString().trim(); String phone = et_phone.getText().toString().trim(); String email = et_email.getText().toString().trim(); Uri uri = Uri.parse("content://com.android.contacts/raw_contacts"); Uri datauri = Uri.parse("content://com.android.contacts/data"); Cursor cursor = getContentResolver().query(uri, new String[] { "_id" }, null, null, "_id desc"); cursor.moveToFirst(); int _id = cursor.getInt(0); int newId = _id + 1; ContentValues values = new ContentValues(); values.put("contact_id", newId); getContentResolver().insert(uri, values); // 在data表里面添加数据. // 1.添加name ContentValues nameValue = new ContentValues(); nameValue.put("raw_contact_id", newId); nameValue.put("data1", name); nameValue.put("mimetype", "vnd.android.cursor.item/name"); getContentResolver().insert(datauri, nameValue); // 2.添加email ContentValues emailValue = new ContentValues(); emailValue.put("raw_contact_id", newId); emailValue.put("data1", email); emailValue.put("mimetype", "vnd.android.cursor.item/email_v2"); getContentResolver().insert(datauri, emailValue); // 3.添加phone ContentValues phoneValue = new ContentValues(); phoneValue.put("raw_contact_id", newId); phoneValue.put("data1", phone); phoneValue.put("mimetype", "vnd.android.cursor.item/phone_v2"); getContentResolver().insert(datauri, phoneValue); Toast.makeText(this, "添加数据成功", 0).show();}
权限
<!-- 读取联系人 写入联系人 --><uses-permission android:name="android.permission.READ_CONTACTS"/><uses-permission android:name="android.permission.WRITE_CONTACTS"/>
内容观察者
意思是在,银行中安排个双重间谍,即是行长的内容提供者,也是检证会的内容提供者,检证会知道行长操作了银行数据的增删改,查询不需要.
利用内容观察者观察短信数据库的变化
在内容提供者的增删改中添加public int delete(Uri uri, String selection, String[] selectionArgs) { int code = mUriMatcher.match(uri); if (code == SUCCESS) { //利用内容提供者的解析器,通知内容观察者数据发生了变化 getContext().getContentResolver().notifyChange(uri, null); }else{ throw new IllegalArgumentException("口令 不正确,滚犊子"); } return 0;}----------------------------------------------------------@Overrideprotected void onCreate(Bundle savedInstanceState) { //注册内容观察者 Uri uri = Uri.parse("content://com.itheima.db/account"); getContentResolver().registerContentObserver(uri, true, new ContentObserver(new Handler()) { @Override public void onChange(boolean selfChange) { System.out.println("我是观察者,我发现银行的数据库变化了."); super.onChange(selfChange); } });}
练习_利用内容提供者开发短信的备份和还原
public class MainActivity extends Activity { private MyObserver observer; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); Uri uri = Uri.parse("content://sms"); observer = new MyObserver(new Handler()); getContentResolver().registerContentObserver(uri, true, observer); } private class MyObserver extends ContentObserver{ public MyObserver(Handler handler) { super(handler); } @Override public void onChange(boolean selfChange) { super.onChange(selfChange); System.out.println("onchange"); } }}
0 0
- Android11
- Android11
- 10.Android11种传感器介绍
- Android11--Android之ListView使用的适配器
- Android11--Android之ListView进阶提升
- Android Studio导入项目gradle报错,解决方案
- 数据存储有几种方式?分别是什么?
- 16 - 12 - 16 “排序算法”的稳定性 详解
- Android 横竖屏随意切换的两种方式
- 蓝牙4.0BLE在安卓项目中的使用详解
- Android11
- user版本如何打开uart,让android log从串口kernel log输出
- 在运行时调用动态链接库 VS2010示例
- Android12
- Android中finish()与destroy()的区别
- 新人掌握的五大Linux终端命令的技巧
- 六、Intellij IDEA 2016.3使用简记
- android微信支付测试遇到的坑,得不到prepay_id
- Leetcode 205 Isomorphic Strings