Android BroadcastReceiver в действии - программирование
Подтвердить что ты не робот

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>
4b9b3361

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