BroadcastReceiver检测到Internet连接或断开连接的问题

时间:2017-10-30 09:34:08

标签: android broadcastreceiver intentfilter connection-leaks

目标是在我的Android应用程序中实现 BroadcastReceiver ,动态检测设备何时更改其连接或断开Internet的状态。我尝试了几个教程和解决方案提案,但我仍然没有设法让它正常工作,我总是得到同样的结果:" 泄露了IntentReceiver "错误。

相关代码是:  首先,我编写了一个派生自 BroadcastReceiver 类的类:

public class InternetConnector_Receiver extends BroadcastReceiver {
   public InternetConnector_Receiver() {}

   @Override
   public void onReceive(Context context, Intent intent) {
      try {
             boolean isVisible = MyApplication.isActivityVisible();// Check if activity is visible or not
             Log.i("Activity is Visible ", "Is activity visible : " + isVisible);

             // If it is visible then trigger the task else do nothing
                if (isVisible == true) {
                   ConnectivityManager connectivityManager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
                   NetworkInfo networkInfo = connectivityManager.getActiveNetworkInfo();

                   // Check internet connection and accrding to state change then text of activity by calling method
                   if (networkInfo != null && networkInfo.isConnected()) {
                      new LMMoviesMainActivity().TTSstatusDataNetChanged(true);
                   } else {
                      new LMMoviesMainActivity().TTSstatusDataNetChanged(false);
                   }
                }
     } catch (Exception e) {
        e.printStackTrace();
     }
  }
}

然后,我在LMMoviesMainActivity中创建相关变量。

问题: IntentFilter 中添加的3个操作是否正确激活了对Internet连接的检测?如果它们不正确,那么正确的值是什么?

private IntentFilter internetConnectionGloIntentFilter;
private InternetConnector_Receiver objGloInternetConnectorReceiver;
internetConnectionGloIntentFilter = new IntentFilter();
internetConnectionGloIntentFilter.addAction("android.net.conn.CONNECTIVITY_CHANGE");
internetConnectionGloIntentFilter.addAction("android.net.wifi.WIFI_STATE_CHANGED");
internetConnectionGloIntentFilter.addAction("android.net.wifi.STATE_CHANGE");
objGloInternetConnectorReceiver = new InternetConnector_Receiver();
registerReceiver(objGloInternetConnectorReceiver, internetConnectionGloIntentFilter);

最后,包含在发生Internet连接更改时要执行的指令的函数:

public void TTSstatusDataNetChanged(boolean isConnectedBool) {
   unregisterReceiver(objGloInternetConnectorReceiver);
   registerReceiver(objGloInternetConnectorReceiver, internetConnectionGloIntentFilter);

   // Change status according to boolean value
   if (isConnectedBool) {

      if (ttsSettingsGloDialog.isShowing()) {
         ttsWarningsGloTextView.setText( "Net ON" );
      }

      dataNetConnectedGloBool = true;
   } else {

      if (ttsSettingsGloDialog.isShowing()) {
         ttsWarningsGloTextView.setText( "Net Off" );
      }

      dataNetConnectedGloBool = false;
   }
}

尝试执行: unregisterReceiver ,我收到消息:

服务com.google.android.youtube.api.service.YouTubeService已泄露最初在此处注册的IntentReceiver wuq @ 3967361。你是否错过了对unregisterReceiver()的调用?

但我想我必须取消注册Receiver,然后重新注册,为下一个连接事件做好准备,对吧?如果当前的unregisterReceiver没有引用意图或事件触发,那么如何正确编写指令并将其关联呢?

我在调试器中检查了Intent触发器, BroadcastReceiver 接收到了该事件,但我不知道如何克服这个泄漏的错误。有任何想法吗?我错过了一些关键的东西吗你看到有什么错吗?谢谢你的兴趣。

3 个答案:

答案 0 :(得分:1)

您只需注册一次广播接收器,而不是每次注册。每次注册广播接收器时,您必须取消注册。每次在方法内部引起泄漏时,请修复它。移除它并仅在onResume中注册并在onPause中取消注册。

@Override
protected void onResume() {
    super.onResume();
    registerReceiver(objGloInternetConnectorReceiver, internetConnectionGloIntentFilter);
}

@Override
protected void onPause() {
    unregisterReceiver(objGloInternetConnectorReceiver);
    super.onPause();
}

答案 1 :(得分:0)

在您的LMMoviesMainActivity的objGloInternetConnectorReceiver回调中取消注册您的接收者OnDestroy()

 @Override
     protected void onDestroy() {
            super.onDestroy();

          unregisterReceiver(objGloInternetConnectorReceiver);

        }

答案 2 :(得分:0)

您的代码中存在多个问题。如果您在onResume()中注册接收者并在onPause()中取消注册,则无需检查活动是否可见。

if (networkInfo != null && networkInfo.isConnected()) {
    new LMMoviesMainActivity().TTSstatusDataNetChanged(true);
} else {
    new LMMoviesMainActivity().TTSstatusDataNetChanged(false);
}

这不起作用,因为您需要引用实际的Activity而不是新的Activity。如果你把BroadcastReceiver放在LMMoviesMainActivity中就行了

if (networkInfo != null && networkInfo.isConnected()) {
    LMMoviesMainActivity.this.TTSstatusDataNetChanged(true);
} else {
    LMMoviesMainActivity.this.TTSstatusDataNetChanged(false);
}

当您收到广播时,您也不必取消注册并注册新的Broadcastreceiver。所以删除这些行:

unregisterReceiver(objGloInternetConnectorReceiver);
registerReceiver(objGloInternetConnectorReceiver, internetConnectionGloIntentFilter);

这里有一个应该有用的完整示例:(别忘了初始化ttsSettingsGloDialog,ttsWarningsGloTextView和dataNetConnectedGloBool)

package com.test;

import android.app.Activity;
import android.app.Dialog;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.widget.TextView;

public class LMMoviesMainActivity extends Activity {

    private IntentFilter internetConnectionGloIntentFilter;
    private InternetConnector_Receiver objGloInternetConnectorReceiver;

    private Dialog ttsSettingsGloDialog;
    private TextView ttsWarningsGloTextView;
    private boolean dataNetConnectedGloBool;

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        internetConnectionGloIntentFilter = new IntentFilter();
        internetConnectionGloIntentFilter.addAction("android.net.conn.CONNECTIVITY_CHANGE");
        internetConnectionGloIntentFilter.addAction("android.net.wifi.WIFI_STATE_CHANGED");
        internetConnectionGloIntentFilter.addAction("android.net.wifi.STATE_CHANGE");

        objGloInternetConnectorReceiver = new InternetConnector_Receiver();
    }

    @Override
    protected void onResume() {
        super.onResume();
        registerReceiver(objGloInternetConnectorReceiver, internetConnectionGloIntentFilter);
    }

    @Override
    protected void onPause() {
        unregisterReceiver(objGloInternetConnectorReceiver);
        super.onPause();
    }

    public void TTSstatusDataNetChanged(boolean isConnectedBool) {
        // Change status according to boolean value
        if (isConnectedBool) {

            if (ttsSettingsGloDialog.isShowing()) {
                ttsWarningsGloTextView.setText( "Net ON" );
            }

            dataNetConnectedGloBool = true;
        } else {

            if (ttsSettingsGloDialog.isShowing()) {
                ttsWarningsGloTextView.setText( "Net Off" );
            }

            dataNetConnectedGloBool = false;
        }
    }

    public class InternetConnector_Receiver extends BroadcastReceiver {
        @Override
        public void onReceive(Context context, Intent intent) {
            try {
                ConnectivityManager connectivityManager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
                NetworkInfo networkInfo = connectivityManager.getActiveNetworkInfo();

                // Check internet connection and accrding to state change then text of activity by calling method
                if (networkInfo != null && networkInfo.isConnected()) {
                    LMMoviesMainActivity.this.TTSstatusDataNetChanged(true);
                } else {
                    LMMoviesMainActivity.this.TTSstatusDataNetChanged(false);
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
}