目标是在我的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 接收到了该事件,但我不知道如何克服这个泄漏的错误。有任何想法吗?我错过了一些关键的东西吗你看到有什么错吗?谢谢你的兴趣。
答案 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();
}
}
}
}