• SMS的源码研究


    SMS_UI---Layout
    conversation_list_screen.xml
    显示对话列表
    conversation_list_actionbar.xml
    未读对话列表的选中高亮 id:unread_conv_count 
    conversation_list_multi_select_actionbar.xml
    已选会话列表的选中高亮 id:selected_conv_count
    conversation_list_item.xml
    每组会话在列表中都是图片+fromdatesubject的形式
    compose_message_activity.xml
    编辑框 发送(id:send_button_sms) 全选 取消 删除

    SMS---Src
    1UI入口
    ComposeMessageActivity extends Activity(com.android.mms.ui)
    onCreate() 
    initMessageSettings()
    加载setting中的设置
    initResourceRefs()
    初始化UI控件
    mSendButtonSms = (ImageButton) findViewById(R.id.send_button_sms);
    mSendButtonSms.setOnClickListener(this); 
    | (mUiHander
    表示一个主线程的Handle对象)
    onClick(View v) --> mUiHandler.sendEmptyMessageDelayed(MSG_RESUME_SEND_BUTTON, RESUME_BUTTON_INTERVAL);
    等待指定的时间(1)之后发送消息到子线程
    sendMessage()
    允许你处理Message对象(Message里可以包含数据)sendEmptyMessage()只能放数据

    SaveMsgThread extends Thread
    启动消息队列机制
    2)待传送的信息
    WorkingMessage (com.android.mms.data)
    即将发送的短信类
    3)发送信息
    SmsMessageSender implements MessageSender(com.android.mms.transaction)
    为短信的发送作准备,使sms进入消息队列,分离接收人
    SmsSingleRecipientSender extends MessageSender
    发送一条短信,最终用frameworkSmsManager来发送信息
    4)接收信息
    SmsReceiver extends BroadcastReceiver(com.android.mms.transaction)
    请求sms service的入口
    PrivilegedSmsReceiver extends SmsReceiver(com.android.mms.transaction)
    接收短信的类

    SmsReceiverService extends Service(com.android.mms.transaction)sms
    的处理中心,处理信息的 send/receive,处理一些来自framework层的的通知。
    MessageStatusReceiver extends BroadcastReceiver(com.android.mms.transaction)
    捕获信息,并读取信息的状态

    SMS---解读
    1)发送信息的流程
    用户在ComposeMessageActivitynew一个WorkingMessage对象
    WorkingMessage
    new一个SmsMessageSender对象
    PendingIntent
    是一个发送异步intent的类
    本质上就是使用MessageSender接口发送信息,实现该接口必须实例化两个方法,分别是sendMessage(long token)setSimId(int simId)

    framework层发送信息的方法 对应于android.telephony.SmsMessage;

    所有发送的消息最终都要保存至消息队列,SmsReceiver--> SmsReceiverService --> SmsSingleRecipientSender -->framework:SmsManager


    (2)
    接收信息的流程
    本质上是靠PrivilegedSmsReceiver类来接收信息

    framework层接收信息的方法 对应于android.telephony.SmsMessage;
    所有接收的消息最终都要保存到消息队列,SmsReceiverService --> SmsSingleRecipientSender -->framework:SmsManager

    (3)数据库的存取
    所有的消息,最终都会保存在sqlite中,对应的数据库操作涉及framework
    framework:SqliteWrapper(android.database.sqlite)
    framework:ContentResovler(android.content)
    framework:SQliteDatabase
    提供query()方法

    MMS---初探
    数据库层MmsSms的区别在于,sms直接用query()update(),mms则使用PduPersister(android.mms.pdu)
    MMS
    主要的处理都在app层,在framework层中主要涉及MMS pdu包的解析处理和发送和接受MMS时的网络处理。
    pdu---(protocol description unit)
    可以从接收到的pdu中创建新的SmsMessage实例,Toast界面组件可以以系统通知的形式来显示接收到的SMS消息文本。
    MMS的操作直接就是对mmssms.db数据库的操作

    (1)push MMS 接收
    MMS
    通知消息是以短信息PDU包的形式传递过来的(M-Notification.ind PDU)Android中的具体处理流程如下:
    1
    )当有新信息来的时候,atchannelreader线程会调用onUnsolicited()函数处理。
    2
    onUnsolicited()函数调用RIL_onUnsolicitedResponse()函数,并传入RIL_UNSOL_RESPONSE_NEW_SMS值及相应数据。
    3
    RIL_onUnsolicitedResponse()调用sendResponse()函数,通过socket(socket名:SOCKET_NAME_RIL)ril.java层传递数据。
    4
    ril java层通过RILReceiver接收器从socket中读出数据,处理后调用ril类中的processResponse()方法,processResponse()方法调用processUnsolicited()方法。
    5
    )在processUnsolicited()方法中,执行下面语句:
    case RIL_UNSOL_RESPONSE_NEW_SMS: {
    if (RILJ_LOGD) unsljLog(response);
    String a[] = new String[2];
    a[1] = (String)ret;
    SmsMessage sms;
    sms = SmsMessage.newFromCMT(a); //
    根据SMS协议解析PDU
    if (mSMSRegistrant != null) {
    mSMSRegistrant.notifyRegistrant(new AsyncResult(null, sms, null)); 
    }
    break;
    其中mSMSRegistrant实例是在初始化的时候创建的,其中存储着SMSDispatcher handler对象和EVENT_NEW_SMS事件信息。
    随后通过message消息机制和handler处理机制把EVENT_NEW_SMS事件传递到了SMSDispatcher handler类 处理。
    6
    SMSDispatcher handler接收到EVENT_NEW_SMS事件,调用handleMessage()方法处理,handleMessage()方法调用其子类dispatchMessage()方法。
    7
    )在dispatchMessage()中,根据smsHeader.portAddrs(PORT_WAP_PUSH = 2948)地址来判断是否是PUSH信息。
    8
    )调用WapPushOverSms类的dispatchWapPdu()方法。
    9
    )使用WspTypeDecoder类实例来对PUSH信息进行解析,并根据content type来判断是否是MMS PUSH信息。
    10
    )调用dispatchWapPdu_MMS()方法,通过SMSDispatcher类的dispatch()方法来广播发送intent. WAP_PUSH_RECEIVED_ACTION
    11
    PushReceiver接收到该intent,启动ReceivePushTas并执行doInBackground()方法。
    12
    )在doInBackground()方法中,通过PduParser类对象解析对应的PDU包,然后执行如下代码:
    case MESSAGE_TYPE_NOTIFICATION_IND: {
    NotificationInd nInd = (NotificationInd) pdu;
    if (!isDuplicateNotification(mContext, nInd)) {
    Uri uri = p.persist(pdu, Inbox.CONTENT_URI); //MMS PUSH
    信息存储在inbox.
    Intent svc = new Intent(mContext, TransactionService.class);//intent
    启动的是TransactionService
    svc.putExtra(TransactionBundle.URI, uri.toString());
    svc.putExtra(TransactionBundle.TRANSACTION_TYPE,
    Transaction.NOTIFICATION_TRANSACTION);//transaction
    类型:NOTIFICATION_TRANSACTION
    mContext.startService(svc);//
    启动TransactionService服务
    }
    13
    TransactionService类中的onStart()调用launchTransaction()方法
    14
    launchTransaction()方法传递给ServiceHandler EVENT_TRANSACTION_REQUEST事件。
    15
    ServiceHandler类的handleMessage()方法处理EVENT_TRANSACTION_REQUEST事件,根据Transaction的类型为NOTIFICATION_TRANSACTION
    创建NotificationTransaction类实例,并根据URImmssms.db中取出PDU包。
    16
    )调用processTransaction(transaction)方法,在processTransaction()方法中,执行如下代码:
    int connectivityResult = beginMmsConnectivity();//
    通过beginMmsConnectivity函数进行data connection
    if (connectivityResult == Phone.APN_REQUEST_STARTED) { //
    如果返回APN_REQUEST_STARTED结果,表示data connection正在连接,等待返回EVENT_DATA_STATE_CHANGED事件
    mPending.add(transaction);//
    transaction放入等待队列中
    return true; //
    返回,等待EVENT_DATA_STATE_CHANGED事件再继续处理
    }
    transaction.attach(TransactionService.this); //
    因为Transaction 类和TransactionService 类都继承自Observable类,
    //
    此处是为了Transaction类的子类在处理完成后通知TransactionService相应的处理结果。
    transaction.process(); //
    进入NotificationTransaction类中处理,创建一个新的线程来处理该transaction
    17)
    下面的处理请参照MMS相关transaction中的NotificationTransaction说明。

    (2)MMSC中提取MMS
    根据DownloadManager类中的mAutoDownload变量的值,从MMSC中提取MMS有两种情况:
    1
    )如果mAutoDownloadTRUE,即允许自动提取,那么在indication通知上来的时候,就会从MMSC向提取MMS信息。
    即使在NotificationTransaction中所做的处理。具体请参照MMS相关transaction中的NotificationTransaction说明
    2
    )否则,就需要手动去从MMSC中提取。具体处理如下:此时UI层会启动TransactionService,并传入Transaction.RETRIEVE_TRANSACTION类型。
    其他的处理流程参考第一条(push MMS接收)中的第13到第17步,只不过相应的transactionRetrieveTransaction,而非NotificationTransaction

    (3)MMS发送
    MMS
    的发送动作是由UI来触发的,主要是有ComposeMessageActivity类中的sendMmsWorker()方法来处理。具体处理流程如下:
    1. sendMmsWorker()
    方法中,创建MmsMessageSender类实例sender,并调用MmsMessageSender类中的sendMessage()方法。
    2.
    mmssms.db中取出对应的PDU数据,把信息移到outbox(以前是存储在draft),然后启动TransactionService服务进行transaction处理。
    3.
    通过TransactionService处理进入了SendTransaction类的run()方法中处理。
    (4)MMS
    存储/删除等数据操作
    MMS
    信息的存储是以SQLite3为基础的,而且其mmssms.db数据库在第一次创建后会一直存在,这就对MMS的存储处理变得简单很多,只需要执行相应的SQL语句就行。
    MMS
    中的内容部分是存储在file中的,并没有放在mmssms.db数据库中,数据库中存放的是如下几张表:
    static final String TABLE_PDU = "pdu";//PDU
    相关信息的表
    static final String TABLE_ADDR = "addr";//MMS
    发件人/收件人地址相关的表
    static final String TABLE_PART = "part"; //body
    可能分成几个部分,存储part相关信息的表,通过该part信息,就可以从file中取到对应的内容部分
    static final String TABLE_RATE = "rate"; // SENT_TIME
    信息表
    static final String TABLE_DRM = "drm"; 
    (5)MMS
    参数设置
    MMS
    的参数设置也是通过SQLite3数据库进行操作的,其content provider类:TelephonyProvider,其DatabaseHelper类是其内部类。
    TelephonyProvider
    对应的CONTENT_URITelephony 类的Carriers内部类中。
    MMS
    参数的设置主要在setting模块操作

     




  • 相关阅读:
    Odoo13_多选下拉框
    Odoo13_联动下拉框
    Odoo13_上传文件并指定保存到位置
    Flask_cookie和session
    云原生设计理念
    docker 清理掉none对象,未使用网络,缓存等命令
    解决ssh连接中断问题
    python更改程序运行目录为程序所在文件夹
    Vuejs Cron 表达式校验
    Kubernetes WebSocket: Error during WebSocket handshake: Unexpected response code: 403
  • 原文地址:https://www.cnblogs.com/yingzi/p/2814895.html
Copyright © 2020-2023  润新知