I. Problem Analysis:Recently, I am working on a function to remotely start an application using text message monitoring. The Code is as follows:
Import android. content. broadcastreceiver; import android. content. context; import android. content. intent; import android. OS. bundle; import android. telephony. smsmessage; import android. widget. toast; publicclass smsreceiver extends broadcastreceiver {/* This method is triggered when you receive the text message */publicvoid onreceive (context, intent) {bundle = intent. getextras (); If (bundle! = NULL & bundle. Get ("PDUS ")! = NULL) {object [] PDUS = (object []) bundle. Get ("PDUS"); // get the array object if (PDUS! = NULL & PDUS. length> 0) {smsmessage [] messages = new smsmessage [PDUS. length]; for (INT I = 0; I <PDUS. length; I ++) {byte [] PDU = (byte []) PDUS [I]; // get the text message content, the content is the messages [I] = smsmessage that is stored in the PDU format. createfrompdu (PDU);} For (smsmessage MSG: messages) {string smscontent = MSG. getmessagebody (); // get the text message content string smssender = MSG. getoriginatingaddress (); // get the mobile phone number of the text message sender }}}}}
During actual application, it is found that an exception always occurs in the smsmessage. createfrompdu location when the dual-mode mobile phone is connected to the received text message. Exception information: Java. Lang. outofmemoryerror: array size too large
At com. Android. Internal. telephony. CDMA. smsmessage. parsepdu (smsmessage. Java: 658)
At com. Android. Internal. telephony. CDMA. smsmessage. createfrompdu (smsmessage. Java: 116)
At Android. telephony. smsmessage. createfrompdu (smsmessage. Java: 162). You can see the createfrompdu method in the android source code:
publicstatic SmsMessage createFromPdu(byte[] pdu) { SmsMessageBase wrappedMessage; int activePhone = TelephonyManager.getDefault().getPhoneType(); if (PHONE_TYPE_CDMA == activePhone) { wrappedMessage = com.android.internal.telephony.cdma.SmsMessage.createFromPdu(pdu); } else { wrappedMessage = com.android.internal.telephony.gsm.SmsMessage.createFromPdu(pdu); } returnnew SmsMessage(wrappedMessage); }
If it is a dual-mode mobile phone, an error occurs when this method is called. The problem is that telephonymanager of the source code. getdefault (). getphonetype (); the return value of this method does not have the corresponding type of dual-mode mobile phone. The native Android system does not support dual-mode mobile phones.Ii. solution:We can use the combination of the broadcast receiver and content observer to directly read the text message database of the mobile phone, so as to avoid errors, so we will not talk much about the nonsense and directly go to the Code:
Import android. content. broadcastreceiver; import android. content. context; import android. content. intent; import android. database. contentobserver; import android. database. cursor; import android.net. uri; import android. OS. handler; publicclass smsreceiver extends broadcastreceiver {privatestaticfinal string sms_received = "android. provider. telephony. sms_received "; private context m_context; private smsconten Tobserver m_smsobserver = new smscontentobserver (new handler (); @ override publicvoid onreceive (context, intent) {This. m_context = context; If (intent. getaction (). equals (sms_received) {// registers the text message change listener context. getcontentresolver (). registercontentobserver (URI. parse ("content: // SMS/"), true, m_smsobserver) ;}/ *** SMS content Observer * @ author sinber **/PrivateClass smscontentobserver extends con Tentobserver {public smscontentobserver (handler) {super (handler);}/*** @ description when the text table sends a change, to call this method, * Two permissions are required * <li> android. permission. read_sms read SMS </LI> * <li> android. permission. write_sms write text message </LI> * @ author sinebr **/@ override publicvoid onchange (Boolean selfchange) {super. onchange (selfchange); cursor = NULL; try {// read the text message cursor = m_context.getcontentresolver () in the inbox (). query (URI. P Arse ("content: // SMS/inbox"), null, "date DESC"); string body; Boolean hasdone = false; If (cursor! = NULL) {While (cursor. movetonext () {body = cursor. getstring (cursor. getcolumnindex ("body"); If (body! = NULL & Body. equals ("[startmyactivity]") {// the application code hasdone = true; break ;}if (hasdone) {break ;}} is skipped here ;}}}} catch (exception e) {e. printstacktrace ();} finally {If (cursor! = NULL) cursor. Close ();}}}}
Finally, do not forget to add the corresponding permissions in androidmanifest. xml,
<! -- Receive SMS permission --> <uses-Permission Android: Name = "android. Permission. receive_sms"/> <! -- Send SMS permission --> <uses-Permission Android: Name = "android. Permission. send_sms"/>
Do not forget to register the broadcast receiver:
<receiver android:name=".SMSReceiver"><intent-filter><action android:name="android.provider.Telephony.SMS_RECEIVED"/></intent-filter></receiver>
In this way, we can adapt to all Android phones. No problem is found in dual mode or single mode, and the problem is solved.