gpt4 book ai didi

java - android广播接收器OnReceive()延迟导致错误

转载 作者:太空狗 更新时间:2023-10-29 16:02:58 25 4
gpt4 key购买 nike

我的广播接收器监听 WiFi ssid 更改,如果 ssid 更改,它返回 boolean 值 WifiChanged true。我在另一个 Activity 中检查这个 boolean 值,该 Activity 根据返回的值更改列表,无论它是真还是假。默认情况下 boolean 值是 false。

我有意更改应触发广播接收器将 boolean 值返回为 true 并相应地设置列表的 wifi,但实际发生的是我的列表根据 boolean 值 false 更改,因为广播接收器需要一段时间才能返回值(value)。在下面的日志中,您可以看到 boolean 值为 false,大约 0.58 秒后 ssid 发生变化。到时候就晚了

08-08 16:43:54.487: D/PlayerManager(20733): Did Wi-Fi Changed: false
|
|
|
08-08 16:43:55.047: V/ConnectionChangeReceiver(20733): onReceive(Context context, Intent intent)
08-08 16:43:55.077: D/ConnectionChangeReceiver(20733): ssid changed from s_ssid="Walter_Meth_Lab" to newSsid="Kings_Landing"

这是我的 OnReceive()

public class ConnectionChangeReceiver extends BroadcastReceiver {
private static final String TAG = "ConnectionChangeReceiver";
private static String s_ssid = null;
private static String s_ipAddress = null;
private static String mNetworkType;
private static ConnectionChangeReceiver sInstance;

private ConnectionChangeListener mConnectionChangeListener;
private boolean mHasWifiChanged;

public static ConnectionChangeReceiver getInstance() {
Log.v(TAG, "getInstance()");
synchronized (ConnectionChangeReceiver.class) {
if (sInstance == null) {
sInstance = new ConnectionChangeReceiver();
}
}
return sInstance;
}

public boolean WifiChanged() {
return mHasWifiChanged;
}


public void setConnectionChangeListener(final ConnectionChangeListener listener) {
this.mConnectionChangeListener = listener;
}

@Override
public void onReceive(final Context context, final Intent intent) {
Log.v(TAG, "onReceive(Context context, Intent intent)");

mHasWifiChanged = false;
String newSsid = null;

String action = intent.getAction();
if ((action.equals(WifiManager.NETWORK_STATE_CHANGED_ACTION)) || (action.equals(WifiManager.WIFI_STATE_CHANGED_ACTION))
|| (action.equals("android.net.conn.CONNECTIVITY_CHANGE"))) {
NetworkInfo networkInfo = (NetworkInfo) intent.getParcelableExtra(ConnectivityManager.EXTRA_NETWORK_INFO);
if (networkInfo != null) {
if (networkInfo.getTypeName().equals("WIFI")) {
WifiManager wm = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
if (wm != null) {
WifiInfo connectionInfo = wm.getConnectionInfo();
if (connectionInfo != null) {
newSsid = connectionInfo.getSSID();
if ((newSsid != null) && (s_ssid != null) && (newSsid.compareTo(s_ssid) != 0)) {
Log.d(TAG, "ssid changed from s_ssid=" + s_ssid + " to newSsid=" + newSsid);
mHasWifiChanged = true;
}
}
}
}
}
}

s_ssid = newSsid;

这是我使用 boolean 值的另一个 Activity

boolean WifiChanged = ConnectionChangeReceiver.getInstance().WifiChanged();
Log.d(TAG, "Did Wi-Fi Changed:" + WifiChanged);
if (WifiChanged) {
//Do Something

}

如果 Wi-Fi ssid 发生变化,列表应该根据 WifiChanged true 进行更改,但它始终会针对 WifiChanged false 进行更改,因为 ChangeReceiver() 不会按时返回 true 并且使用默认的 false。

最佳答案

有很多方法可以做到这一点。

我更喜欢使用 LocalBroadcastManager

这将如何工作:不是让 Activity 请求信息,而是让 ConnectionChangeReceiver 交付它 - 当它可用时ConnectionChangeReceiver 处理完接收到的 intent 后,它会发送一个 local 广播。如果您的 Activity 是活跃的并且正在聆听,它就会对此使用react。

// Snippet from your `ConnectionChangeReceiver # onReceive(...)` method
if (connectionInfo != null) {
newSsid = connectionInfo.getSSID();
if ((newSsid != null) && (s_ssid != null) && (newSsid.compareTo(s_ssid) != 0)) {
Log.d(TAG, "ssid changed from s_ssid=" + s_ssid + " to newSsid=" + newSsid);
mHasWifiChanged = true;

// We can send a local broadcast now
// Note that the String `"com.my.app.wifi.WIFI_RELATED_CHANGE"` can be
// customized to your preference
Intent localIntent = new Intent("com.my.app.wifi.WIFI_RELATED_CHANGE");

// Including this extra is redundant here since `mHasWifiChanged` will
// always be true at this point. I am including it for example sake.
// Again, notice that the key `"com.my.app.wifi.WIFI_HAS_CHANGED"` can
// be customized
localIntent.putExtra("com.my.app.wifi.WIFI_HAS_CHANGED", mHasWifiChanged);

// Broadcasts the Intent to receivers in this app
LocalBroadcastManager.getInstance(context).sendBroadcast(localIntent);
}
}

在 Activity 方面:在您的 Activity 中创建一个 BroadcastReceiver 并将其设置为监听操作 "com.my.app.wifi.WIFI_RELATED_CHANGE"。此字符串值必须与从 ConnectionChangeReceiver #onReceive(...) 发送广播时使用的值相同:

// Declared as a class member in your Activity
BroadcastReceiver wifiRelatedChangeListener = new BroadcastReceiver() {

@Override
public void onReceive(Context context, Intent intent) {

String action = intent.getAction();
if (action.equals("com.my.app.wifi.WIFI_RELATED_CHANGE")) {
// In your current setup, `mHasWifiChanged` will always be true
// Act on it
}
}
};

您应该将 BroadcastReceiver 声明为类成员。这将允许您适本地注册和取消注册 BroadcastReceiver:在 onResume() 中注册并在 onPause() 中取消注册。

在您的 Activity 的 onResume() 中,注册此接收器以监听操作 com.my.app.wifi.WIFI_RELATED_CHANGE:

@Override
public void onResume() {
super.onResume();

// Activity has come to foreground. Register to listen for changes to wifi state.

// Create an IntentFilter with action `com.my.app.wifi.WIFI_RELATED_CHANGE`
IntentFilter intentFilter = new IntentFilter("com.my.app.wifi.WIFI_RELATED_CHANGE");

// Register your broadcastreceiver to receive broadcasts
// with action `com.my.app.wifi.WIFI_RELATED_CHANGE`
LocalBroadcastManager.getInstance(this)
.registerReceiver(wifiRelatedChangeListener, intentFilter);
}

onPause()中注销接收者:

@Override
public void onPause() {
super.onPause();

// Activity is going to background. No need to listen anymore
LocalBroadcastManager.getInstance(this).unregisterReceiver(wifiRelatedChangeListener);
}

请注意,您可以在许多 Activity 中声明一个接收器,例如 wifiRelatedChangeListener。广播从 ConnectionChangeReceiver # onReceive(...) 发送一次。无论此时哪个 Activity 在前台/正在收听,都将收到此广播并据此采取行动。

By that time its too late

这个问题不会出现在上面讨论的解决方案中。

关于java - android广播接收器OnReceive()延迟导致错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25215280/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com