Android的内容观察者、通知、内容提供者

一、内容提供者的作用
1. 应用成需创建的数据库文件,默认都是私有的,其他应用程序不具备读写权限
2. 如果真的想把自己的数据库数据暴露给其他程序访问,那么就应该通过内容提供者来暴露。
3. 与aidl有点类似,但不太一样,aidl是提供内存中的数据给其他应用访问,内容提供者是提供磁盘中的数据给其他应用访问。

二、使用内容提供者的步骤
1. 自定义一个类,继承ContentProvider
public class Backdoor extends ContentProvider {}
2. 注册,要添加主机名
<!--      authorities 它就相当于是一个口令,外部应用如果想操作这个内容提供者,
    为他干活,必须要与内容提供者的口令一致才可以。 -->
    <provider android:name="com.itheima.db.Backdoor"
        android:authorities="com.itheima.db.BANK"></provider>
3. 定义一个Uri匹配器
/**
	 * 由于应用程序一安装,就会把程序中的内容提供者口令发布出来,为了提高数据的安全性, 所以必须对来访的uri(口令),做一些匹配规则过滤一下。
	 */
	// 定义一个uri的匹配器,指定里面如果传递过来的uri,一旦没有匹配,将返回的int值 -1
	static UriMatcher matcher = new UriMatcher(UriMatcher.NO_MATCH);
4. 预设一些匹配规则
	static {
		// 一开始就给这个匹配器预设一些匹配规则,如果传递过来的uri
		// 匹配了authority 和 path ,那么将返回后面的匹配码
		//数据库里面有可能有多张表,为了规范匹配规则,path一般都写表名,根据表的名字来判定
		//当前访问的是哪个表的数据 ,如果有多张表,并且还想把这些所有表都暴露出来,那么这个匹配规则
		//就应该写多条语句了。并且注意返回的code不能一样。
		matcher.addURI("com.itheima.db.BANK", "account", 200);
	//	matcher.addURI("com.itheima.db.BANK", "stu", 201);
		}
5. 编写CRUD方法
	@Override
	public int delete(Uri uri, String selection, String[] selectionArgs) {
		// 使用uri匹配去去过滤传递过来的uri口令,如果匹配成功,将返回200,否则将返回 -1
		int code = matcher.match(uri);
		if (code == 200) {
			System.out.println("delete---");
			Db db = new Db(getContext()); 
			SQLiteDatabase data = db.getWritableDatabase();
			data.delete("account", selection, selectionArgs);
		} else {
			throw new IllegalArgumentException("口令错误,滚犊子~~");
		}
		return 0;
	}
6. 在其他应用操作内容提供者
	public void insert(View v) {
		// 其他应用通过内容提供者 content provider 暴露数据
		// 本应用想操作内容提供者---内容解析者


		// 1.通过上下文得到内容解析者
		ContentResolver resolver = getContentResolver();


		// 2. 要访问内容提供者,必须要指定口令
		// 由于内容提供者省级了口令,既有主机名也有path路径,所以这里为了能够匹配成功
		// 必须加上主机名还有path路径名
		Uri uri = Uri.parse("content://com.itheima.db.BANK/account");


		//定义要插入的数据
		ContentValues values = new ContentValues();
		values.put("name", "zhangsan");
		values.put("money", 5000);


		// 3.调用内容提供者中的添加方法
		resolver.insert(uri, values);


	}

三、学习内容提供者的目的
1. 一般在开发当中都不会把自己的数据暴露出来,也就是编写自定义的内容提供者的几率非常之小。
2. 去访问系统应用暴露出来的数据,如:备份来联系人和备份短信

四、添加和删除短信
* 添加短信
	//添加短信
	public void insert(View v) {
		ContentResolver resolver = getContentResolver();
		//定义口令,这个口令,通过查看上层应用中的provider中的TelephonyProvider 这个应用中清单文件和源代码
		Uri uri = Uri.parse("content://sms");
		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 v) {
		ContentResolver resolver = getContentResolver();
		//定义口令,这个口令,通过查看上层应用中的provider中的TelephonyProvider 这个应用中
		//清单文件和源代码
		Uri uri = Uri.parse("content://sms");
		resolver.delete(uri, "address=?", new String[]{"110"});
		Toast.makeText(this, "删除短息成功", 0).show();
	}
五、界面提醒
1. Toast
2. Dialog-对话框
3. notification -- 通知

> 通知是运行在另外一个进程中 , systemui
//发送通知
public void send(View v){
	/*
	 * 高版本
	 * //1.得到通知管理者
	NotificationManager manager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
	
	//2.定义一个notification的构建器,通过这个构建器去定义通知的一些属性
	 Notification noti = new Notification.Builder(this)
     .setContentTitle("这是标题")
     .setContentText("这是文本内容")
     .setSmallIcon(R.drawable.ic_launcher)
     .setLargeIcon(BitmapFactory.decodeResource(getResources(), R.drawable.ic_launcher))
     .build();
	
	//2.发送一个通知 , 指定通知的id,还有通知的对象
	manager.notify(1, noti);
	*
	*
	*/


	//低版本
	NotificationManager manager = (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://10086"));
	
	
	//指定点击通知之后,跳转一个界面
	PendingIntent pIntent = PendingIntent.getActivity(
			this, 
			1, //请求码
			intent, //跳转的意图
			0);//可选的标记
	
	//设置拖动通知下来之后,展示的内容以及点击之后跳转到的界面
	notification.setLatestEventInfo(
			this, 
			"这是标题", 
			"这是文本", 
			pIntent);
	manager.notify(2, notification);	
}


六、联系人的内容提供者
6.1 查询联系人
> 1. 查询raw_contacts表,得到contact_id
> 2. 根据contact_id,去查询 data1, mimetype类型

6.2 删除联系人
> 删除联系人后,发现并不是真的从数据库中把这条记录给移除,而是把contact_id置为null而已,
Android之所以这么做,是为了日后联网同步所考虑的。

6.3 添加联系人
> 先查询raw_contacts表,获取到当前的最新_id
//添加一条联系人记录
	ContentResolver resolver = getContentResolver();
	//2定义查询raw_contact表的uri
	Uri contactUri = Uri.parse("content://com.android.contacts/raw_contacts");
	//查询data表的uri
	Uri dataUri = Uri.parse("content://com.android.contacts/data");****


	//由于不知道当前的contact_id已经走到了多少,所以不能盲目直接编写,应该去查询
	//该表中的_id列,然后倒序排列,取第一条就可以了。 
	Cursor cursor = resolver.query(contactUri, new String[]{"_id"}, null, null, "_id desc");
	cursor.moveToFirst();
	int id = cursor.getInt(0)+1; //在原来的id基础上+1 ,形成了现在新添加的id
> 在它基础上+1 ,得到现在要往数据库添加的新raw_contact_id
	ContentValues values = new ContentValues();
	values.put("contact_id", id);
	resolver.insert(contactUri, values);
>  最后往data表里面添加 姓名、电话、邮箱...
	//往data表里面添加数据
	//添加姓名
	ContentValues nameVal = new ContentValues();
	nameVal.put("data1", et_name.getText().toString()); //添加姓名
	nameVal.put("raw_contact_id", id); //添加这个数据属于谁的uri
	nameVal.put("mimetype", "vnd.android.cursor.item/name"); //指定添加的数据属于什么类型
	resolver.insert(dataUri, nameVal);//插入记录
七、内容观察者
> 内容观察者实际上就是当数据的数据发生了改变之后,发布出来一个通知,如果有哪一个内容观察者
> 在观察这个uri对应的路径,那么就会收到这个通知
* 发布通知
	// 对外发布一个通知,告诉其他人,这个uri对应的数据已经发生了改变。如果第二个参数不是null,
	//那么在此指定的这个内容观察者将会收到这个通知,如果是null,代表的是不会直接报告给某一个内容观察者,
	//仅仅是发出来一个通知,如果有关心这个通知,那么久能知道事件的发生
	getContext().getContentResolver().notifyChange(uri, null);
注意:发布通知这个事件不一定在内容观察者里面执行,也可以在数据库操作完成之后执行。
* 注册一个内容观察者
	Uri uri = Uri.parse("content://com.itheima.db.BANK/account");
	
	//注册一个内容观察者,让他观察指定的uri, 如果这个uri的数据发生了改变,那么将会得到通知
	getContentResolver().registerContentObserver(
			uri, //观察指定的uri
			true,  // 如果是true, 代表只要前面的uri能够匹配成功,那么就会收到通知,如果是false代表的时候
					//要所有的路径都完全匹配
			new ContentObserver(new Handler()) {
		//一旦这个uri对应的数据发生了改变,那么这个方法将会被调用.
		@Override
		public void onChange(boolean selfChange) {
			System.out.println("来人啊,银行行长又来偷钱了。。。");
		}
	});
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值