Ответ 1
Вам также необходимо указать использование-разрешение в файле манифеста:
<uses-permission android:name="android.permission.RECEIVE_SMS"/>
Следующие руководства помогут:
Я хочу, чтобы мое приложение поймало входящие SMS-сообщения. Есть несколько примеров этого. Похоже, нам просто нужно это сделать:
// AndroidManifest.xml
<receiver android:name=".SMSReceiver">
<intent-filter>
<action android:name="android.provider.Telephony.SMS_RECEIVED" />
</intent-filter>
</receiver>
// SMSReceiver.java
public class SMSReceiver extends BroadcastReceiver
{
@Override
public void onReceive(Context context, Intent intent) {
Log.i(TAG, "SMS received.");
....
}
}
Это правильно? Я отправляю свой телефон на некоторые sms-сообщения, но оператор журнала никогда не печатается. У меня есть некоторые другие SMS-приложения, установленные на телефоне, которые отображают всплывающее окно при получении sms - они каким-то образом блокируют намерение получить доступ к моему приложению, они просто поглощают его полностью?
Спасибо
Вам также необходимо указать использование-разрешение в файле манифеста:
<uses-permission android:name="android.permission.RECEIVE_SMS"/>
Следующие руководства помогут:
Еще одна вещь, о которой эти ответы не упомянуты, - вы должны потребовать разрешение android.permission.BROADCAST_SMS. Если вы этого не сделаете, любое приложение может обманывать сообщения в вашем приложении.
<receiver android:name=".SMSReceiver"
android:exported="true"
android:permission="android.permission.BROADCAST_SMS">
<intent-filter>
<action android:name="android.provider.Telephony.SMS_RECEIVED"/>
</intent-filter>
</receiver>
В пути есть несколько ошибок. Вы можете найти всю необходимую информацию о stackoverflow. Для удобства я собрал всю информацию в этом ответе.
"android.provider.Telephony.SMS_RECEIVED"
"android.permission.RECEIVE_SMS"
в манифесте xml, чтобы получать sms-сообщения. В android 6 и выше вам также необходимо запросить разрешение во время выполнения.adb shell am broadcast
не будет работать. Используйте telnet-соединение с симулятором для проверки получения sms.Самое главное - иметь возможность отправлять фальшивые sms-сообщения на устройство, поэтому мы можем протестировать код.
Для этого мы будем использовать виртуальное устройство и telnet-соединение с ним.
Теперь подключитесь к номеру порта, указанному в строке заголовка симулятора, с помощью telnet
$ telnet localhost 5554
Если вы видите это: Android Console: Authentication required
, вам необходимо аутентифицировать соединение с помощью этой команды:
auth xxxxxx
Замените xxxxxx
выше маркером, читаемым из файла ~/.emulator_console_auth_token
.
Теперь вы должны иметь возможность запускать все команды. Чтобы отправить sms-сообщение, введите следующую команду:
sms send 555 "This is a message"
Если вы можете заменить 555 на номер телефона отправителя и собственное сообщение.
Чтобы получить трансляции, вам необходимо зарегистрировать объект BroadcastReceiver
. Вы можете сделать это в функции manifest.xml ИЛИ только для вызова registerReceiver
. Я покажу вам последнее, поскольку легче рассуждать и все же более гибко.
Подключение широковещательного приемника к основной активности
Поток данных является одним из способов. От широковещательного приемника до основного действия. Поэтому самый простой способ заставить их говорить - использовать функциональный интерфейс. Эта функция будет выполнять такую функцию, и широковещательный приемник будет иметь экземпляр активности, переданный в качестве параметра в конструкторе.
Файл SmsHandler.java:
package ...
interface SmsHandler {
void handleSms(String sender, String message);
}
Реализация широковещательного приемника
Радиовещательный приемник получит намерение в обратном вызове. Мы будем использовать функцию Telephony.Sms.Intents.getMessagesFromIntent(intent)
для получения sms-сообщений. Обратите внимание на параметр SmsHandler в конструкторе. Это будет активность, на которую мы отправим полученные sms.
Файл SmsInterceptor.java:
package ...
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.provider.Telephony;
import android.telephony.SmsMessage;
public class SmsInterceptor extends BroadcastReceiver {
private SmsHandler handler;
/* Constructor. Handler is the activity *
* which will show the messages to user. */
public SmsInterceptor(SmsHandler handler) {
this.handler = handler;
}
@Override
public void onReceive(Context context, Intent intent) {
/* Retrieve the sms message chunks from the intent */
SmsMessage[] rawSmsChunks;
try {
rawSmsChunks = Telephony.Sms.Intents.getMessagesFromIntent(intent);
} catch (NullPointerException ignored) { return; }
/* Gather all sms chunks for each sender separately */
Map<String, StringBuilder> sendersMap = new HashMap<>();
for (SmsMessage rawSmsChunk : rawSmsChunks) {
if (rawSmsChunk != null) {
String sender = rawSmsChunk.getDisplayOriginatingAddress();
String smsChunk = rawSmsChunk.getDisplayMessageBody();
StringBuilder smsBuilder;
if ( ! sendersMap.containsKey(sender) ) {
/* For each new sender create a separate StringBuilder */
smsBuilder = new StringBuilder();
sendersMap.put(sender, smsBuilder);
} else {
/* Sender already in map. Retrieve the StringBuilder */
smsBuilder = sendersMap.get(sender);
}
/* Add the sms chunk to the string builder */
smsBuilder.append(smsChunk);
}
}
/* Loop over every sms thread and concatenate the sms chunks to one piece */
for ( Map.Entry<String, StringBuilder> smsThread : sendersMap.entrySet() ) {
String sender = smsThread.getKey();
StringBuilder smsBuilder = smsThread.getValue();
String message = smsBuilder.toString();
handler.handleSms(sender, message);
}
}
}
Основное действие
Наконец, нам нужно реализовать интерфейс SmsHandler в основной активности и добавить регистрацию широковещательного приемника и проверку разрешения на функцию onCreate
.
Файл MainActivity.java:
package ...
import ...
public class MainActivity extends AppCompatActivity implements SmsHandler {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
/* Register the broadcast receiver */
registerSmsListener();
/* Make sure, we have the permissions */
requestSmsPermission();
}
/* This function will be called by the broadcast receiver */
@Override
public void handleSms(String sender, String message) {
/* Here you can display the message to the user */
}
private void registerSmsListener() {
IntentFilter filter = new IntentFilter();
filter.addAction("android.provider.Telephony.SMS_RECEIVED");
/* filter.setPriority(999); This is optional. */
SmsInterceptor receiver = new SmsInterceptor(this);
registerReceiver(receiver, filter);
}
private void requestSmsPermission() {
String permission = Manifest.permission.RECEIVE_SMS;
int grant = ContextCompat.checkSelfPermission(this, permission);
if ( grant != PackageManager.PERMISSION_GRANTED) {
String[] permission_list = new String[1];
permission_list[0] = permission;
ActivityCompat.requestPermissions(this, permission_list, 1);
}
}
}
Наконец, не забудьте добавить разрешение RECEIVE_SMS в ваш манифест xml
<?xml version="1.0" encoding="utf-8"?>
<manifest ...>
<uses-permission android:name="android.permission.RECEIVE_SMS"/>
<application>
...
</application>
</manifest>
Также обратите внимание, что приложение Hangouts в настоящее время блокирует мой BroadcastReceiver от получения SMS-сообщений. Мне пришлось отключить функциональность SMS в приложении Hangouts (Настройки- > SMS- > Включить SMS-сообщение), прежде чем мой SMS BroadcastReceived начнет увольняться.
Изменить: Похоже, что некоторые приложения будут прерватьBroadcast() в намерении, которое не позволит другим приложениям получать намерение. Решение состоит в том, чтобы увеличить атрибут android:priority
в теге intent-filter
:
<receiver android:name="com.company.application.SMSBroadcastReceiver" >
<intent-filter android:priority="500">
<action android:name="android.provider.Telephony.SMS_RECEIVED" />
</intent-filter>
</receiver>
Подробнее см. здесь: Включение поддержки SMS в Hangouts 2.0 нарушает BroadcastReceiver SMS_RECEIVED в моем приложении
Пробовал ли вы emulator?
После развертывания вашего приложения в эмуляторе вы можете отправлять события, такие как SMS, через DDMS или через командную строку, подключившись к telnet:
telnet localhost <port_emulator>
send sms <incoming_tel_number> <sms_content>
port_emulator обычно 5554
Вы должны прочитать эту статью о том, чтобы отправить и получить смс программно. http://mobiforge.com/developing/story/sms-messaging-android
Android Messenger (клиент SMS) имеет функцию "Чат", которая передает сообщения по WiFi вместо SMS.
Если человек, с которым вы тестируете, также использует Messenger, вам нужно отключить эту функцию на одном или обоих ваших устройствах, в противном случае SMS-сообщение фактически не принимается:
Чтобы отключить функции чата:
- Открытые сообщения Сообщения Логотип Круглый.
- Нажмите Еще, а затем Настройки.
- Нажмите "Дополнительно", а затем выберите "Функции чата".
- Включите или отключите функцию чата.