Android BroadcastReceiver в действии
Я просто пробую этот небольшой образец проекта, все, что он делает:
В первой операции есть кнопка, которая отправляет трансляцию. Вторая операция показывает тост, когда он получен.
Ниже приведен код, широковещательная передача не получена. Что я делаю неправильно?
Отправка трансляции
public class SendBroadcast extends Activity {
public static String BROADCAST_ACTION = "com.unitedcoders.android.broadcasttest.SHOWTOAST";
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
}
public void sendBroadcast(View v){
Intent broadcast = new Intent();
broadcast.setAction(BROADCAST_ACTION);
sendBroadcast(broadcast);
}
}
Получение
public class ToastDisplay extends Activity {
private BroadcastReceiver receiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
Toast.makeText(getApplicationContext(), "received", Toast.LENGTH_SHORT);
}
};
@Override
protected void onResume() {
IntentFilter filter = new IntentFilter();
filter.addAction(SendBroadcast.BROADCAST_ACTION);
registerReceiver(receiver, filter);
super.onResume();
}
@Override
protected void onPause() {
unregisterReceiver(receiver);
super.onPause();
}
}
манифеста
<application android:icon="@drawable/icon" android:label="@string/app_name">
<activity android:name=".SendBroadcast" android:label="@string/app_name">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity android:name=".ToastDisplay">
<intent-filter>
<action android:name="com.unitedcoders.android.broadcasttest.SHOWTOAST"></action>
</intent-filter>
</activity>
</application>
Ответы
Ответ 1
Что я делаю неправильно?
Исходный код ToastDisplay в порядке (мой аналогичен и работает), но он получит только что-то, если он в настоящее время находится на переднем плане (вы регистрируете приемник в onResume). Но он ничего не может получить, если отображается другое действие (в данном случае действие SendBroadcast).
Вместо этого вы, вероятно, захотите startActivity ToastDisplay из первого действия?
BroadcastReceiver и Activity имеют смысл в другом варианте использования. В моем приложении мне нужно получать уведомления из службы отслеживания GPS и показывать их в действии (если действие находится на переднем плане).
Нет необходимости регистрировать получателя в манифесте. Это было бы даже вредоносным в моем случае использования - мой приемник манипулирует пользовательским интерфейсом действия, и пользовательский интерфейс не будет доступен во время onReceive, если активность в настоящее время не отображается. Вместо этого я регистрирую и отменю регистрацию получателя для активности в onResume и onPause, как описано в
Документация BroadcastReceiver:
Вы можете динамически зарегистрировать экземпляр этого класса с помощью Context.registerReceiver() или статически опубликовать реализацию через тег в вашем AndroidManifest.xml.
Ответ 2
Toast.makeText(getApplicationContext(), "received", Toast.LENGTH_SHORT);
делает тост, но не показывает его.
Вам нужно сделать Toast.makeText(getApplicationContext(), "received", Toast.LENGTH_SHORT).show();
Ответ 3
Вам необходимо определить приемник как класс в манифесте, и он получит намерение:
<application
....
<receiver android:name=".ToastReceiver">
<intent-filter>
<action android:name="com.unitedcoders.android.broadcasttest.SHOWTOAST"/>
</intent-filter>
</receiver>
</application>
И вам не нужно создавать класс вручную внутри ToastDisplay.
В коде, который вы указали, вы должны находиться внутри операции ToastDisplay, чтобы фактически получить намерение.
Ответ 4
Расширяет класс ToastDisplay с помощью BroadcastReceiver и регистрирует приемник в файле манифеста и не регистрирует ваш широковещательный приемник в onResume().
<application
....
<receiver android:name=".ToastDisplay">
<intent-filter>
<action android:name="com.unitedcoders.android.broadcasttest.SHOWTOAST"/>
</intent-filter>
</receiver>
</application>
если вы хотите зарегистрироваться в действии, затем зарегистрируйтесь в методе onCreate(), например:
onCreate(){
sentSmsBroadcastCome = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
Toast.makeText(context, "SMS SENT!!", Toast.LENGTH_SHORT).show();
}
};
IntentFilter filterSend = new IntentFilter();
filterSend.addAction("m.sent");
registerReceiver(sentSmsBroadcastCome, filterSend);
}
Ответ 5
Я думаю, ваша проблема в том, что вы отправляете трансляцию перед началом другой активности! поэтому другая деятельность ничего не получит.
- Лучшей практикой для тестирования кода является отправка трансляции из потока или из службы, чтобы активность была открыта, и ее зарегистрированный получатель и фоновый процесс отправили сообщение.
- запустите действие ToastDisplay из активности отправителя (я не тестировал это, но может работать)
Ответ 6
Вы забываете написать .show() в конце, который используется для отображения тоста.
Toast.makeText(getApplicationContext(), "received", Toast.LENGTH_SHORT).show();
Это распространенная ошибка, которую программист делает, но я уверен, что после этого вы больше не повторите ошибку...: D
Ответ 7
Также вам необходимо зарегистрировать приемник в onCreate(), например:
IntentFilter filter = new IntentFilter();
filter.addAction("csinald.meg");
registerReceiver(receiver, filter);