Прямо сейчас я могу получить смс со следующим кодом:
override fun onReceive(c: Context, i: Intent) {
val bundle = intent.extras
if (bundle != null && intent.action == SMS_RECEIVED) {
var currentMessage: SmsMessage
var msgs: Array<SmsMessage>? = null
var pdusObj: Array<Any>? = null
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
msgs = Telephony.Sms.Intents.getMessagesFromIntent(intent)
currentMessage = msgs!![0]
} else {
pdusObj = bundle.get("pdus") as Array<Any>
currentMessage = SmsMessage.createFromPdu(pdusObj[0] as ByteArray)
}
mPhoneNumb = currentMessage.displayOriginatingAddress
}
Мне интересно, могу ли я каким-либо образом сделать что-то обратное: создать намерение (с моим номером телефона и текстовым сообщением) для эмуляции входящих смс.
Есть какой-либо способ сделать это?
ОБНОВЛЕНИЕ:
благодаря MikeM найдите это решение: >Создайте PDU для Android, который работает с SmsMessage.createFromPdu() (GSM 3gpp)
но я все еще не могу отправить поддельное смс на свой широковещательный приемник, на этот раз я получаю вылет со следующей ошибкой:
SecurityException: Permission Denial: not allowed to send broadcast android.provider.Telephony.SMS_RECEIVED from pid=14860, uid=10621
но у меня уже есть это разрешение! вот мой манифест:
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.test.test">
<uses-permission android:name="android.permission.READ_SMS"/>
<uses-permission android:name="android.permission.RECEIVE_SMS"/>
<uses-permission android:name="android.permission.VIBRATE"/>
<application
android:label="@string/app_name"
android:theme="@style/AppTheme">
<activity
android:name=".MainActivity"
android:label="@string/app_name"
android:theme="@style/AppTheme.NoActionBar">
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity>
<receiver android:name=".receiver.SmsReceiver">
<intent-filter android:priority="1000">
<action android:name="android.provider.Telephony.SMS_RECEIVED"/>
</intent-filter>
</receiver>
</application>
</manifest>
и вот мой класс, который должен создавать и отправлять поддельные смс моему получателю:
public class SendTestSms {
public 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) {
e.printStackTrace();
}
pdu = bo.toByteArray();
} catch (IOException e) {
e.printStackTrace();
}
Intent intent = new Intent(context, SmsReceiver.class);
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.sendBroadcast(intent);
}
private static byte reverseByte(byte b) {
return (byte) ((b & 0xF0) >> 4 | (b & 0x0F) << 4);
}
}
есть идеи, почему мое разрешение не имеет значения для отправки трансляции?
Intent
иstartService()
на таргетингIntent
ваш приемник и вызовsendBroadcast()
. Однако есть и другие способы проверки вашего приемника, если это все, что вы пытаетесь сделать. В эмуляторе вы можете использовать telnet или отправить от одного к другому или использовать встроенный инструмент. - person Mike M.   schedule 02.02.2017SMS_RECEIVED
; вы можете только получить его. Вот почему вы можете настроить таргетинг только на свой Receiver. Вам придется удалить вызовsetAction()
или изменить действие на что-то другое. И удалитьsetClassName()
тоже. На самом деле это не очень хороший тест, поскольку единственное, что вы действительно проверяете, это то, можете ли вы создавать и декодировать PDU. Вот почему я упомянул это в первую очередь. :-) - person Mike M.   schedule 04.02.2017