Android下自动连接指定SSID的WIFI的简单实现

一、关于WiFi模块的概述:

  1.在Android developer的文档中WiFi模块的信息:

      首先,登记广播的监听;其次,请求扫描wifi信号;最后获取扫描到的wifi信息。

  2.在广播监听到结果后,创建出WifiManager的对象之后通过getScanResults()方法获取到扫描wifi的对象信息。     

二、指定SSID和密码进行wifi的自动连接:

  需求分析:在很多的智能设备上并没有可用于交互的界面。这种情形在智能设备就可以提供指定SSID和密码的wifi自动连接。

      1.创建一个管理类用于管理wifi的状态、连接动作的各类信息:

public class WIFIConnectionManager {

    private static final String TAG = WIFIConnectionManager.class.getName();
    private static WIFIConnectionManager sInstance = null;
    private android.net.wifi.WifiManager mWifiManager;
    private int networkId;


    public WIFIConnectionManager(Context context) {
        mWifiManager = (android.net.wifi.WifiManager) context.getApplicationContext().getSystemService(Context.WIFI_SERVICE);
    }

    public static WIFIConnectionManager getInstance(Context context) {
        if (sInstance == null) {
            synchronized (WIFIConnectionManager.class) {
                if (sInstance == null) {
                    sInstance = new WIFIConnectionManager(context);
                }
            }
        }
        return sInstance;
    }


    /**
     * 尝试连接指定wifi
     *
     * @param ssid     wifi名
     * @param password 密码
     * @return 是否连接成功
     */
    public boolean connect(@NonNull String ssid, @NonNull String password) {
        Log.d(TAG, "connect() called with: ssid = [" + ssid + "], password = [" + password + "]");
        Log.d(TAG, "connect: wifi opened = " + openWifi());
        boolean isConnected = isConnected(ssid);//当前已连接至指定wifi
        Log.d(TAG, "connect: is already connected = " + isConnected);
        if (isConnected) {
            return true;
        }
        networkId = mWifiManager.addNetwork(newWifiConfig(ssid, password, true));
        boolean result = mWifiManager.enableNetwork(networkId, true);
        Log.d(TAG, "connect: network enabled = " + result);
        return result;
    }


    /**
     * 根据wifi名与密码配置 WiFiConfiguration, 每次尝试都会先断开已有连接
     *
     * @param isClient 当前设备是作为客户端,还是作为服务端, 影响SSID和PWD
     */
    @NonNull
    private WifiConfiguration newWifiConfig(String ssid, String password, boolean isClient) {
        WifiConfiguration config = new WifiConfiguration();
        config.allowedAuthAlgorithms.clear();
        config.allowedGroupCiphers.clear();
        config.allowedKeyManagement.clear();
        config.allowedPairwiseCiphers.clear();
        config.allowedProtocols.clear();
        if (isClient) {//作为客户端, 连接服务端wifi热点时要加双引号
            config.SSID = "\"" + ssid + "\"";
            config.preSharedKey = "\"" + password + "\"";
        } else {//作为服务端, 开放wifi热点时不需要加双引号
            config.SSID = ssid;
            config.preSharedKey = password;
        }
        config.hiddenSSID = true;
        config.allowedAuthAlgorithms.set(WifiConfiguration.AuthAlgorithm.OPEN);
        config.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.TKIP);
        config.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_PSK);
        config.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.TKIP);
        config.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.CCMP);
        config.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.CCMP);
        config.status = WifiConfiguration.Status.ENABLED;
        return config;
    }

    /**
     * @return 热点是否已开启
     */
    public boolean isWifiEnabled() {
        try {
            Method methodIsWifiApEnabled = WifiManager.class.getDeclaredMethod("isWifiApEnabled");
            return (boolean) methodIsWifiApEnabled.invoke(mWifiManager);
        } catch (Exception e) {
            Log.e(TAG, "isWifiEnabled: ", e);
            return false;
        }
    }

    /**
     * 是否已连接指定wifi
     */
    public boolean isConnected(String ssid) {
        WifiInfo wifiInfo = mWifiManager.getConnectionInfo();
        if (wifiInfo == null) {
            return false;
        }
        switch (wifiInfo.getSupplicantState()) {
            case AUTHENTICATING:
            case ASSOCIATING:
            case ASSOCIATED:
            case FOUR_WAY_HANDSHAKE:
            case GROUP_HANDSHAKE:
            case COMPLETED:
                return wifiInfo.getSSID().replace("\"", "").equals(ssid);
            default:
                return false;
        }
    }

    /**
     * 打开WiFi
     * @return
     */
    public boolean openWifi() {
        boolean opened = true;
        if (!mWifiManager.isWifiEnabled()) {
            opened = mWifiManager.setWifiEnabled(true);
        }
        return opened;
    }

    /**
     * 关闭wifi
     * @return
     */
    public boolean closeWifi() {
        boolean closed = true;
        if (mWifiManager.isWifiEnabled()) {
            closed = mWifiManager.setWifiEnabled(false);
        }
        return closed;
    }

    /**
     * 断开连接
     * @return
     */
    public WIFIConnectionManager disconnect() {
        if (networkId != 0) {
            mWifiManager.disableNetwork(networkId);
        }
        mWifiManager.disconnect();
        return this;
    }

    /**
     * 是否连接过指定Wifi
     */
    @Nullable
    public WifiConfiguration everConnected(String ssid) {
        List<WifiConfiguration> existingConfigs = mWifiManager.getConfiguredNetworks();
        if (existingConfigs == null || existingConfigs.isEmpty()) {
            return null;
        }
        ssid = "\"" + ssid + "\"";
        for (WifiConfiguration existingConfig : existingConfigs) {
            if (existingConfig.SSID.equals(ssid)) {
                return existingConfig;
            }
        }
        return null;
    }

    /**
     * 获取本机的ip地址
     */
    @Nullable
    public String getLocalIp() {
        return convertIp(mWifiManager.getConnectionInfo().getIpAddress());
    }

    private String convertIp(int ipAddress) {
        if (ipAddress == 0) return null;
        return ((ipAddress & 0xff) + "." + (ipAddress >> 8 & 0xff) + "."
                + (ipAddress >> 16 & 0xff) + "." + (ipAddress >> 24 & 0xff));
    }

    public WifiManager getWifiManager() {
        return mWifiManager;
    }
}

      2.该设备必须在不断的进行扫描wifi的信息,与自己内置的WiFi是否SSID和密码一致。

public class WIFIAutoConnectionService extends Service {

    public static final String SSID = "HUAWEI";
    public static final String PWD = "nihao321";
    private static final String TAG = WIFIAutoConnectionService.class.getSimpleName();
    private static final String KEY_SSID = "KEY_SSID";
    private static final String KEY_PWD = "KEY_PWD";


    /**
     * wifi名
     */
    private String mSsid = "";
    /**
     * 密码
     */
    private String mPwd = "";


    /**
     * 负责不断尝试连接指定wifi
     */
    private Handler mHandler = new Handler(Looper.getMainLooper(), new Handler.Callback() {
        @Override
        public boolean handleMessage(Message msg) {
            WIFIConnectionManager.getInstance(WIFIAutoConnectionService.this).connect(mSsid, mPwd);
            boolean connected =  WIFIConnectionManager.getInstance(WIFIAutoConnectionService.this).isConnected(mSsid);
            Log.d(TAG, "handleMessage: wifi connected = " + connected);
            if (!connected) {
                Log.d(TAG, "handleMessage: re-try in 5 seconds");
                mHandler.sendEmptyMessageDelayed(0, 5000);//5s循环
            }
            return true;
        }
    });

    /**
     * 连接指定wifi热点, 失败后5s循环
     *
     * @param context 用于启动服务的上下文
     * @param ssid    默认HUD-WIFI
     * @param pwd     (WPA加密)默认12345678
     */
    public static void start(Context context, String ssid, String pwd) {
        Intent starter = new Intent(context,WIFIAutoConnectionService.class);
        starter.putExtra(KEY_SSID, ssid).putExtra(KEY_PWD, pwd);
        context.startService(starter);
        Log.d(TAG, "start: ");
    }

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

    /**
     * @return always null
     */
    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        mSsid = intent.getStringExtra(KEY_SSID);
        mPwd = intent.getStringExtra(KEY_PWD);
        mHandler.sendEmptyMessage(0);
        return START_NOT_STICKY;
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        Log.d(TAG, "onDestroy: ");
    }

     3.创建一个BroadcastReceiver来判断wifi的连接及扫描获取的结果:

public class WIFIStateReceiver extends BroadcastReceiver {

    private static final String TAG = WIFIStateReceiver.class.getName();
    private Context mContext;
    List<ScanResult> scanResults;

    public WIFIStateReceiver(Context context) {
        this.mContext = context;
    }

    @Override
    public void onReceive(Context context, Intent intent) {
        if (!intent.getAction().equals(WifiManager.NETWORK_STATE_CHANGED_ACTION)) {
            return;
        }
        scanResults =  WIFIConnectionManager.getInstance(mContext).getWifiManager().getScanResults();
        for (int i = 0 ; i < scanResults.size();i++) {
            Log.e(TAG,"scanResults:----"+(scanResults.get(i)).SSID);
        }
        if (!WIFIConnectionManager.getInstance(mContext).isConnected("HUAWEI")) {
            WIFIConnectionManager.getInstance(mContext).connect("HUAWEI", "nihao321");
        }
    }

}

   4.主界面的简单逻辑:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context=".MainActivity">


    <EditText
        android:layout_gravity="center_horizontal"
        android:hint="输入WiFi的名称"
        android:id="@+id/et_account"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />
    <EditText
        android:layout_gravity="center_horizontal"
        android:id="@+id/et_pwd"
        android:hint="输入WiFi密码"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />

    <Button
        android:layout_gravity="center_horizontal"
        android:id="@+id/btn_auto"
        android:text="模拟WiFi的自动连接"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />

    <Button
        android:layout_gravity="center_horizontal"
        android:id="@+id/btn_disconnect"
        android:text="断开连接"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />



</LinearLayout>
public class MainActivity extends AppCompatActivity implements View.OnClickListener{

    private static final String TAG = MainActivity.class.getName();
    private EditText mEtAccount;
    private EditText mEtPwd;
    private WIFIStateReceiver mWIFIStateReceiver;
    private Button mBtnAuto;
    private Button mBtnDisconnect;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        initView();
        initData();
        initEvent();
    }

    private void initEvent() {
        mBtnAuto.setOnClickListener(this);
        mBtnDisconnect.setOnClickListener(this);
    }

    private void initData() {

    }

    private void initView() {
        mEtAccount = findViewById(R.id.et_account);
        mEtPwd = findViewById(R.id.et_pwd);
        mBtnAuto = findViewById(R.id.btn_auto);
        mBtnDisconnect = findViewById(R.id.btn_disconnect);
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        unregisterReceiver(mWIFIStateReceiver);
    }

    @Override
    public void onClick(View v) {
        switch (v.getId()) {
            case R.id.btn_auto: {
                if (mWIFIStateReceiver == null) {
                    mWIFIStateReceiver = new WIFIStateReceiver(MainActivity.this);
                    registerReceiver(mWIFIStateReceiver, new IntentFilter(WifiManager.NETWORK_STATE_CHANGED_ACTION));
                    WIFIAutoConnectionService.start(this,mEtAccount.getText().toString().trim(),mEtPwd.getText().toString().trim());
                }
            }
            break;
            case R.id.btn_disconnect: {
               WIFIConnectionManager.getInstance(this).disconnect();
               WIFIConnectionManager.getInstance(this).closeWifi();
            }
            break;
        }
    }
}

三、简单小demo的地址

  • 5
    点赞
  • 33
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
实现Android 13的WIFI自动连接,可以通过以下步骤: 1. 在AndroidManifest.xml文件中添加以下权限: ``` <uses-permission android:name="android.permission.CHANGE_WIFI_STATE" /> <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_NETWORK_STATE" /> ``` 2. 在代码中获取WifiManager对象: ``` WifiManager wifiManager = (WifiManager) getSystemService(Context.WIFI_SERVICE); ``` 3. 判断是否连接指定WIFI,并连接: ``` WifiConfiguration wifiConfiguration = null; List<WifiConfiguration> configuredNetworks = wifiManager.getConfiguredNetworks(); for (WifiConfiguration config : configuredNetworks) { if (config.SSID != null && config.SSID.equals("\"" + ssid + "\"")) { wifiConfiguration = config; break; } } if (wifiConfiguration != null) { wifiManager.enableNetwork(wifiConfiguration.networkId, true); } else { // 如果没有连接指定WIFI,则创建新的WIFI配置,并连接 wifiConfiguration = new WifiConfiguration(); wifiConfiguration.SSID = "\"" + ssid + "\""; wifiConfiguration.preSharedKey = "\"" + password + "\""; int netId = wifiManager.addNetwork(wifiConfiguration); wifiManager.enableNetwork(netId, true); } ``` 其中,ssid和password分别代表要连接WIFISSID和密码。 4. 添加BroadcastReceiver监听WIFI连接状态变化: ``` private BroadcastReceiver wifiReceiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { String action = intent.getAction(); if (WifiManager.NETWORK_STATE_CHANGED_ACTION.equals(action)) { NetworkInfo info = intent.getParcelableExtra(WifiManager.EXTRA_NETWORK_INFO); if (info.isConnected()) { // WIFI连接 } else { // WIFI连接 } } } }; // 注册BroadcastReceiver IntentFilter intentFilter = new IntentFilter(); intentFilter.addAction(WifiManager.NETWORK_STATE_CHANGED_ACTION); registerReceiver(wifiReceiver, intentFilter); ``` 这样,当WIFI连接状态变化时,就会收到广播,从而可以处理相应的逻辑。 注意:在Android 13中,为了保护用户隐私,系统对应用程序的WIFI连接能力进行了限制,并且需要用户在设置中手动授权。因此,在实现WIFI自动连接时,需要在应用程序中请求相应的权限,并引导用户进行授权。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值