26

我想创建一个应用程序,当 SMS 到达并处理该 SMS 时收到通知,但是阅读createFromPdu函数的参考,它指出:

此方法很快将被弃用,所有通过处理 SMS_RECEIVED_ACTION 广播意图来处理传入 SMS 消息的应用程序现在必须将新格式 String extra 从意图传递到新方法 createFromPdu(byte[], String) ,该方法采用额外的格式参数。为了在需要同时支持 3GPP 和 3GPP2 格式的设备(例如双模 GSM/CDMA 和 CDMA/LTE 手机)上正确解码 PDU,这是必需的。

但是,createFromPdu(byte[], String)文档和 SDK 中都缺少该功能。

我应该怎么办?我需要支持这些双卡双模手机。

4

5 回答 5

28

简而言之,使用这个:

SmsMessage smsMessage;

if (Build.VERSION.SDK_INT >= 19) { //KITKAT         
    SmsMessage[] msgs = Telephony.Sms.Intents.getMessagesFromIntent(intent);              
    smsMessage = msgs[0];            
} else {             
    Object pdus[] = (Object[]) bundle.get("pdus");             
    smsMessage = SmsMessage.createFromPdu((byte[]) pdus[0]);          
}
于 2015-08-04T18:12:19.753 回答
5
    public void onReceive(Context context, Intent intent) {
        SmsMessage[] msgs = Telephony.Sms.Intents.getMessagesFromIntent(intent);
        String format = intent.getStringExtra("format");


        SmsMessage sms = msgs[0];
        Log.v("TAG", "handleSmsReceived" + (sms.isReplace() ? "(replace)" : "") +
                " messageUri: " +
                ", address: " + sms.getOriginatingAddress() +
                ", body: " + sms.getMessageBody());

        String message = sms.getMessageBody();
}

如果你想从 pdu 创建 SmsMessage 对象,你可以使用新的 api

http://developer.android.com/reference/android/telephony/SmsMessage.html#createFromPdu(byte[], java.lang.String)

  SmsMessage sms2 = SmsMessage.createFromPdu(msgs[0].getPdu(),format);
于 2015-12-17T08:58:12.703 回答
2

您没有提及您的目标是哪个 Android 版本,但考虑到我假设 Jelly Bean 4.x 的问题日期。

在写这篇文章的时候,我们在 Lollipop MR1,关于使用带有格式参数的 createFromPdu 的弃用说明仍然存在:

https://android.googlesource.com/platform/frameworks/opt/telephony/+/android-5.1.0_r3/src/java/android/telephony/SmsMessage.java

但是,您可以使用 Telephony 提供程序 API,而不是直接使用该 API :http getMessagesFromIntent: //grepcode.com/file/repository.grepcode.com/java/ext/com.google.android/android/4.1.2_r1/android/提供者/Telephony.java/#686

该方法考虑了 PDU 格式(以及 Lollipop 中用于多 SIM 设备的订阅 ID),并为您提供了一组 SmsMessage 实例。

在 Google 的 MMS 应用中可以看到如何使用它的示例:

https://android.googlesource.com/platform/packages/apps/Mms/+/master/src/com/android/mms/transaction/SmsReceiverService.java(见handleSmsReceived

于 2015-04-08T20:58:46.340 回答
2

createFromPdu(byte[])已从 SDK_INT 23 弃用,因此您必须使用

createFromPdu((byte[]) , format);

这是我获取传入短信的代码

我使用SMSReceiver类作为一个内部类Activity

这是我的工作代码

public class SamplaActivity extends BaseActivity {
    SMSReceiver otp;
    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_splash);

        otp=new SMSReceiver();


........
........
    }

  @Override
    protected void onResume() {
        super.onResume();

//        register broadcast receiver
        IntentFilter filter = new IntentFilter();
        filter.addAction("android.provider.Telephony.SMS_RECEIVED");
        registerReceiver(otp, filter);
    }
@Override
    protected void onPause() {
        super.onPause();
        unregisterReceiver(otp);
    }

    private class SMSReceiver extends BroadcastReceiver {
        private Bundle bundle;
        private SmsMessage currentSMS;
        private String message;

        @Override
        public void onReceive(Context context, Intent intent) {

            if (intent.getAction().equals("android.provider.Telephony.SMS_RECEIVED")) {
                bundle = intent.getExtras();
                if (bundle != null) {
                    Object[] pdu_Objects = (Object[]) bundle.get("pdus");
                    if (pdu_Objects != null) {

                        for (Object aObject : pdu_Objects) {

                            currentSMS = getIncomingMessage(aObject, bundle);

                            String senderNo = currentSMS.getDisplayOriginatingAddress();

                            message = currentSMS.getDisplayMessageBody();
                            Toast.makeText(OtpActivity.this, "senderNum: " + senderNo + " :\n message: " + message, Toast.LENGTH_LONG).show();
                        }
                        this.abortBroadcast();
                        // End of loop
                    }
                }
            } // bundle null
        }
    }

private SmsMessage getIncomingMessage(Object aObject, Bundle bundle) {
    SmsMessage currentSMS;
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
        String format = bundle.getString("format");
        currentSMS = SmsMessage.createFromPdu((byte[]) aObject, format);
    } else {
        currentSMS = SmsMessage.createFromPdu((byte[]) aObject);
    }

    return currentSMS;
}

}
于 2016-06-27T10:28:03.313 回答
0

抱歉回复晚了,但无论如何它可能会有所帮助。除了检查 android 版本,如果它高于 M 并提取 sing 格式。我建议使用:

compile 'me.everything:providers-android:1.0.1'

显现

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

在你的代码中

public List<Sms> mySmses(Context context)throws Exception{
    TelephonyProvider telephonyProvider = new TelephonyProvider(context);
    List<Sms> smses = telephonyProvider.getSms(TelephonyProvider.Filter.INBOX).getList();
    if(smses.isEmpty()){
        throw new Exception("No SMS found");
    }
    return smses;
}

请记住使用 AsyncTask 来获取 SMSes(使用上述方法),因为这是一个长时间运行的操作。如果它在 UI 线程上执行,它可能会导致您的应用程序崩溃(在某些情况下)。

这个图书馆节省了我的时间。希望它会对某人做同样的事情。

于 2017-12-11T23:22:29.337 回答