android 基於wifi模塊通信開發


這篇文章主要是我寫完手機與wifi模塊通信后所用來總結編寫過程的文章,下面,我分幾點來說一下編寫的大概流程。

一、拉出按鈕控件並設置它的點擊事件

二、設置wifi權限

三、打開和關閉wifi

四、掃描wifi到列表中

     (1)拉出ListView控件,並設置它的適配器和點擊事件

     (2)注冊廣播

   (3)動態申請位置權限

   (4)添加並顯示到列表控件

   (5)注銷廣播

五、連接wifi設備

 

 

一、拉出按鈕控件並設置它的點擊事件

首先,我們在新建的項目中的布局文件,即activity_main.xml文件中,添加按鈕控件的聲明。

1 <Button
2             android:id="@+id/OPEN"
3             android:layout_width="wrap_content"
4             android:layout_height="wrap_content"
5             android:text="打開WiFi" />

然后,我們到MainActivity.java文件中,定義Button對象。

1 public Button openWifi;

然后,我們在MainActivity.java文件中的onCreate()方法中給Button的對象賦值,其中,fingViewById()的參數為我們在xml文件中定義的按鈕的id名。

 openWifi = (Button) findViewById(R.id.OPEN);

接下來,我們就可以開始設置點擊事件了。我們在onCreate()中,調用setOnClickListener()方法。

openWifi.setOnClickListener(this);

最后,我們在MainActivity.java中重寫onClick()方法即可。

@Override
public void OnClick(View v)
{
      switch(v.getId())
      {
           case R.id.OPEN:     break;
       }          

}

 

 

二、設置wifi權限

我們可以在AndroidManifest.xml中添加權限。

    <uses-permission android:name="android.permission.CHANGE_NETWORK_STATE" /> <!-- 允許改變wifi連接狀態 -->
    <uses-permission android:name="android.permission.CHANGE_WIFI_STATE" /> <!-- 允許應用獲取網絡狀態信息 -->
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> <!-- 允許應用獲得WiFi信息 -->
    <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" /> <!-- 獲取位置信息 -->
    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
    <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" /> <!-- 獲取手機狀態 -->
    <uses-permission android:name="android.permission.READ_PHONE_STATE" /> <!-- 讀寫SD卡 -->
    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.INTERNET" />

 

 

三、打開和關閉wifi

首先,我們要先定義一個WifiManager類的對象。

final WifiManager wifiManager = (WifiManager) getApplicationContext().getSystemService(Context.WIFI_SERVICE);

然后我們只要在按鈕的點擊事件中添加以下代碼即可。

wifiManager.setWifiEnabled(true);   //開啟wifi
wifiManager.setWifiEnabled(false);  //關閉wifi

 

 

四、掃描wifi到列表中

(1)、拉出ListView控件,並設置它的適配器和點擊事件

首先,我們要在activity_main.xml文件中,添加列表控件的聲明。

<ListView
        android:id="@+id/LIST"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"></ListView>

然后,我們要在MainActivity.java文件中,定義ListView對象。

public ListView listView;

同理,我們要在onCreate()方法中設置列表的點擊事件。

listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {

            }
});

添加完后,我們就可以觸發列表的點擊事件了。但是,這樣還是看不見列表里的變化的,因為我們還沒有為列表添加適配器。我們可以先了解一下適配器是什么。適配器是一個連接數據和AdapterView(ListView就是一個典型的AdapterView)的橋梁,通過它能有效地實現數據與AdapterView的分離設置,使AdapterView與數據的綁定更加簡便,修改更加方便。

接下來,我們就開始定義適配器和有個集合類對象。

public ArrayAdapter adapter;
public ArrayList<String> arrayList = new ArrayList();   //用於存放字符串
public ArrayList<ScanResult> scanList = new ArrayList(); //用於存放掃描到的設備的信息

然后,我們在onCreate()方法中給適配器賦值。

        adapter = new ArrayAdapter(this, android.R.layout.simple_expandable_list_item_1, arrayList);
        listView.setAdapter(adapter);//設置列表顯示

(2)注冊廣播

首先,我們要在onCreate()中定義IntentFilter的對象。

 IntentFilter filter = new IntentFilter();
        filter.addAction(WifiManager.NETWORK_STATE_CHANGED_ACTION);
        filter.addAction(WifiManager.WIFI_STATE_CHANGED_ACTION);
        filter.addAction(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION);
        filter.addAction(ConnectivityManager.CONNECTIVITY_ACTION);

接下來我們要重寫BroadcastReceiver類來定義廣播。

 private BroadcastReceiver receiver = new BroadcastReceiver() {
        @Override
        public void onReceive(final Context context, Intent intent) {
            final WifiManager wifiManager = (WifiManager) getApplicationContext().getSystemService(Context.WIFI_SERVICE);
            String action = intent.getAction();
            if (action.equals(wifiManager.SCAN_RESULTS_AVAILABLE_ACTION))//搜索到可用的wifi
            {
                scanResults = wifiManager.getScanResults();//獲取wifi的掃描結果
                scanResults = getNewList(scanResults);
                for (ScanResult scanResult : scanResults) {
                    arrayList.add(scanResult.SSID);
                    scanList.add(scanResult);
                    adapter.notifyDataSetChanged();
                }
            }

            if (action.equals(WifiManager.NETWORK_STATE_CHANGED_ACTION)) {
                NetworkInfo info = intent.getParcelableExtra(WifiManager.EXTRA_NETWORK_INFO);
                if (info.getState().equals(NetworkInfo.State.CONNECTED)) {
                    final WifiInfo wifiInfo = wifiManager.getConnectionInfo();
                    Toast.makeText(context, "已成功連接" + wifiInfo.getSSID(), Toast.LENGTH_SHORT).show();
                } else if (info.getState().equals(NetworkInfo.State.DISCONNECTED)) {
                    Toast.makeText(context, "已斷開連接", Toast.LENGTH_SHORT).show();
                }
            }
        }
    };

最后,在onCreate()中注冊廣播。

registerReceiver(receiver, filter);

 (3)申請動態的位置權限

public void applypermission() {
        if (Build.VERSION.SDK_INT >= 23) {
            //檢查是否已經給了權限
            int checkpermission = ContextCompat.checkSelfPermission(getApplicationContext(),
                    Manifest.permission.ACCESS_FINE_LOCATION);
            if (checkpermission != PackageManager.PERMISSION_GRANTED) {//沒有給權限
                Log.e("permission", "動態申請");
                //參數分別是當前活動,權限字符串數組,requestcode
                ActivityCompat.requestPermissions(WiFiMainActivity.this, new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, 1);
            }
        }
    }

    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
            Toast.makeText(WiFiMainActivity.this, "已授權", Toast.LENGTH_SHORT).show();
        } else {
            Toast.makeText(WiFiMainActivity.this, "拒絕授權", Toast.LENGTH_SHORT).show();
        }

    }

(4)添加並顯示到列表控件

添加有個按鈕控件,然后在調用startScan()方法就可以開始掃描了。

public void scanWiFi() {
        adapter.clear();    //清空列表里的數據
        adapter.notifyDataSetChanged();       //刷新
        WifiManager wifiManager = (WifiManager) getApplicationContext().getSystemService(Context.WIFI_SERVICE);
        if (!wifiManager.isWifiEnabled()) {      //判斷wifi是否打開
            wifiManager.setWifiEnabled(true);    //如果沒有打開就打開wifi
        }
        //開始掃描wifi設備
        wifiManager.startScan();
    }
public List<ScanResult> getNewList(List<ScanResult> list) {
        List<ScanResult> lists = new ArrayList();
        for (int i = 0; i < list.size(); i++) {
            if (!lists.contains(list.get(i))) {
                lists.add(list.get(i));
            }
        }
        return lists;
    }

 

 

(5)注銷廣播

 在onCreate()中使用unregisterReceiver()方法注銷廣播。

protected void onDestroy() {
        super.onDestroy();//解除注冊
        unregisterReceiver(receiver);
    }

 

 

五、連接wifi設備

wifiManager.disconnect();
                final ScanResult result = scanList.get(i);
                String capabilities = result.capabilities;
                int type = WIFICIPHER_WPA;
                if (!TextUtils.isEmpty(capabilities))//判斷字符串是否為null
                {
                    if (capabilities.contains("WPA") || capabilities.contains("wpa")) {
                        type = WIFICIPHER_WPA;
                    } else if (capabilities.contains("WEP") || capabilities.contains("wep")) {
                        type = WIFICIPHER_WEP;
                    } else {
                        type = WIFICIPHER_NOPASS;
                    }
                    config = isExsits(result.SSID);
                    if (config == null) {
                        if (type != WIFICIPHER_NOPASS) {
                            final EditText editText = new EditText(WiFiMainActivity.this);
                            final int fianalType = type;
                            alertDialog = new AlertDialog.Builder(WiFiMainActivity.this);
                            alertDialog.setTitle("請輸入WiFi密碼:");
                            alertDialog.setView(editText);
                            alertDialog.setPositiveButton("OK", new DialogInterface.OnClickListener() {
                                @Override
                                public void onClick(DialogInterface dialog, int which) {
                                    config = createWifiInfo(result.SSID, editText.getText().toString(), fianalType);
                                    connectWifi(config);
                                }
                            });

                            alertDialog.setNegativeButton("CANCEL", null).show();
                        } else {
                            config = createWifiInfo(result.SSID, "", type);
                            connectWifi(config);
                        }
                    } else {
                        connectWifi(config);
                    }
                }

 

public void connectWifi(WifiConfiguration config) {
        final WifiManager wifiManager = (WifiManager) getApplicationContext().getSystemService(Context.WIFI_SERVICE);
        int wcgID = wifiManager.addNetwork(config);
        wifiManager.enableNetwork(wcgID, true);
    }

 

public WifiConfiguration createWifiInfo(String SSID, String password, int type) {
        WifiConfiguration config = new WifiConfiguration();
        config.allowedAuthAlgorithms.clear();
        config.allowedGroupCiphers.clear();
        config.allowedKeyManagement.clear();
        config.allowedPairwiseCiphers.clear();
        config.allowedProtocols.clear();
        config.SSID = "\"" + SSID + "\"";

        if (type == WIFICIPHER_WEP) {
            config.preSharedKey = "\"" + password + "\"";
            config.hiddenSSID = true;
            config.allowedAuthAlgorithms.set(WifiConfiguration.AuthAlgorithm.SHARED);
            config.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.CCMP);
            config.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.TKIP);
            config.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.WEP40);
            config.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.WEP104);
            config.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE);
            config.wepTxKeyIndex = 0;
        } else if (type == WIFICIPHER_WPA) {
            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;
    }

 

private WifiConfiguration isExsits(String ssid) {
        final WifiManager wifiManager = (WifiManager) getApplicationContext().getSystemService(Context.WIFI_SERVICE);
        List<WifiConfiguration> existingConfigs = wifiManager.getConfiguredNetworks();
        for (WifiConfiguration existingConfig : existingConfigs) {
            if (existingConfig.SSID.equals("\"" + ssid + "\""))
                return existingConfig;
        }
        return null;
    }

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM