Проблема в понимании широковещательного приемника

#android #multithreading #broadcastreceiver #broadcast

#Android #многопоточность #broadcastreceiver #широковещательный

Вопрос:

У меня есть приложение, в котором я пытаюсь определить, КОГДА появляется подключение к Интернету и когда оно исчезает.

В тот момент, когда он появляется, я запускаю новый поток (отличный от пользовательского интерфейса), который соединяет мое приложение с удаленным сервером.

Для этого я вряд ли пытаюсь реализовать широковещательный приемник, который прослушивает подключение, но у меня возникают проблемы с пониманием концепции.

В моем onCreate() у меня есть что-то вроде:

 onCreate()    
{
     cThread = new Thread(new ClientThread(syncToken));
     cThread.start();
}
  

Когда есть подключение к Интернету, я отправляю данные через сокет, когда нет, я сохраняю данные в базе данных. И когда появляется Интернет, я перезапускаю свой поток, чтобы повторно подключиться и отправить старые данные (которые не были отправлены из-за сбоя сети) и новые.

Допустим, я бы реализовал что-то вроде этого:

 DoRefreshBroadcastReceiver refreshBroadcastReceiver; 
...    
onResume() {    
  // register the refreshing complete broadcast receiver    
  IntentFilter intentFilter = new IntentFilter(DO_REFRESH);    
  refreshBroadcastReceiver = new doRefreshBroadcastReceiver();    
  registerReceiver(refreshBroadcastReceiver, intentFilter);        
}

public class DoRefreshBroadcastReceiver extends BroadcastReceiver {     
    @Override
    public void onReceive(Context context, Intent intent) {    
        // call method to run fetch code...
    }
} 
  

Означает ли это, что при обнаружении подключения к Интернету вызывается мой onReceive() ? И я мог бы начать свой поток там?

Какова концепция использования намерения? Потому что я действительно этого не понимаю. Как его использовать и какова его цель?


ИДЕЯ: я действительно не знаю, как использовать это намерение в этом случае или как использовать его в моем приложении!

Будет ли эта штука обнаруживать подключение к Интернету, даже если я не участвую в этой деятельности?


Редактировать:

Вот как выглядит мой onReceive:


 onCreate()
{
    cThread = new Thread(new ClientThread(syncToken));
    // cThread.start();

    connIntentFilter = new IntentFilter(
                             "android.net.conn.CONNECTIVITY_CHANGE");
    connListener = new MyConnectivityListener();
}
  

 public void onReceive(Context context, Intent intent)
{
    mNetworkInfo = (NetworkInfo) intent
            .getParcelableExtra(ConnectivityManager.EXTRA_NETWORK_INFO);

    if (mNetworkInfo != null amp;amp; mNetworkInfo.isConnected())
    {
        /*
         * if(mNetworkInfo.getType()==ConnectivityManager.TYPE_WIFI);
         *
         *
         * else
         */

        cThread.start();
    }

    else {
        System.out.println("There is no internet connection!");

        try {
            cThread.stop();
        }
        catch (Exception e) {
            e.printStackTrace();
        }
    }
}
  

 mNetworkInfo != null amp;amp; mNetworkInfo.isConnected()    
  

Означает ли это, что он подключен, или я должен проверить определенный тип соединения в эмуляторе?

* Я думаю, что я должен запустить свой поток непосредственно в onReceive() . Как только мое приложение запускается, оно обнаруживает подключение к Интернету и BroadcastReceiver запускается, не так ли?

Комментарии:

1. Я прошу слишком многого?

Ответ №1:

Попробуйте что-то вроде этого…

 public class MyActivity extends Activity {

    private MyConnectivityListener connListener = null;
    private IntentFiler connIntentFilter = null;
    private Boolean connIntentFilterIsRegistered = false;

    @Override
    protected void onCreate(...) {
        ...
        connIntentFilter = new IntentFilter("android.net.conn.CONNECTIVITY_CHANGE");
        connListener = new MyConnectivityListener();
    }

    @Override
    protected void onResume() {
        ...
        if (!connIntentFilterIsRegistered) {
            registerReceiver(connListener, connIntentFilter);
            connIntentFilterIsRegistered = true;
        }
    }

    @Override
    protected void onPause() {
        ...
        if (connIntentFilterIsRegistered) {
            unregisterReceiver(connListener);
            connIntentFilterIsRegistered = false;
        }
    }

    protected class MyConnectivityListener extends BroadcastReceiver {

        @Override
        public void onReceive(Context context, Intent intent) {
            // The NetworkInfo for the affected network is sent
            // as an extra; it should be consulted to see what
            // kind of connectivity event occurred.
        }
    }
}
  

BroadcastReceiver фактически является «слушателем», который прослушивает события, отправленные системой или, в некоторых случаях, вашими собственными компонентами приложения.

В этом случае система осуществляет широковещательную передачу android.net.conn.CONNECTIVITY_CHANGE всякий раз, когда происходит изменение соединения (подключено / отключено). Зарегистрировав свой BroadcastReceiver для «прослушивания» этого события, вы можете получить extra включенное в намерение из onReceive(...) метода вашего BroadcastReceiver и сделать все, что вам нужно, соответственно. Дополнительный объект — это объект NetworkInfo, который будет содержать информацию о конкретной сети и о том, подключена она или нет.

Комментарии:

1. Если я помещу этот connIntentFilter = new IntentFilter («android.net.conn. CONNECTIVITY_CHANGE»); в моем onCreate () это та вещь, которая сообщает моей трансляции, когда изменяется состояние сети??? Мне не нужно что-то еще …? Во-вторых, в onReceive () я проверяю, что это за соединение … и если есть WiFi или что-то подобное, это означает, что я мог бы перезапустить свой поток … да ???….. И если подключен и все в порядке, могу ли я запустить свой поток в onReceive ()???? Или как работает эта часть перезапуска потока??? Спасибо, что еще немного прояснили ситуацию 🙂

2. @george: Бит в onCreate() предназначен просто для инициализации connIntentFilter именем «события», которое вы хотите прослушать. Затем вы передаете его registerReceiver(...) вместе с экземпляром вашего BroadcastReceiver. Регистрируясь, вы сообщаете системе, что хотите получать уведомления об изменении соединения. Проверив NetworkInfo в onReceive, вы можете определить, является ли «событие» подключением или разъединением, поэтому запустите / остановите свой поток соответствующим образом.

3. Не могли бы вы, пожалуйста, взглянуть на редактирование моего вопроса, несколько последних вопросов: D! Большое вам спасибо

4. @george: Я думаю, ты в значительной степени там. Чтобы ответить на один вопрос — нет, приемник не будет продолжать работать после того, как вы оставите свою активность, если вы реализуете код в моем примере для отмены регистрации приемника в onPause () (что рекомендуется). Если вам нужно, чтобы он работал постоянно, тогда все становится сложнее. Я предлагаю вам поэкспериментировать с ним в том виде, в каком он есть сейчас, и узнать больше о том, как работают BroadcastReceivers и Intent broadcasts.

5. Если я запускаю свое приложение и у меня есть подключение к Интернету, оно подключается к удаленному серверу, но если я удалю подключение к Интернету, оно не отобразит никакой System.out.println () ….. или не подключится повторно к моему удаленному серверу