NoticationMgr对于未接来电的处理.docx_第1页
NoticationMgr对于未接来电的处理.docx_第2页
NoticationMgr对于未接来电的处理.docx_第3页
NoticationMgr对于未接来电的处理.docx_第4页
NoticationMgr对于未接来电的处理.docx_第5页
已阅读5页,还剩8页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

NoticationMgr对于未接来电的处理通过本文档将要学习Android KK和Android L两大版本对于未接来电逻辑处理上的差异,这个差异主要体现在架构设计。主要是通过以下三个方面:q 取消未接来电的通知;q 有未接来电时的通知;q 开机显示未接来电的能知;Android KK版本对未接来电(Missed call)的处理取消未接来电的通知当有未接来电时显示未接来电的通知当有未接来电时显示未接来电的通知是由CallNotifier的onDisconnect方法调用NotificationMgr的notifyMissedCall方法,第8行调用PhoneGlobals.createCallLogIntent方法获得拉起通话记录的intent,第16行的mNumberMissedCalls+未接来电计数器自增1,第20至第27行是设置显示的信息只有一个未接来电时,会显示“未接来电/XX”,XX是联系人的姓名或号码,有多个未接来电时,会显示“未接来电/n个未接来电”,当只有一个未接来电时,且号码有效时,增加两个action,即“回拨”、“发信息”,当参数phoneIcon或photo不为null时,还可以设置在托盘中显示的大图标。最后调用NotificationManager的notify方法在托盘中显示未接来电通知开机后显示未接来电通知当Phone应用启动的时候在PhoneGlobals的onCreate方法中调用NotificationMgr的init方法进行初始化,接着调用updateNotificationAtStartup方法在NotificationMgr的updateNotificationAtStartup方法中实例化QueryHandler,主要用于查询通话记录、联系人等信息,第10至12行是设置查询的条件,第16行调用QueryHandler的startQuery方法执行查询,注意在调用startQuery方法的第一个参数CALL_LOG_TOKEN,此查询是异步执行的。整体介绍一个QueryHandler的结构,QueryHandler是异常查询处理器,主要完成查询通话记录,根据通话记录查询联系人,加载联系人的头像NotificationInfo用于存储查询出来的未接来电的基本信息通话记录完成后回调onQueryComplete方法,在调用startQuery时传入的第一个参数是CALL_LOG_TOKEN,所以此时case CALL_LOG_TOKEN满足,调用getNotificationInfo方法,将cursor中的信息构造一个NotificationInfo的实例,再次调用QueryHandler的startQuery方法查询通话记录是否存在对应的联系人信息,传入的第一个参数是CONTACT_TOKEN,调用getNotificationInfo方法,将cursor中的信息构造一个NotificationInfo的实例联系人信息查询完成后回调onQueryComplete方法,token是CONTACT_TOKEN,对于是一个默生的号码(通讯录人不存在对应的联系人信息)时直接调用notifyMissedCall方法在托盘显示未接来电通知,如果存在对应的联系人信息通过调ContactAsyncHelper的startObtainPhotoAsync方法获取对应联系人的头像,QueryHandler已实现了ContactAsyncHelper的OnImageLoadCompleteListener接口,所以联系人头像加载完成后回调QueryHandler的onImageLoadComplete方法,当联系人的头像加载完成后,回调onImageLoadComplete方法,最终调用notifyMissedCall方法在托盘中显示未接来电通知。Android L 未接来电的处理未接来电的处理逻辑由Android KK 版本的TeleService转移到Android L版本的Telecom中处理,但是在TeleService中仍然保留了KK版本的NotificationMgr类的代码,但如Android KK版本对外的接口已经不存在了。取消未接来电的通知第三方的应用可以通过调用TelecomManager类的cancelMissedCallsNotification方法取消未接来电的消息通知,看到cancelMissedCallsNotification的方法的命名应该感到很nice吧,这个就是将Android KK中TelephonyManager中移植过来的。public class TelecomManager .public void cancelMissedCallsNotification() ITelecomService service = getTelecomService();if (service != null) try service.cancelMissedCallsNotification(); catch (RemoteException e) 代码 x-xTelecomManager调用TelecomServiceImpl的cancelMissedCallsNotification方法后,向内部的MainThreadHandler发送MSG_CANCEL_MISSED_CALLS_NOTIFICATION消息,处理此消息时调用了MissedCallNotifier的clearMissedCalls方法。public class TelecomServiceImpl extends ITelecomService . public void cancelMissedCallsNotification() enforceModifyPermissionOrDefaultDialer(); sendRequestAsync(MSG_CANCEL_MISSED_CALLS_NOTIFICATION, 0); private final class MainThreadHandler extends Handler Override public void handleMessage(Message msg) if (msg.obj instanceof MainThreadRequest) MainThreadRequest request = (MainThreadRequest) msg.obj; Object result = null; switch (msg.what) . case MSG_CANCEL_MISSED_CALLS_NOTIFICATION: mMissedCallNotifier.clearMissedCalls(); break;.代码 x-xMissedCallNotifier的clearMissedCalls做了两件事件:q 将通话记录数据库中的未接来电记录的未读状态变更为已读状态;q 清除在通知栏中的通知;通话记录未接来电的未读状态-已读状态,通过一个多线程异步任务的方法更新通话记录的provider。 public class MissedCallNotifier . /* Clears missed call notification and marks the call logs missed calls as read. */ void clearMissedCalls() AsyncTask.execute(new Runnable() Override public void run() / Clear the list of new missed calls from the call log. try ContentValues values = new ContentValues(); values.put(Calls.NEW, 0); values.put(Calls.IS_READ, 1); StringBuilder where = new StringBuilder(); where.append(Calls.NEW); where.append( = 1 AND ); where.append(Calls.TYPE); where.append( = ?); mContext.getContentResolver().update(Calls.CONTENT_URI, values, where.toString(), new String Integer.toString(Calls.MISSED_TYPE) ); catch (Exception e) e.printStackTrace(); Log.e(MissedCallNotifier, e, ); ); cancelMissedCallNotification(); .代码 x-x接着调用cancelMissedCallNotification方法,内部通过调用NotificationManager的cancel方法清除通知栏中的未接来电notification,并将未接来电计数器mMissedCallCount重置为0。 public class MissedCallNotifier . /* Cancels the missed call notification. */ private void cancelMissedCallNotification() / Reset the number of missed calls to 0. mMissedCallCount = 0; mNotificationManager.cancel(MISSED_CALL_NOTIFICATION_ID); .代码 x-x来电未接时在通知栏中显示Missed call 通知在CallsManager的构造方法中注册了回调。public CallsManager(Context context, MissedCallNotifier missedCallNotifier, PhoneAccountRegistrar phoneAccountRegistrar) . mMissedCallNotifier = missedCallNotifier; mListeners.add(missedCallNotifier);代码 x-xMissedCallNotifier继承了CallsManagerListenerBase,重构了onCallStateChanged方法,当call的状态发生变化时被回调。如果新的状态是DISCONNECTED,表示有通话断开了,如果断开的原因是MISSED,表示有一个未接来电,然后调用showMissedCallNotification方法。public class MissedCallNotifier extends CallsManagerListenerBase . public void onCallStateChanged(Call call, int oldState, int newState) if (oldState = CallState.RINGING & newState = CallState.DISCONNECTED & call.getDisconnectCause().getCode() = DisconnectCause.MISSED) showMissedCallNotification(call); 代码 x-x在showMissedCallNotification方法,主要是准备显示notfication相关的信息(如来电号码或联系人名称,头像),最终调用NotificationManager的notifyAsUser方法在通知栏中显示missed-call通知。public class MissedCallNotifier extends CallsManagerListenerBase . void showMissedCallNotification(Call call) mMissedCallCount+;. / Create the notification. Notification.Builder builder = new Notification.Builder(mContext); builder.setSmallIcon(android.R.drawable.stat_notify_missed_call) .setColor(mContext.getResources().getColor(R.color.theme_color) .setWhen(call.getCreationTimeMillis() .setContentTitle(mContext.getText(titleResId) .setContentText(expandedText) .setContentIntent(createCallLogPendingIntent() .setAutoCancel(true) .setDeleteIntent(createClearMissedCallsPendingIntent();. Notification notification = builder.build(); mNotificationManager.notifyAsUser( null /* tag */ , MISSED_CALL_NOTIFICATION_ID, notification, UserHandle.CURRENT); 代码 x-x在showMissedCallNotification中调用了Notification.Builder的setContentIntent和setDeleteIntent方法,其参数分别是createCallLogPendingInteng和createClearMissedCallsPendingIntent的返回值,setXXXIntent的作用:q 点击通知栏中的这条通知时执行;q 当通知从通知栏中移除时执行;这两个方法的返回类型都是PendingInteng,先来看一下PendingInteng是什么PendingIntentIntent英文意思是意图,Pending表示即将发生或来临的事情。 PendingIntent这个类用于处理即将发生的事情。比如在通知Notification中用于跳转页面,但不是马上跳转。 Intent 是及时启动,intent 随所在的activity 消失而消失。 PendingIntent 可以看作是对intent的包装,通常通过getActivity,getBroadcast ,getService来得到pendingintent的实例,当前activity并不能马上启动它所包含的intent,而是在外部执行 pendingintent时,调用intent的。正由于pendingintent中 保存有当前App的Context,使它赋予外部App一种能力,使得外部App可以如同当前App一样的执行pendingintent里的 Intent, 就算在执行时当前App的进程已经不存在了,也能通过存在pendingintent里的Context照样执行Intent。另外还可以处理intent执行后的操作。常和AlerManger 和NotificationManager一起使用。 Intent一般是用作Activity、Sercvice、BroadcastReceiver之间传递数据,而Pendingintent,一般用在 Notification上,可以理解为延迟执行的intent,PendingIntent是对Intent一个包装。createCallLogPendingInteng方法,返回的是打开通话记录的intent /* * Creates a new pending intent that sends the user to the call log. * * return The pending intent. */ private PendingIntent createCallLogPendingIntent() Intent intent = new Intent(Intent.ACTION_VIEW, null); intent.setType(CallLog.Calls.CONTENT_TYPE); TaskStackBuilder taskStackBuilder = TaskStackBuilder.create(mContext); taskStackBuilder.addNextIntent(intent); return taskStackBuilder.getPendingIntent(0, 0); 代码 x-xcreateClearMissedCallsPendingIntent方法的注释已经说的很清楚了,missed-call通知清除时被调用的intent,此方法的内部接着调用了createTelecomPendingIntent方法,传入字符串TelecomBroadcastReceiver.ACTION_CLEAR_MISSED_CALLS。 /* * Creates an intent to be invoked when the missed call notification is cleared. */ private PendingIntent createClearMissedCallsPendingIntent() return createTelecomPendingIntent( TelecomBroadcastReceiver.ACTION_CLEAR_MISSED_CALLS, null); 代码 x-x接着看createTelecomPendingIntent方法的实现,其实就是返回broadcast的intent。看到这一步其实大家应该已经很明白了吧,当未接来电的通知被清除的时候是发送了一个广播,那么这个广播发送给哪个类处理了呢,带着疑问我们接着往下看。 /* * Creates generic pending intent from the specified parameters to be received by * link TelecomBroadcastReceiver. * * param action The intent action. * param data The intent data. */ private PendingIntent createTelecomPendingIntent(String action, Uri data) Intent intent = new Intent(action, data, mContext, TelecomBroadcastReceiver.class); return PendingIntent.getBroadcast(mContext, 0, intent, 0); 代码 x-x找到TelecomBroadcastReceiver类的定义,原来它真的是broadcast receiver,一切就都明白了吧,当未接来电的通知被清除的时候是发送一个广播,而广播的receiver就是TelecomBroadcastReceiver,从这个类的定义可以看出除了清除未接来电,还有发送短信和回拨等。public final class TelecomBroadcastReceiver extends BroadcastReceiver /* The action used to send SMS response for the missed call notification. */ static final String ACTION_SEND_SMS_FROM_NOTIFICATION = com.android.server.telecom.ACTION_SEND_SMS_FROM_NOTIFICATION; /* The action used to call a handle back for the missed call notification. */ static final String ACTION_CALL_BACK_FROM_NOTIFICATION = com.android.server.telecom.ACTION_CALL_BACK_FROM_NOTIFICATION; /* The action used to clear missed calls. */ static final String ACTION_CLEAR_MISSED_CALLS = com.android.

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论