Android

Create PDU for Android that works with SmsMessage.createFromPdu() (GSM 3gpp)

Создание PDU для Android, работающего с SmsMessage.createFromPdu() (GSM 3gpp)

Цель: (ПРИМЕЧАНИЕ: выбранный ответ генерирует PDU GSM (3gpp)) для CDMA (3gpp2), пожалуйста, обратитесь сюда

Чтобы создать PDU, в который можно передавать SmsMessage.createFromPdu(byte[] pdu). Я "Транслирую намерение" одному из моихBroadcastReciever, который прослушивает SMS-сообщения.

Один BroadcastReciever

Использование android.provider.Telephony.SMS_RECEIVED для "реальных" SMS

Использование пользовательского intent-filter действия для этих новых "SMS-сообщений приложения".

@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());
...

Итак, я хочу, чтобы мой BroadcastReciever мог обрабатывать оба типа сообщений без добавления дополнительного кода

(да, я знаю, что у меня может быть другое BroadcastReciever для другого intent-filter действия, но я хотел бы на самом деле осуществить это, поскольку я знаю, что это можно сделать, я упрямый)

Исследования:

Я занимался исследованиями весь день и ночь. Я пытался написать свой собственный, хотя я очень плохо разбираюсь в математике и преобразованиях и создаю подходящий алгоритм. Я просмотрел разделы Stack о PDU и Создание PDU Android, но ссылка в ответе не работает. Я даже посмотрел на com.google.android.mms.pdu исходный код

пока мне удалось создать PDU только без "исходного адреса", используя некоторый код из http://www.wrankl.de/JavaPC/SMSTools.html

PDU:

назначение: 555 сообщение: helloworld

"1100038155f50000aa0ae8329bfdbebfe56c32"

Что, очевидно, недопустимо...

Дополнительные примечания:

Я не планирую ничего делать с PDU, кроме локального использования, я не хочу жестко закодированных PDU в моем коде, потому что я не использую PDU повторно.

Если есть что-то, что я могу добавить к коду, который я использую для добавления в "исходный адрес", это сработает. Или у кого-нибудь есть информация о библиотеке, о которой я не знаю?

Спасибо

Обновления:

пробовал

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

который дает мне следующее (в шестнадцатеричном представлении)

"0000100200000000000000000000000004010203040000000e000320ec400107102e8cbb366f00"

не сработало

Переведено автоматически
Ответ 1

Возможно, в этом фрагменте не так много полей сведений, как вы хотите, но для моей простой цели он может вызывать уведомление, как другое 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);
}

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;
}
Ответ 2

Прошло много времени с тех пор, как я выполнял какие-либо прямые операции с PDU, но когда я это сделал, я быстро сдался и использовал SMSLib: утилиты PDU, которые он отлично использовал для отправки через телефоны Nokia (по последовательной ссылке). Мое предположение (которое может быть неверным) заключается в том, что они будут работать и для Android, предполагая, что интерфейс действительно соответствует спецификации.

Ответ 3

Проверьте этот код в console.c. Здесь эмулятор Android создает pdu и RIL.java где сообщение CMT преобразуется в SmsMessage. Вы можете использовать SmsMessage.getPdu для получения pdu. Но SmsMessage.newFromCmt похоже, что это внутренний API. Так что это может быть ненадежно.

Далее, это только для Gsm, cdma имеет совершенно другой поток кодов, и поскольку RIL.java и модем полностью зависят от производителя, это может работать только на эмуляторе.

Обычно GSM-код более надежен на Android, поэтому может также работать на телефоне gsm. Попробуйте.

java android