2011-08-17 31 views
127

我正在嘗試創建一個應用程序,用於監控收到的短信,並通過收到的短信啓動程序,同時它也應該讀取短信內容。Android - 收聽傳入短信

工作流程:發送到Android設備 自我可執行應用

短信閱讀SMS信息

如果任何人能幫助我!

+1

我知道要創建一個應用程序來發送短信,但在這裏我需要創建一個短信應用從手機短信獲取的信息並將其保存到SQLite數據庫.....我怎麼能開發這樣的應用程序 – iShader

+0

@iShader我希望你在創建應用程序方面取得了成功,只是想知道你是如何設法同步消息的設備和服務器 –

+0

檢查這個博客http://www.gadgetsaint.com/android/read -sms-messages-android /#。WLrJHRJ97fY – ASP

回答

239
public class SmsListener extends BroadcastReceiver{ 

    private SharedPreferences preferences; 

    @Override 
    public void onReceive(Context context, Intent intent) { 
     // TODO Auto-generated method stub 

     if(intent.getAction().equals("android.provider.Telephony.SMS_RECEIVED")){ 
      Bundle bundle = intent.getExtras();   //---get the SMS message passed in--- 
      SmsMessage[] msgs = null; 
      String msg_from; 
      if (bundle != null){ 
       //---retrieve the SMS message received--- 
       try{ 
        Object[] pdus = (Object[]) bundle.get("pdus"); 
        msgs = new SmsMessage[pdus.length]; 
        for(int i=0; i<msgs.length; i++){ 
         msgs[i] = SmsMessage.createFromPdu((byte[])pdus[i]); 
         msg_from = msgs[i].getOriginatingAddress(); 
         String msgBody = msgs[i].getMessageBody(); 
        } 
       }catch(Exception e){ 
//       Log.d("Exception caught",e.getMessage()); 
       } 
      } 
     } 
    } 
} 

注:在您的清單文件中添加BroadcastReceiver-

<receiver android:name=".listener.SmsListener"> 
    <intent-filter> 
     <action android:name="android.provider.Telephony.SMS_RECEIVED" /> 
    </intent-filter> 
</receiver> 

添加此權限:

<uses-permission android:name="android.permission.RECEIVE_SMS" /> 
+2

你可以擴展我爲什麼使用輔助接收器嗎? – WindRider

+2

@VineetShukla你能解釋一下pdus是什麼? –

+9

使用Intents.SMS_RECEIVED_ACTION而不是硬編碼的。 –

52

注意,在某些設備上的代碼不會不機器人工作:優先= 「1000」 in intent filter:

<receiver android:name=".listener.SmsListener"> 
    <intent-filter android:priority="1000"> 
     <action android:name="android.provider.Telephony.SMS_RECEIVED" /> 
    </intent-filter> 
</receiver> 

這裏是一些優化:

public class SmsListener extends BroadcastReceiver{ 

    @Override 
    public void onReceive(Context context, Intent intent) { 
     if (Telephony.Sms.Intents.SMS_RECEIVED_ACTION.equals(intent.getAction())) { 
      for (SmsMessage smsMessage : Telephony.Sms.Intents.getMessagesFromIntent(intent)) { 
       String messageBody = smsMessage.getMessageBody(); 
      } 
     } 
    } 
} 

注意
值必須是整數,如 「100」。更高的數字具有更高的優先級。默認值爲0的值必須大於-1000和小於1000

Here's a link.

+26

這個答案可能更優雅,但需要API 19。 – baekacaek

+8

根據[this](http://developer.android.com/guide/topics/manifest/intent-filter-element.html),'android:priority'不能高於'1000'(或小於' - 1000')。 – craned

+2

它不適用於使用Android 5.1的小米紅米Note 3 Pro。每個人都在提供這個解決方案,但它似乎不適合我。 – Sermilion

4

@Mike M.,我發現與接受答案的問題(參見我們的看法):

本質上說,在經過持續的循環,如果我們不是每次都串接多的消息是沒有意義的:

for (int i = 0; i < msgs.length; i++) { 
    msgs[i] = SmsMessage.createFromPdu((byte[])pdus[i]); 
    msg_from = msgs[i].getOriginatingAddress(); 
    String msgBody = msgs[i].getMessageBody(); 
} 

請注意,我們剛剛成立msgBody的消息不管的相應部分的字符串值我們使用的是什麼索引,這使得遍歷SMS消息不同部分的整個循環無用,因爲它只會設置爲最後一個索引值。相反,我們應該用+=,或作爲麥克指出,StringBuilder

總而言之,這裏是我的短信收到的代碼如下所示:

if (myBundle != null) { 
    Object[] pdus = (Object[]) myBundle.get("pdus"); // pdus is key for SMS in bundle 

    //Object [] pdus now contains array of bytes 
    messages = new SmsMessage[pdus.length]; 
    for (int i = 0; i < messages.length; i++) { 
     messages[i] = SmsMessage.createFromPdu((byte[]) pdus[i]); //Returns one message, in array because multipart message due to sms max char 
     Message += messages[i].getMessageBody(); // Using +=, because need to add multipart from before also 
    } 

    contactNumber = messages[0].getOriginatingAddress(); //This could also be inside the loop, but there is no need 
} 

只是把這個答案在那裏的情況下,任何人有同樣的困惑。

1

這就是我使用的!

public class SMSListener extends BroadcastReceiver { 

    // Get the object of SmsManager 
    final SmsManager sms = SmsManager.getDefault(); 
String mobile,body; 

    public void onReceive(Context context, Intent intent) { 

     // Retrieves a map of extended data from the intent. 
     final Bundle bundle = intent.getExtras(); 

     try { 

      if (bundle != null) { 

       final Object[] pdusObj = (Object[]) bundle.get("pdus"); 

       for (int i = 0; i < pdusObj.length; i++) { 

        SmsMessage currentMessage = SmsMessage.createFromPdu((byte[]) pdusObj[i]); 
        String phoneNumber = currentMessage.getDisplayOriginatingAddress(); 

        String senderNum = phoneNumber; 
        String message = currentMessage.getDisplayMessageBody(); 
        mobile=senderNum.replaceAll("\\s",""); 
        body=message.replaceAll("\\s","+"); 


        Log.i("SmsReceiver", "senderNum: "+ senderNum + "; message: " + body); 


        // Show Alert 
        int duration = Toast.LENGTH_LONG; 
        Toast toast = Toast.makeText(context, 
          "senderNum: "+ mobile+ ", message: " + message, duration); 
        toast.show(); 

       } // end for loop 
      } // bundle is null 

     } catch (Exception e) { 
      Log.e("SmsReceiver", "Exception smsReceiver" +e); 

     } 
    } 
} 
1

如果要處理上打開活動的意圖,你可以使用PendintIntent(完成以下步驟):

public class SMSReciver extends BroadcastReceiver { 
    @Override 
    public void onReceive(Context context, Intent intent) { 
     final Bundle bundle = intent.getExtras(); 
     try { 
      if (bundle != null) { 
       final Object[] pdusObj = (Object[]) bundle.get("pdus"); 
       for (int i = 0; i < pdusObj.length; i++) { 
        SmsMessage currentMessage = SmsMessage.createFromPdu((byte[]) pdusObj[i]); 
        String phoneNumber = currentMessage.getDisplayOriginatingAddress(); 
        String senderNum = phoneNumber; 
        String message = currentMessage.getDisplayMessageBody(); 
        try { 
         if (senderNum.contains("MOB_NUMBER")) { 
          Toast.makeText(context,"",Toast.LENGTH_SHORT).show(); 

          Intent intentCall = new Intent(context, MainActivity.class); 
          intentCall.putExtra("message", currentMessage.getMessageBody()); 

          PendingIntent pendingIntent= PendingIntent.getActivity(context, 0, intentCall, PendingIntent.FLAG_UPDATE_CURRENT); 
          pendingIntent.send(); 
         } 
        } catch (Exception e) { 
        } 
       } 
      } 
     } catch (Exception e) { 
     } 
    } 
} 

清單:

<activity android:name=".MainActivity" 
      android:launchMode="singleTask"/> 
<receiver android:name=".SMSReciver"> 
      <intent-filter android:priority="1000"> 
       <action android:name="android.provider.Telephony.SMS_RECEIVED"/> 
      </intent-filter> 
     </receiver> 

onNewIntent:

@Override 
     protected void onNewIntent(Intent intent) { 
       super.onNewIntent(intent); 
       Toast.makeText(this, "onNewIntent", Toast.LENGTH_SHORT).show(); 

       onSMSReceived(intent.getStringExtra("message")); 

      } 

權限:

<uses-permission android:name="android.permission.RECEIVE_SMS" /> 
<uses-permission android:name="android.permission.READ_SMS" /> 
<uses-permission android:name="android.permission.SEND_SMS" />