• After 15+ years, we've made a big change: Android Forums is now Early Bird Club. Learn more here.

WifiManager.StartScan() is crash my app. Why?

I am trying to create a base class that implements all the wifi related functionality that some of the activities in my app use.

I am trying to implement functionality that builds a list of available wifi networks and puts it in m_listScanResults. I can then use this if needed to populate a spinner.

But as soon as I invoke StartScan() my phone screen goes white and my app crashes.

If I comment out StartScan() my activity screen appears as normal.

Why is this happening? What am I doing wrong?

Code:
public class CWifiActivity extends CBaseActivity
{
    @Override
    protected void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);

        if (m_app != null)
        {
            m_wifiManag = (WifiManager)m_app.getSystemService(Context.WIFI_SERVICE);

            if (m_wifiManag != null)
            {
                m_wifiManag.setWifiEnabled(true);

                if (connectWifi())
                {

                }
                else
                {

                }
                registerReceiver(new BroadcastReceiver()
                {
                    @Override
                    public void onReceive(Context c, Intent intent)
                    {
                        //m_listScanResults = m_wifiManag.getScanResults();
                    }
                }, new IntentFilter(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION));
                m_wifiManag.startScan();
            }
        }
    }

// Class members
protected WifiManager m_wifiManag = null;
protected String m_strWifiFailure = new String();
protected List<ScanResult> m_listScanResults = null;
 
CMainActivity is he class that is instantiated.

The idea was, from the perspective of .onResume() in my final derived class, to have m_listScanResults sitting there with the list of available networks that I could fill a spinner control with for example.

In this case CMainActivity is just using CWifiActivity.m_wifiManag to determine if wifi is enabled and connected and whether or not to disable the buttons that popup activities that require wifi to do the UDP comms.

Code:
CBaseActivity
------------------
package com.example.greg.irrigationcontroller;

import android.app.AlertDialog;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;

/**
* Created by Greg on 8/10/2017.
*/

public class CBaseActivity extends AppCompatActivity
{
    @Override
    protected void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);

        m_app = ((CIrrigationApplication) getApplicationContext());
    }

    public void debug(String strMsg)
    {
        AlertDialog.Builder dlgAlert = null;

        dlgAlert = new AlertDialog.Builder(m_app.m_activityCurrent);
        dlgAlert.setMessage(strMsg);
        dlgAlert.setTitle("DEBUG");
        dlgAlert.setPositiveButton("OK", null);
        dlgAlert.setCancelable(true);
        dlgAlert.create();
        dlgAlert.show();
    }
    public void error(String strMsg)
    {
        AlertDialog.Builder dlgAlert = null;

        dlgAlert = new AlertDialog.Builder(m_app.m_activityCurrent);
        dlgAlert.setMessage(strMsg);
        dlgAlert.setTitle("ERROR");
        dlgAlert.setPositiveButton("OK", null);
        dlgAlert.setCancelable(true);
        dlgAlert.create();
        dlgAlert.show();
    }
    protected CIrrigationApplication m_app = null;
}

CWifiActivity
----------------
package com.example.greg.irrigationcontroller;

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.net.wifi.ScanResult;
import android.net.wifi.WifiConfiguration;
import android.net.wifi.WifiInfo;
import android.net.wifi.WifiManager;
import android.os.Bundle;
import android.widget.ArrayAdapter;
import android.widget.Spinner;

import java.util.ArrayList;
import java.util.List;

/**
* Created by Greg on 8/10/2017.
*/

public class CWifiActivity extends CBaseActivity
{
    @Override
    protected void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);

        if (m_app != null)
        {
            m_wifiManag = (WifiManager)m_app.getSystemService(Context.WIFI_SERVICE);

            if (m_wifiManag != null)
            {
                m_wifiManag.setWifiEnabled(true);

                if (connectWifi())
                {

                }
                else
                {

                }
                registerReceiver(new BroadcastReceiver()
                {
                    @Override
                    public void onReceive(Context c, Intent intent)
                    {
                        m_listScanResults = m_wifiManag.getScanResults();
                    }
                }, new IntentFilter(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION));
                m_wifiManag.startScan();
            }
        }
    }

    protected ArrayAdapter<String> getNetworkNames()
    {
        ArrayList<String> arrayNetworks = new ArrayList<String>();

        if (m_listScanResults != null)
        {
            for (int nI = 0; nI < m_listScanResults.size(); nI++)
            {
                arrayNetworks.add(m_listScanResults.get(nI).SSID);
            }
        }
        ArrayAdapter<String> arrayadapterNetworks = new ArrayAdapter<String>(m_app.m_activityCurrent, android.R.layout.simple_spinner_item, arrayNetworks);
        arrayadapterNetworks.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);

        return arrayadapterNetworks;
    }

    protected int getIndex(Spinner spinner, String strSelection)
    {
        int nIndex = 0;

        for (int nI=0; nI < spinner.getCount(); nI++)
        {
            if (spinner.getItemAtPosition(nI).toString().equalsIgnoreCase(strSelection))
            {
                nIndex = nI;
                break;
            }
        }
        return nIndex;
    }

    private BroadcastReceiver m_NetworkStateReceiver = new BroadcastReceiver()
    {
        @Override
        public void onReceive(Context context, Intent intent)
        {
            ConnectivityManager cm = (ConnectivityManager)context.getSystemService(Context.CONNECTIVITY_SERVICE);
            NetworkInfo ni = cm.getActiveNetworkInfo();

            if (ni.getState() == NetworkInfo.State.DISCONNECTED)
            {
                if ((m_app != null) && (m_app.m_activityCurrent != null))
                {
                    if ((m_wifiManag != null) && !m_wifiManag.isWifiEnabled())
                        m_app.m_activityCurrent.error("Wifi has been disabled.");
                    else
                        m_app.m_activityCurrent.error("Disconnected from wifi network.");
                }
            }
        }
    };

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

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

    protected String connectWifiType()
    {
        // Get current connected SSID for comparison to ScanResult
        WifiInfo wifiInfo = m_wifiManag.getConnectionInfo();

        String strWifiType = new String(), strCurrentSSID = wifiInfo.getSSID(), strCapabilities = new String();;

        // Fetch a list of current available wifi networks.
        List<ScanResult> listNetworks = m_wifiManag.getScanResults();

        if (listNetworks != null)
        {
            for (ScanResult WifiNetwork : listNetworks)
            {
                // Check if current connected SSID
                if (strCurrentSSID.equals(WifiNetwork.SSID))
                {
                    // Get capabilities of current connection
                    strCapabilities =  WifiNetwork.capabilities;

                    if (strCapabilities.contains("WPA2"))
                    {
                        strWifiType = "WPA2";
                    }
                    else if (strCapabilities.contains("WPA"))
                    {
                        strWifiType = "WPA";
                    }
                    else if (strCapabilities.contains("WEP"))
                    {
                        strWifiType = "WEP";
                    }
                }
            }
        }
        return strWifiType;
    }

    protected WifiConfiguration getWifiConfig(final String strWifiType, final String strNetworkName, final String strNetworkKey)
    {
        WifiConfiguration wifiConfig = new WifiConfiguration();

        wifiConfig.SSID = "\"".concat(strNetworkName).concat("\"");
        wifiConfig.status = WifiConfiguration.Status.DISABLED;
        wifiConfig.priority = 40;

        if ((strWifiType == "WPA2") || (strWifiType == "WPA"))
        {
            wifiConfig.allowedProtocols.set(WifiConfiguration.Protocol.RSN);
            wifiConfig.allowedProtocols.set(WifiConfiguration.Protocol.WPA);
            wifiConfig.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_PSK);
            wifiConfig.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.CCMP);
            wifiConfig.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.TKIP);
            wifiConfig.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.WEP40);
            wifiConfig.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.WEP104);
            wifiConfig.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.CCMP);
            wifiConfig.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.TKIP);
            wifiConfig.preSharedKey = "\"".concat(strNetworkKey).concat("\"");
        }
        else if (strWifiType.contains("WEP"))
        {
            wifiConfig.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE);
            wifiConfig.allowedProtocols.set(WifiConfiguration.Protocol.RSN);
            wifiConfig.allowedProtocols.set(WifiConfiguration.Protocol.WPA);
            wifiConfig.allowedAuthAlgorithms.set(WifiConfiguration.AuthAlgorithm.OPEN);
            wifiConfig.allowedAuthAlgorithms.set(WifiConfiguration.AuthAlgorithm.SHARED);
            wifiConfig.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.CCMP);
            wifiConfig.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.TKIP);
            wifiConfig.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.WEP40);
            wifiConfig.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.WEP104);
            wifiConfig.wepKeys[0] = "\"".concat(strNetworkKey).concat("\"");
            wifiConfig.wepTxKeyIndex = 0;
        }
        else
        {
            wifiConfig.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE);
            wifiConfig.allowedProtocols.set(WifiConfiguration.Protocol.RSN);
            wifiConfig.allowedProtocols.set(WifiConfiguration.Protocol.WPA);
            wifiConfig.allowedAuthAlgorithms.clear();
            wifiConfig.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.CCMP);
            wifiConfig.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.TKIP);
            wifiConfig.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.WEP40);
            wifiConfig.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.WEP104);
            wifiConfig.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.CCMP);
            wifiConfig.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.TKIP);
        }
        return wifiConfig;
    }

    protected boolean connectWifi()
    {
        boolean bResult = false;

        if ((m_wifiManag != null) && (m_app != null))
        {
            if (!m_wifiManag.isWifiEnabled())
            {
                m_strWifiFailure = "Please enable wifi.";
                m_wifiManag = null;
            }
            else if (m_app.m_strNetworkName.isEmpty() || m_app.m_strNetworkKey.isEmpty())
            {
                m_strWifiFailure = "Wifi network name and/or network key is blank.";
                m_wifiManag = null;
            }
            else
            {
                String strWifiType = connectWifiType();
                WifiConfiguration wifiConfig = getWifiConfig(strWifiType, m_app.m_strNetworkName, m_app.m_strNetworkKey);

                int nNetworkID = m_wifiManag.addNetwork(wifiConfig);
                if (nNetworkID != -1)
                {
                    m_wifiManag.enableNetwork(nNetworkID, true);
                }
                else
                {
                    m_strWifiFailure = "Failed to connect to wifi network '" + m_app.m_strNetworkName + "' - is network name and password correct?";
                    m_wifiManag = null;
                }
            }
        }
        return bResult;
    }

    protected WifiManager m_wifiManag = null;
    protected String m_strWifiFailure = new String();
    protected List<ScanResult> m_listScanResults = null;
}

CMainActivity
---------------------------
package com.example.greg.irrigationcontroller;

import android.app.AlertDialog;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;

/**
* Created by Greg on 8/10/2017.
*/

public class CBaseActivity extends AppCompatActivity
{
    @Override
    protected void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);

        m_app = ((CIrrigationApplication) getApplicationContext());
    }

    public void debug(String strMsg)
    {
        AlertDialog.Builder dlgAlert = null;

        dlgAlert = new AlertDialog.Builder(m_app.m_activityCurrent);
        dlgAlert.setMessage(strMsg);
        dlgAlert.setTitle("DEBUG");
        dlgAlert.setPositiveButton("OK", null);
        dlgAlert.setCancelable(true);
        dlgAlert.create();
        dlgAlert.show();
    }
    public void error(String strMsg)
    {
        AlertDialog.Builder dlgAlert = null;

        dlgAlert = new AlertDialog.Builder(m_app.m_activityCurrent);
        dlgAlert.setMessage(strMsg);
        dlgAlert.setTitle("ERROR");
        dlgAlert.setPositiveButton("OK", null);
        dlgAlert.setCancelable(true);
        dlgAlert.create();
        dlgAlert.show();
    }
    protected CIrrigationApplication m_app = null;
}
 
Back
Top Bottom