短息发送成功后,收到短信中心返回的状态后界面会提示xxx已收到消息;
这原本是个非常简单的Toast提示,不过在android的Mms源码中却中转了n次
写得有些复杂。这几天在改一个相关bug,分析了一次,这里将分析过程贴
方便大家查阅,减少遇到相关问题时话费在了解其提示过程的时间。
首先在Mms里搜索字符串:delivery_toast_body
可以搜到只在MessagingNotification类中有用到(其他的资源文件不管)。
打开MessagingNotification类找到相关地方如下:
private static final MmsSmsDeliveryInfo getSmsNewDeliveryInfo(Context context) {
ContentResolver resolver = context.getContentResolver();
Cursor cursor = SqliteWrapper.query(context, resolver, Sms.CONTENT_URI,
SMS_STATUS_PROJECTION, NEW_DELIVERY_SM_CONSTRAINT,
null, Sms.DATE_SENT);
if (cursor == null) {
return null;
}
try {
if (!cursor.moveToLast()) {
return null;
}
String address = cursor.getString(COLUMN_SMS_ADDRESS);
long timeMillis = 3000;
Contact contact = Contact.get(address, false);
String name = contact.getNameAndNumber();
return new MmsSmsDeliveryInfo(context.getString(R.string.delivery_toast_body, name),
timeMillis);//字符串在这里被调用
} finally {
cursor.close();
}
}
看到如上代码后,发现没什么Toast提示,所以只能跟踪下getSmsNewDeliveryInfo这个方法,看它在哪被调用了
搜索该方法后:
public static void blockingUpdateNewMessageIndicator(Context context, long newMsgThreadId,
boolean isStatusMessage) {
/// M: add for notification settings
NotificationProfile notiProf = getNotificationProfileByThreadId(context, newMsgThreadId);
。。。。。。。
MmsSmsDeliveryInfo delivery = null;
。。。。。。。
// And deals with delivery reports (which use Toasts). It's safe to call in a worker
// thread because the toast will eventually get posted to a handler.
delivery = getSmsNewDeliveryInfo(context);//该方法在此被调用了,并赋给了delivery
if (delivery != null) {
delivery.deliver(context, isStatusMessage);//delivery又调用deliver(context, isStatusMessage)方法
}
notificationSet.clear();
threads.clear();
}
这里我们就得搜索deliver(context, isStatusMessage)方法了:
搜后发现在下面这个内部类里面:
private static final class MmsSmsDeliveryInfo {
public CharSequence mTicker;
public long mTimeMillis;
public MmsSmsDeliveryInfo(CharSequence ticker, long timeMillis) {
mTicker = ticker;
mTimeMillis = timeMillis;
}
public void deliver(Context context, boolean isStatusMessage) {
updateDeliveryNotification(
context, isStatusMessage, mTicker, mTimeMillis);
}
}
然后搜素 updateDeliveryNotification(context, isStatusMessage, mTicker, mTimeMillis); 方法。因为这里
deliver(Context context, boolean isStatusMessage)方法的实现就只调用了它。
搜后发现终于是找到了Toast提示:
private static void updateDeliveryNotification(final Context context,
boolean isStatusMessage,
final CharSequence message,
final long timeMillis) {
if (!isStatusMessage) {
return;
}
if (!NotificationPreferenceActivity.getNotificationEnabled(context)) {
return;
}
sToastHandler.post(new Runnable() {
@Override
public void run() {
Toast.makeText(context, message, (int)timeMillis).show();//这里它启动了一个线程来做toast提示。
}
});
}
搜到这里你只要将这些方法稍微看看,也就明白短信发送后是如何做Toast提示的了。