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; }