2011-08-17 52 views
127

Tôi đang cố gắng tạo một ứng dụng để theo dõi tin nhắn SMS đến và khởi chạy chương trình qua SMS đến, cũng nên đọc nội dung từ SMS.Android - Nghe tin nhắn SMS đến

Workflow:

SMS gửi đến điện thoại Android tự ứng dụng thực thi Đọc thông tin SMS

Nếu bất cứ ai có thể giúp tôi!

+1

Tôi biết tạo ứng dụng để gửi SMS, nhưng ở đây tôi cần tạo ứng dụng SMS nhận thông tin từ SMS và lưu vào Cơ sở dữ liệu SQLite ..... Làm cách nào để phát triển ứng dụng như vậy – iShader

+0

@iShader tôi hy vọng bạn đã thành công trong việc tạo ứng dụng, chỉ muốn biết làm cách nào bạn quản lý để đồng bộ hóa thông điệp b/w thiết bị và máy chủ –

+0

Kiểm tra blog này http://www.gadgetsaint.com/android/read -sms-messages-android/#. WLrJHRJ97fY – ASP

Trả lời

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()); 
       } 
      } 
     } 
    } 
} 

Lưu ý: Trong file manifest của bạn thêm BroadcastReceiver-

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

Thêm sự cho phép này:

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

Bạn có thể cho tôi biết lý do bạn sử dụng máy thu phụ không? – WindRider

+2

@VineetShukla bạn có thể vui lòng giải thích pdus là gì ?? –

+9

sử dụng Intents.SMS_RECEIVED_ACTION thay vì mã hóa cứng. –

52

Lưu ý rằng trên một số thiết bị mã của bạn sẽ không làm việc mà không android: priority = Bộ lọc ý định "1000":

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

Và đây là một số tối ưu:

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(); 
      } 
     } 
    } 
} 

Note:
Giá trị phải là một số nguyên, chẳng hạn như "100". Số cao hơn có mức độ ưu tiên cao hơn. Giá trị mặc định là 0. Giá trị phải lớn hơn -1000 và ít hơn 1000.

Here's a link.

+26

Câu trả lời này có thể thanh lịch hơn, nhưng yêu cầu API 19. Chỉ cần một FYI cho người khác. – baekacaek

+8

Theo [this] (http://developer.android.com/guide/topics/manifest/intent-filter-element.html), 'android: priority' không được cao hơn '1000' (hoặc nhỏ hơn' - 1000'). – craned

+2

Nó không hoạt động trên Xiaomi Redmi Note 3 Pro với Android 5.1. Mọi người đều cung cấp giải pháp này, nhưng nó dường như không có tác dụng với tôi. – Sermilion

4

@ Mike M. và tôi thấy một vấn đề với câu trả lời được chấp nhận (xem ý kiến ​​của chúng tôi):

về cơ bản, không có điểm nào trong trải qua các vòng lặp for nếu chúng ta không concatenating thông điệp nhiều phần dữ liệu mỗi lần:

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(); 
} 

Chú ý rằng chúng ta chỉ cần đặt msgBody đến chuỗi giá trị của các phần tương ứng của thông điệp không có vấn đề những gì chúng tôi đang trên chỉ mục, mà làm cho toàn bộ các điểm của looping thông qua các phần khác nhau của tin nhắn SMS vô dụng, vì nó sẽ chỉ được thiết lập để các giá trị chỉ số cuối cùng. Thay vào đó chúng ta nên sử dụng +=, hoặc như Mike ghi chú khác, StringBuilder:

Tất cả trong tất cả, đây là những gì SMS tôi nhận mã trông giống như:

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 
} 

Chỉ cần đặt câu trả lời này ngoài kia trong trường hợp bất cứ ai khác có cùng một sự nhầm lẫn.

1

Đây là những gì tôi đã sử dụng!

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

Trong trường hợp bạn muốn xử lý ý định về hoạt động mở ra, bạn có thể sử dụng PendintIntent (Hoàn thành các bước dưới đây):

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) { 
     } 
    } 
} 

manifest:

<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")); 

      } 

quyền:

<uses-permission android:name="android.permission.RECEIVE_SMS" /> 
<uses-permission android:name="android.permission.READ_SMS" /> 
<uses-permission android:name="android.permission.SEND_SMS" /> 
Các vấn đề liên quan