【问题标题】:Broadcast receiver not working correctly when App is Executed执行应用程序时广播接收器无法正常工作
【发布时间】:2018-01-29 19:40:11
【问题描述】:

问题描述: 我正在尝试开发一个简单的 android 应用程序来强制连接到已经存储在手机上的特定开放 WiFi 配置。

注册广播接收器以监视连接状态。如果连接成功,那么我想在屏幕上打印一条消息。

在下面的代码sn-p中,注册的广播接收器是ConnectionReceiver()。执行应用程序时从不打印 toast 消息。如果我检查手机 wifi 设置菜单,则设备已连接到 wifi 网络。

知道为什么代码从不进入广播接收器中的 if (networkInfo.isConnected().... 语句。

我执行了以下检查: 1.确认尝试连接的wifi网络设备处于活动状态。 2. 在设置菜单中确认设备可以手动连接设备。 3. 运行调试器 - 在 toast 消息上添加断点并确认执行正在进入 if 语句但不显示 toast 消息。 4. 我也尝试显示一个活动屏幕,但它也没有显示。 5. 确认广播接收器已注册。 6.确认manifest文件包含以下权限:

<uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE"/>

知道为什么 toast 消息没有显示在下面的代码 sn-p 中吗?

    package com.agt01.wifitest;

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.IntentFilter;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.net.wifi.WifiConfiguration;
import android.net.wifi.WifiInfo;
import android.net.wifi.WifiManager;
import android.provider.Settings;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.widget.Toast;

import java.util.List;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.TimeUnit;

public class MainActivity extends AppCompatActivity {

public static final String SSID = "vego";
private static final int REQUEST_ENABLE_WIFI = 10;
private static final int TIMEOUT = 20;
private ConnectionReceiver connectionReceiver;
private final ScheduledExecutorService worker =
        Executors.newSingleThreadScheduledExecutor();
private ScheduledFuture taskHandler;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    WifiManager wifiManager  = (WifiManager) getSystemService(Context.WIFI_SERVICE);
    if (wifiManager.isWifiEnabled()) {
        connectToSpecificNetwork();
    } else {
        showWifiDisabledDialog();
    }


}

private void connectToSpecificNetwork() {
    WifiManager wifiManager  = (WifiManager) getSystemService(Context.WIFI_SERVICE);
    ConnectivityManager cm = (ConnectivityManager) getSystemService(CONNECTIVITY_SERVICE);
    NetworkInfo networkInfo = cm.getNetworkInfo(ConnectivityManager.TYPE_WIFI);
    WifiInfo wifiInfo = wifiManager.getConnectionInfo();
    if (networkInfo.isConnected() && wifiInfo.getSSID().replace("\"", "").equals(SSID)) {
        setContentView(R.layout.activity_conect);
        return;
    }
    else {
        List<WifiConfiguration> wifiConfigurations = wifiManager.getConfiguredNetworks();
        for (WifiConfiguration wifiConfiguration : wifiConfigurations) {
            if (wifiConfiguration.SSID.equals("\"" + SSID + "\"")) {
                connectionReceiver = new ConnectionReceiver();
                IntentFilter intentFilter = new IntentFilter();
                intentFilter.addAction(WifiManager.NETWORK_STATE_CHANGED_ACTION);
                intentFilter.addAction(WifiManager.SUPPLICANT_CONNECTION_CHANGE_ACTION);
                intentFilter.addAction(WifiManager.SUPPLICANT_STATE_CHANGED_ACTION);
                intentFilter.addAction(WifiManager.WIFI_STATE_CHANGED_ACTION);
               // setContentView(R.layout.activity_main);
                registerReceiver(this.connectionReceiver, intentFilter);
                wifiManager.enableNetwork(wifiConfiguration.networkId, true);
                //Log.i(TAG, "connectToWifi: will enable " + wifiConfiguration.SSID);
                wifiManager.reconnect();
                break;
            }
        }

    }

}


/**
 * Broadcast receiver for connection related events
 */
private class ConnectionReceiver extends BroadcastReceiver {

    WifiManager wifi = (WifiManager) getSystemService(WIFI_SERVICE);


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

        WifiManager wifiManager  = (WifiManager) getSystemService(Context.WIFI_SERVICE);
        ConnectivityManager cm = (ConnectivityManager) getSystemService(CONNECTIVITY_SERVICE);
        NetworkInfo networkInfo = cm.getNetworkInfo(ConnectivityManager.TYPE_WIFI);
        WifiInfo wifiInfo = wifiManager.getConnectionInfo();
        CharSequence text = "Hello toast!";
        int duration = Toast.LENGTH_LONG;

        Toast toast = Toast.makeText(getApplicationContext(), text, duration);

        if (networkInfo.isConnected() && wifiInfo.getSSID().replace("\"", "").equals(SSID)) {
            setContentView(R.layout.activity_connected);
            toast.show();
        }
    }
}

// User has returned from settings screen. Check if wifi is enabled
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    if (requestCode == REQUEST_ENABLE_WIFI && resultCode == 0) {
        WifiManager wifi = (WifiManager) getSystemService(WIFI_SERVICE);
        if (wifi.isWifiEnabled() || wifi.getWifiState() == WifiManager.WIFI_STATE_ENABLING) {
            connectToSpecificNetwork();
        } else {
            finish();
        }
    } else {
        finish();
    }
}
/**
 * Ask user to go to settings and enable wifi
 */
private void showWifiDisabledDialog() {
    new AlertDialog.Builder(this)
            .setCancelable(false)
            .setMessage(getString(R.string.wifi_disabled))
            .setPositiveButton(getString(R.string.enable_wifi), new DialogInterface.OnClickListener() {
                public void onClick(DialogInterface dialog, int which) {
                    // open settings screen
                    Intent intent = new Intent(Settings.ACTION_WIFI_SETTINGS);
                    startActivityForResult(intent, REQUEST_ENABLE_WIFI);
                }
            })
            .setNegativeButton(getString(R.string.exit_app), new DialogInterface.OnClickListener() {

                public void onClick(DialogInterface dialog, int which) {
                    finish();
                }
            })
            .show();
}

}

【问题讨论】:

  • 等等,你问“知道为什么代码永远不会进入广播接收器中的 if (networkInfo.isConnected().... 语句”,但你稍后在摘要中说你可以在if 语句中打断点...
  • 对造成的混乱表示歉意。由于执行应用程序时未显示 toast 消息或活动屏幕,我认为代码没有进入 if 语句。但是,当在 if 语句中添加断点时,我注意到代码确实进入了 if 语句。与正常操作相比,应用程序在调试模式下的行为是否可能有所不同?

标签: android


【解决方案1】:

如果输入 if 语句后 toast 消息没有显示,通常可能是上下文问题。试试Toast.makeText(getContext(), text, duration)Toast.makeText(getApplicationContext(), text, duration) 等。

请检查以下代码,它非常适合我,即它显示 Hello toast!信息。在运行应用程序之前,我已连接到 wifi。 (为了测试我改变了 if else 逻辑)

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.IntentFilter;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.net.wifi.WifiConfiguration;
import android.net.wifi.WifiInfo;
import android.net.wifi.WifiManager;
import android.provider.Settings;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.widget.Toast;

import java.util.List;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.TimeUnit;

public class MainActivity extends AppCompatActivity {

    public static final String SSID = "SD";
    private static final int REQUEST_ENABLE_WIFI = 10;
    private static final int TIMEOUT = 20;
    private ConnectionReceiver connectionReceiver;
    private final ScheduledExecutorService worker =
            Executors.newSingleThreadScheduledExecutor();
    private ScheduledFuture taskHandler;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        WifiManager wifiManager = (WifiManager) getApplicationContext().getSystemService(Context.WIFI_SERVICE);
        if (wifiManager.isWifiEnabled()) {
            connectToSpecificNetwork();
        } else {
            showWifiDisabledDialog();
        }


    }

    private void connectToSpecificNetwork() {
        WifiManager wifiManager = (WifiManager) getApplicationContext().getSystemService(Context.WIFI_SERVICE);
        ConnectivityManager cm = (ConnectivityManager) getSystemService(CONNECTIVITY_SERVICE);
        NetworkInfo networkInfo = cm.getNetworkInfo(ConnectivityManager.TYPE_WIFI);
        WifiInfo wifiInfo = wifiManager.getConnectionInfo();
        if (!networkInfo.isConnected() && wifiInfo.getSSID().replace("\"", "").equals(SSID)) {
            setContentView(R.layout.activity_main);
            return;
        } else {
            List<WifiConfiguration> wifiConfigurations = wifiManager.getConfiguredNetworks();
            for (WifiConfiguration wifiConfiguration : wifiConfigurations) {
                if (wifiConfiguration.SSID.equals("\"" + SSID + "\"")) {
                    connectionReceiver = new ConnectionReceiver();
                    IntentFilter intentFilter = new IntentFilter();
                    intentFilter.addAction(WifiManager.NETWORK_STATE_CHANGED_ACTION);
                    intentFilter.addAction(WifiManager.SUPPLICANT_CONNECTION_CHANGE_ACTION);
                    intentFilter.addAction(WifiManager.SUPPLICANT_STATE_CHANGED_ACTION);
                    intentFilter.addAction(WifiManager.WIFI_STATE_CHANGED_ACTION);
                    // setContentView(R.layout.activity_main);
                    registerReceiver(this.connectionReceiver, intentFilter);
                    wifiManager.enableNetwork(wifiConfiguration.networkId, true);
                    //Log.i(TAG, "connectToWifi: will enable " + wifiConfiguration.SSID);
                    wifiManager.reconnect();
                    break;
                }
            }

        }

    }


    /**
     * Broadcast receiver for connection related events
     */
    private class ConnectionReceiver extends BroadcastReceiver {

        WifiManager wifi = (WifiManager) getApplicationContext().getSystemService(WIFI_SERVICE);


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

            WifiManager wifiManager = (WifiManager) getApplicationContext().getSystemService(Context.WIFI_SERVICE);
            ConnectivityManager cm = (ConnectivityManager) getSystemService(CONNECTIVITY_SERVICE);
            NetworkInfo networkInfo = cm.getNetworkInfo(ConnectivityManager.TYPE_WIFI);
            WifiInfo wifiInfo = wifiManager.getConnectionInfo();
            CharSequence text = "Hello toast!";
            int duration = Toast.LENGTH_LONG;

            Toast toast = Toast.makeText(getApplicationContext(), text, duration);

            if (networkInfo.isConnected() && wifiInfo.getSSID().replace("\"", "").equals(SSID)) {
                setContentView(R.layout.activity_main);
                toast.show();
            }
        }
    }

    // User has returned from settings screen. Check if wifi is enabled
    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        if (requestCode == REQUEST_ENABLE_WIFI && resultCode == 0) {
            WifiManager wifi = (WifiManager) getApplicationContext().getSystemService(WIFI_SERVICE);
            if (wifi.isWifiEnabled() || wifi.getWifiState() == WifiManager.WIFI_STATE_ENABLING) {
                connectToSpecificNetwork();
            } else {
                finish();
            }
        } else {
            finish();
        }
    }

    /**
     * Ask user to go to settings and enable wifi
     */
    private void showWifiDisabledDialog() {
        new AlertDialog.Builder(this)
                .setCancelable(false)
                .setMessage("wifi disabled")
                .setPositiveButton("enable wifi", new DialogInterface.OnClickListener() {
                    public void onClick(DialogInterface dialog, int which) {
                        // open settings screen
                        Intent intent = new Intent(Settings.ACTION_WIFI_SETTINGS);
                        startActivityForResult(intent, REQUEST_ENABLE_WIFI);
                    }
                })
                .setNegativeButton("exit app", new DialogInterface.OnClickListener() {

                    public void onClick(DialogInterface dialog, int which) {
                        finish();
                    }
                })
                .show();
    }
}

【讨论】:

  • 我尝试了以下方法:Toast.makeText(getApplicationContext(), text, duration); ,但是行为仍然相同。如果我将 toast 移到 if 语句之外,则会显示它,这意味着正在调用 ConnectionReceiver 并且上下文很好
  • 在 ConnectionReceiver 中,如果我将 isConnected() 更改为 isAvailable() 则打印 if 语句中的 toast 消息。这并不理想,因为即使设备未连接到硬编码的 wifi 接入点,也可以显示 toast 消息。知道为什么在使用 isConnected() 时它不显示吗?
  • @eagleeye,我试过你的软件。如果设备已经连接到硬编码的 wifi AP,那么一切都很好。如果您连接到另一个 wifi AP,然后启动应用程序,此时您会看到 toast 消息未显示的问题。期望它应该在设备连接到硬编码的 wifi AP 时显示。
  • @seang 添加一个 'try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); }' 在 wifimanager.reconnect() 之后显示 toast 消息。
  • 我按照要求使用 try/catch 代码更新了我的代码。行为如下,如果设备已经连接到硬编码的 AP 并启动应用程序,则会显示 toast 消息。如果设备连接到其他 wifi 设备并启动了应用程序,则并不总是显示 toast 消息。我还能做些什么来使行为更具确定性吗?
猜你喜欢
  • 1970-01-01
  • 2016-10-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-04-28
  • 1970-01-01
  • 2019-02-21
相关资源
最近更新 更多