Подтвердить что ты не робот

Android - Создать SMS из устаревшего API PDU?

Я хочу создать приложение, которое получает уведомление, когда приходит SMS и обрабатывает это SMS, но, читая ссылку для функции createFromPdu, она заявляет, что:

Этот метод скоро будет устаревшим, и все приложения, обрабатывающие входящие SMS-сообщения, обработав намерение трансляции SMS_RECEIVED_ACTION, теперь должны передать новый формат String дополнительно из намерения в новый метод createFromPdu (byte [], String), который принимает дополнительный формат. Это необходимо для правильного декодирования PDU на устройствах, которым требуется поддержка как 3GPP, так и 3GPP2 форматов одновременно, таких как телефоны с двумя режимами GSM/CDMA и CDMA/LTE.

Однако функция createFromPdu(byte[], String) отсутствует как в документации, так и в SDK.

Что мне делать? Мне нужно поддерживать эти двухмодовые телефоны с двумя SIM-картами.

4b9b3361

Ответ 1

Короче говоря, используйте это:

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

Ответ 2

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

Если вы хотите создать объект SmsMessage из pdu, вы можете использовать новый api

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

  SmsMessage sms2 = SmsMessage.createFromPdu(msgs[0].getPdu(),format);

Ответ 3

Вы не указываете, какую версию 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

Вместо того, чтобы использовать этот API напрямую, вы можете использовать API провайдера телефонии getMessagesFromIntent: http://grepcode.com/file/repository.grepcode.com/java/ext/com.google.android/android/4.1.2_r1/android/provider/Telephony.java/#686

Этот метод рассматривает формат PDU (и идентификатор подписки в Lollipop для устройств Multi SIM) и предоставляет массив экземпляров SmsMessage.

Пример того, как он используется, можно увидеть в приложении Google MMS:

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

Ответ 4

createFromPdu(byte[]) устарел из SDK_INT 23, поэтому вы должны использовать

createFromPdu((byte[]) , format);

вот мой код для получения входящих SMS

Я использую класс 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;
}

}

Ответ 5

извините за поздний ответ, но это может помочь в любом случае. кроме проверки версии Android, и если она выше М и извлекает формат пения. Я бы предложил использовать:

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 для извлечения SMS-сообщений (используя описанный выше метод), поскольку это длительная работа. Это может привести к сбою вашего приложения (в некоторых случаях), если оно выполняется в потоке пользовательского интерфейса.

Эта библиотека спасла мое время. Надеюсь, что он сделает то же самое с кем-то.