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.
- Correcta / mejor manera de manejar el problema de la transacción de fragmentos Android
- "Error: no se puede encontrar la variable de símbolo xml" al intentar google analytics
- Clase AutoCompleteTextView & Async
- Llamando super en extremo
- Comunicación multihilo: ¿qué tan bueno es el uso de variables atómicas como AtomicInteger? ¿Por qué no hay AtomicFloat?
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ó
- Cómo convertir un entero de color a un hex en String en Android?
- Cómo cambiar el nombre de un proyecto en Android Studio
- Android - convertir la cadena de certificados pkcs12 al objeto de certificado x509 para bks keystore
- Cómo afilar una imagen en Android?
- GreenBroot EventBus no pudo enviar el evento
- Función de devolución de llamada de Bluetooth onCharacteristicRead no está realizando llamada de intención a otra actividad Trabajar con <API21. Restaurantes en Marshmallow
- ¿Cuál es el propósito de un patrón de delegación?
- El temporizador Android llega tarde cuando la pantalla del teléfono está bloqueada
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.