Crear PDU para Android que funciona con SmsMessage.createFromPdu () (GSM 3gpp)

Objetivo: (NOTA: La respuesta seleccionada genera una PDU GSM (3gpp) para CDMA (3gpp2).

Para crear una PDU que se puede pasar a SmsMessage.createFromPdu(byte[] pdu) . Estoy "transmitiendo una intención" a uno de mis BroadcastReciever que escucha mensajes SMS.

One BroadcastReciever

Uso de android.provider.Telephony.SMS_RECEIVED para SMS "reales"

Uso de una acción de intent-filter personalizada para estos nuevos "SMS de aplicación" .

 @Override public void onReceive(Context context, Intent intent) { Bundle bundle = intent.getExtras(); if (bundle != null) { Object[] pdusObj = (Object[]) bundle.get("pdus"); SmsMessage[] messages = new SmsMessage[pdusObj.length]; // getting SMS information from Pdu. for (int i = 0; i < pdusObj.length; i++) { messages[i] = SmsMessage.createFromPdu((byte[]) pdusObj[i]); } for (SmsMessage currentMessage : messages) { //the currentMessage.getDisplayOriginatingAddress() //or .getDisplayMessageBody() is null if I Broadcast a fake sms Log.i("BB", "address:"+currentMessage.getDisplayOriginatingAddress()+" message:"+currentMessage.getDisplayMessageBody()); ... 

Así que quiero que mi BroadcastReciever sea ​​capaz de manejar ambos tipos de mensajes sin agregar código extra

(Sí sé que puedo tener un diferente BroadcastReciever para la acción diferente intent-filter pero me gustaría realmente sacar esto como sé que se puede hacer, soy terco)

Investigación:

He estado haciendo la investigación todo el día / noche. He intentado escribir mis propios, aunque soy muy terrible con las matemáticas y las conversiones y la creación de un algoritmo adecuado. He mirado sobre temas de pila en PDUs , y crear PDU Android, pero el enlace está roto en la respuesta. Incluso he com.google.android.mms.pdu código fuente de com.google.android.mms.pdu

Hasta ahora sólo he sido capaz de crear una PDU sin una " dirección de origen " utilizando algún código de http://www.wrankl.de/JavaPC/SMSTools.html

PDU:

Destino: 555 mensaje: helloworld

 "1100038155f50000aa0ae8329bfdbebfe56c32" 

Lo cual obviamente no es válido …

Notas laterales:

No pienso hacer nada con la PDU además del uso local, no quiero PDU codificado en mi código porque no estoy reutilizando la PDU.

Si hay algo que puedo agregar al código que estoy usando para agregar en una "dirección de origen" , que funcionará. ¿O alguien tiene información sobre una biblioteca que no conozco?

Gracias

Actualizaciones:

intentó

 byte[] by =(byte[])(SmsMessage.getSubmitPdu("12345", "1234", "hello", false).encodedMessage); 

Que me da lo siguiente (en representación hexadecimal)

 "0000100200000000000000000000000004010203040000000e000320ec400107102e8cbb366f00" 

No funcionó

Tal vez este fragmento no tiene muchos campos de detalle como desea, pero para mi propósito simple puede invocar notificación como otro sms.

  private static void createFakeSms(Context context, String sender, String body) { byte[] pdu = null; byte[] scBytes = PhoneNumberUtils .networkPortionToCalledPartyBCD("0000000000"); byte[] senderBytes = PhoneNumberUtils .networkPortionToCalledPartyBCD(sender); int lsmcs = scBytes.length; byte[] dateBytes = new byte[7]; Calendar calendar = new GregorianCalendar(); dateBytes[0] = reverseByte((byte) (calendar.get(Calendar.YEAR))); dateBytes[1] = reverseByte((byte) (calendar.get(Calendar.MONTH) + 1)); dateBytes[2] = reverseByte((byte) (calendar.get(Calendar.DAY_OF_MONTH))); dateBytes[3] = reverseByte((byte) (calendar.get(Calendar.HOUR_OF_DAY))); dateBytes[4] = reverseByte((byte) (calendar.get(Calendar.MINUTE))); dateBytes[5] = reverseByte((byte) (calendar.get(Calendar.SECOND))); dateBytes[6] = reverseByte((byte) ((calendar.get(Calendar.ZONE_OFFSET) + calendar .get(Calendar.DST_OFFSET)) / (60 * 1000 * 15))); try { ByteArrayOutputStream bo = new ByteArrayOutputStream(); bo.write(lsmcs); bo.write(scBytes); bo.write(0x04); bo.write((byte) sender.length()); bo.write(senderBytes); bo.write(0x00); bo.write(0x00); // encoding: 0 for default 7bit bo.write(dateBytes); try { String sReflectedClassName = "com.android.internal.telephony.GsmAlphabet"; Class cReflectedNFCExtras = Class.forName(sReflectedClassName); Method stringToGsm7BitPacked = cReflectedNFCExtras.getMethod( "stringToGsm7BitPacked", new Class[] { String.class }); stringToGsm7BitPacked.setAccessible(true); byte[] bodybytes = (byte[]) stringToGsm7BitPacked.invoke(null, body); bo.write(bodybytes); } catch (Exception e) { } pdu = bo.toByteArray(); } catch (IOException e) { } Intent intent = new Intent(); intent.setClassName("com.android.mms", "com.android.mms.transaction.SmsReceiverService"); intent.setAction("android.provider.Telephony.SMS_RECEIVED"); intent.putExtra("pdus", new Object[] { pdu }); intent.putExtra("format", "3gpp"); context.startService(intent); } private static byte reverseByte(byte b) { return (byte) ((b & 0xF0) >> 4 | (b & 0x0F) << 4); } 

Espero que encuentres algo útil

Actualización:

  public static final SmsMessage[] getMessagesFromIntent( Intent intent) { Object[] messages = (Object[]) intent.getSerializableExtra("pdus"); byte[][] pduObjs = new byte[messages.length][]; for (int i = 0; i < messages.length; i++) { pduObjs[i] = (byte[]) messages[i]; } byte[][] pdus = new byte[pduObjs.length][]; int pduCount = pdus.length; SmsMessage[] msgs = new SmsMessage[pduCount]; for (int i = 0; i < pduCount; i++) { pdus[i] = pduObjs[i]; msgs[i] = SmsMessage.createFromPdu(pdus[i]); } return msgs; } 

Ha pasado mucho tiempo desde que he hecho cualquier discusión directa de PDU, pero cuando lo hice rápidamente me di por vencido y usé SMSLib : las utilidades PDU ha funcionado perfectamente para enviar a través de teléfonos Nokia (a través de un enlace serial). Mi suposición (que puede estar equivocada) es que van a trabajar para Android también, suponiendo que la interfaz es en realidad compatible con la especificación.

Compruebe este código en console.c . Aquí es donde el emulador android crea el pdu y RIL.java donde el mensaje CMT se convierte en un SmsMessage. Puede utilizar SmsMessage.getPdu para obtener el pdu. Pero SmsMessage.newFromCmt parece ser una api interna. Así que puede que no sea fiable.

Además esto es sólo para Gsm, cdma tiene un flujo de código completamente diferente y ya que RIL.java y el módem son completamente específicos del fabricante, esto sólo podría funcionar en el emulador.

Por lo general, el código GSM es más confiable en android, por lo que también podría trabajar en el teléfono GSM. No dale una oportunidad.

  • Acceso a R.java desde diferentes paquetes
  • ¿Cómo cambiar el valor de una variable local dentro de una clase interna?
  • ¿Cómo puedo verificar los datos firmados que vienen para la aplicación de facturación de Android Market utilizando Java (Servlet)
  • Cargando muchas imágenes del servidor en Android
  • Android Tutorial REST / Proyecto de ejemplo
  • Error de inicio de sesión y registro de la aplicación de Android
  • Cómo alinear mediante programación un Android TextView a la derecha de otro TextView
  • Error "no se pudo obtener wglGetExtensionsStringARB"
  • Generar una suma md5 desde un objeto Bitmap de Android
  • Guardar datos de usuario durante un día (el mismo día -> muchos datos de usuario)
  • ¿Cómo comprobar con gracia si un recurso bruto no existe?
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.