关于android中PendingIntent.getBroadcase的注册广播VSAlarmManager .cancle(PendingIntent)如何区分PendingIntent
使用语句
- PendingIntent intent= PendingIntent.getBroadcast(Context context, int requestCode, Intent intent, int flags)
获得PendingIntent,浏览了各类文章,大多数说了这种方法,但是基本上也就是止步于此,可是还有最重要的没有谈及,如何区别多个已注册的PendingIntent呢,看了一下PendingIntent.getBroadcast的javadoc,第四个参数flags意为标记,初步认为flags是标识各个PendingIntent的,于是在测试中设置了个全局变量
- public static int currentIntent=0;
然后用currentIntent++作为第四个参数传递进去,测试,注册了两个监听,等待时间的到来,bingo,居然可以了,目测已经可以。可是继续深入时问题来了,我要传递参数怎样?正解做法就是在第三个参数中设置
- intent.setExtra(String key,String value); //设置传递的参数
然后在自己实现的Receiver里用传进来的参数Intent intent实现
- intent.getIntegerExtra(String key);
就可以获得参数,可以真正在实现的时候发现,在receiver里始终取不到参数,再经过一番查找,发现要把PendingIntent.getBroadcast的第四个参数设置于PendingIntent.FLAG_UPDATE_CURRENT,设置后测试,果然可以,可是这样问题又出来了,又要如何区别注册的intent呢?再次查看getBroadcast的javadoc,几个参数都没有说明如何区别要注册的PendingIntent,反而看到第二个参数的说明很神奇,就是这个参数目前为保留状态,仍未用到,无奈中,继续search各种说法,才发现,用requestCode来区别居然是可以的(可是为什么javadoc要说该参数未被使用呢?不解;估计用于区分PendingIntent的方法就是其中任意一个参数不同便可以区分了)代码如下:
设置监听
- Intent setAlertIntent=new Intent(this,AlertReceiver.class);
- setAlertIntent.putExtra("try", "i'm just have a try");
- PendingIntent pendingIntent=PendingIntent.getBroadcast(this, alarmCount++, setAlertIntent,PendingIntent.FLAG_UPDATE_CURRENT);
- AlarmManager alarmManager=(AlarmManager)getSystemService(ALARM_SERVICE);
- alarmManager.set(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), pendingIntent);
Receiver中获取传递的数据:
public void onReceive(Context context, Intent intent) {// TODO Auto-generated method stubBundle bundle= intent.getExtras();if(bundle==null){Toast.makeText(context,"nothing", Toast.LENGTH_LONG).show();}else{Set<String> set=bundle.keySet();for(String item:set){System.out.println(item);System.out.println(".............");}Toast.makeText(context,bundle.getCharSequence("try"), Toast.LENGTH_LONG).show();}}
以上转自:http://blog.csdn.net/huang_hws/article/details/7327670
上面写得非常不错!但是抛出了一个问题:如何区别要注册的PendingIntent ?真的是以requestCode来区分的?
实际上,并不是以requestCode来区分
不妨做个试验1:
Intent intent = new Intent("MyReceiver");
Intent _intent = new Intent("LOL"); //注意这里是 _intent !有下划线的
PendingIntent p = PendingIntent.getBroadcast(AlarmMainActivity.this, 0, intent,PendingIntent.FLAG_UPDATE_CURRENT);
PendingIntent p1 = PendingIntent.getBroadcast(AlarmMainActivity.this, 1, intent,PendingIntent.FLAG_UPDATE_CURRENT);
PendingIntent p2 = PendingIntent.getBroadcast(AlarmMainActivity.this, 0, intent,PendingIntent.FLAG_CANCEL_CURRENT);
PendingIntent p3 = PendingIntent.getBroadcast(AlarmMainActivity.this, 0, _intent,PendingIntent.FLAG_UPDATE_CURRENT);
PendingIntent p4 = PendingIntent.getBroadcast(AlarmMainActivity.this, 0, intent,PendingIntent.FLAG_UPDATE_CURRENT);
System.out.println("*******");
if(p == p1)System.out.println("p1==p");
if(p == p2)System.out.println("p2==p");
if(p == p3)System.out.println("p3==p");
if(p == p4)System.out.println("p4==p");
System.out.println("*******");
结果输出:
很吃惊!居然p1 - 4都没有一个跟p 是同一个引用,说明每调用PendingIntent.getBroadcast(.....),构造的PendingIntent都不一样,哪怕是构造参数也一样。
那么AlarmManager.cancle(PendingIntent operation)这注销PendingIntent的函数是如何实现注销的的功能的?
该方法在Android API Docs 中的解析:
Remove any alarms with a matching Intent. Any alarm, of any type, whose Intent matches this one (as defined by filterEquals(Intent)), will be canceled.
关于如何matches Intent,又转移到: filterEquals(Intent) 这方法(在Intent类中)
该方法在Android API Docs 中的解析:
public boolean filterEquals (Intent other)
Determine if two intents are the same for the purposes of intent resolution (filtering). That is, if their action, data, type, class, and categories are the same. This does not compare any extra data included in the intents.
这里说明只比较action data type class categories 而不比较里面的extra data(e.g. Bundle 、extra string int long ....)
所以这样就可以理解到cancle()的实现方式
但是国外大神们都说更requestCode 有关 参考: http://stackoverflow.com/questions/3273342/how-can-i-setup-multiple-alarms-in-android/3274576#3274576 不知道是不是我理解错了?(本人是弱菜>.<)
下面给出public boolean filterEquals (Intent other) 方法实现的源码:
public boolean filterEquals(Intent other) {
5489 if (other == null) {
5490 return false;
5491 }
5492 if (mAction != other.mAction) {
5493 if (mAction != null) {
5494 if (!mAction.equals(other.mAction)) {
5495 return false;
5496 }
5497 } else {
5498 if (!other.mAction.equals(mAction)) {
5499 return false;
5500 }
5501 }
5502 }
5503 if (mData != other.mData) {
5504 if (mData != null) {
5505 if (!mData.equals(other.mData)) {
5506 return false;
5507 }
5508 } else {
5509 if (!other.mData.equals(mData)) {
5510 return false;
5511 }
5512 }
5513 }
5514 if (mType != other.mType) {
5515 if (mType != null) {
5516 if (!mType.equals(other.mType)) {
5517 return false;
5518 }
5519 } else {
5520 if (!other.mType.equals(mType)) {
5521 return false;
5522 }
5523 }
5524 }
5525 if (mPackage != other.mPackage) {
5526 if (mPackage != null) {
5527 if (!mPackage.equals(other.mPackage)) {
5528 return false;
5529 }
5530 } else {
5531 if (!other.mPackage.equals(mPackage)) {
5532 return false;
5533 }
5534 }
5535 }
5536 if (mComponent != other.mComponent) {
5537 if (mComponent != null) {
5538 if (!mComponent.equals(other.mComponent)) {
5539 return false;
5540 }
5541 } else {
5542 if (!other.mComponent.equals(mComponent)) {
5543 return false;
5544 }
5545 }
5546 }
5547 if (mCategories != other.mCategories) {
5548 if (mCategories != null) {
5549 if (!mCategories.equals(other.mCategories)) {
5550 return false;
5551 }
5552 } else {
5553 if (!other.mCategories.equals(mCategories)) {
5554 return false;
5555 }
5556 }
5557 }
5558
5559 return true;
5560 }
后来我又发现原来PendingIntent复写了equals()的方法
所以我实验了一下: (替换了一下上面的)
System.out.println("*******");
if(p.equals(p1))System.out.println("p1==p");
if(p.equals(p2))System.out.println("p2==p");
if(p.equals(p3))System.out.println("p3==p");
if(p.equals(p4))System.out.println("p4==p");
System.out.println("*******");
结果还是一样!囧! PendingIntent 文档说明:
public boolean equals (Object otherObj)
Comparison operator on two PendingIntent objects, such that true is returned then they both represent the same operation from the same package. This allows you to use getActivity(Context, int, Intent, int)
, getBroadcast(Context, int, Intent, int)
, or getService(Context, int, Intent, int)
multiple times (even across a process being killed), resulting in different PendingIntent objects but whose equals() method identifies them as being the same operation.
Parameters
otherObj | the object to compare this instance with. |
---|
Returns
true
if the specified object is equal to thisObject
;false
otherwise.
564
@Override
565
public boolean equals(Object otherObj) {
566
if (otherObj instanceof PendingIntent) {
567
return mTarget.asBinder().equals(((PendingIntent)otherObj)
568
.mTarget.asBinder());
569
}
570
return false;
571
}
关于android中PendingIntent.getBroadcase的注册广播VSAlarmManager .cancle(PendingIntent)如何区分PendingIntent相关推荐
- android中群发短信PendingIntent.getBroadcase的注册广播
/*** 发送的广播**/String SENT_SMS_ACTION = "SENT_SMS_ACTION"; // 注册广播registerReceiver(sendMess ...
- Android中build target,minSdkVersion,targetSdkVersion,maxSdkVersion概念区分
Android中build target,minSdkVersion,targetSdkVersion,maxSdkVersion概念区分 本文参考了谷歌开发者文档:http://developer. ...
- android四大组件之Service 注册广播接收者
广播的注册一共有两种,一种就是用清单文件注册,还有另外一种就是用代码注册,代码注册比较灵活,可以在需要的时候注册,不需要的时候解除注册 用服务注册广播首先要开启服务, 然后在服务oncreate方法里 ...
- android广播 有序 无序,Android中的有序和无序广播浅析
BroadcastReceiver所对应的广播分两类:无序广播和有序广播. 无序广播即为我们平时经常使用的广播,其主要是通过public abstract void sendBroadcast (In ...
- android 接收来电广播,android中未接来电的广播接收器
Joe.. 11 您需要使用ContentObserver public class MissedCallsContentObserver extends ContentObserver { publ ...
- android registerreceiver传参数,Android应用程序注册广播接收器(registerReceiver)的过程分析...
前面我们介绍了Android系统的广播机制,从本质来说,它是一种消息订阅/发布机制,因此,使用这种消息驱动模型的第一步便是订阅消息:而对Android应用程序来说,订阅消息其实就是注册广播接收器,本文 ...
- Android应用程序注册广播接收器 registerReceiver 的过程分析
分享一下我老师大神的人工智能教程!零基础,通俗易懂!http://blog.csdn.net/jiangjunshow 也欢迎大家转载本篇文章.分享知识,造福人民,实现我们中华民族伟大复兴! 前面我们 ...
- 创建广播接收器并注册广播
发送广播:使用Intent 接收广播:广播接收器 创建广播接收器: 方法:新建一个类继承自BroadcastReceiver,并重写父类的onReceive( )方法.当有广播接收到的时候,onRec ...
- Android学习小Demo(13)Android中关于ContentObserver的使用
在一些应用上,比如手机银行,QQ,微信等,很多时候我们都需要通过发送验证码到手机上,然后把验证码填上去,然后才能成功地继续去做下面一步事情. 而如果每次我们都要离开当前界面,然后去查收短信,记住验证码 ...
最新文章
- markdown demo 学习
- C++学习 之 fill和memeset的区别
- 海量存储系列上--转载,值得一读
- hdu 1879 继续通畅工程(最小生成树)
- 使用单项循环链表实现字典操作(算法导论第十章10.2-5题)
- RuntimeError: Failed to register operator torchvision::_new_empty_tensor_op. +torchtorchversion版本匹配
- VSCODE远程连接服务器,远程开发。
- mvn 修改所有子项目pom版本
- 《大数据》第1期“研究”——大数据管理系统评测基准的挑战与研究进展(下)...
- 嵌入式开发之davinci--- spi 中的时钟极性CPOL和相位CPHA
- ajax如何处理程序设计,Struts与Ajax高级程序设计
- 百度音乐 android,千千音乐(com.ting.mp3.android) - 8.2.3.4 - 应用 - 酷安
- Openlayer 3 的画图测量面积
- Tensorflow的快速安装(张量图例)
- Windows 7程序开发系列之一(任务栏篇)
- CF369E Valera and Queries
- Unity中如何跟随某个物体运动浅谈
- 制图综合,制图综合的影响因素?
- Springboot整合JavaMail通过阿里企业邮箱发验证码
- [ctf.show.reverse] BJDCTF2020 encode
热门文章
- 同城CP群是怎么赚钱的?寂寞的人们来买单!
- (LeetCode 406)根据身高重建队列 [贪心+sort+条件推理 ]
- 视频摘要算法综述 ==》Video Synopsis
- eul for Mac(菜单栏系统监控工具)中文版支持m1芯片
- AR市场为何频频“呼唤”苹果?
- element-ui iconfont.woff 报404错误
- 计算机考试系统无法创建word,干货分享 | 时间来不及备考计算机考试,怎么办?...
- 写一个 JS 调用栈可视化工具 hound-trace
- Linux命令大全- tcpdump命令详解
- 【RT-Thread开源作品秀】基于STM32F407与RT-Thread的智能水培系统