Android WiFi開發

概述

介紹Android WiFi的掃描、鏈接、信息、以及WiFi熱點等等的實現,並用代碼實現。

詳細

1、準備工做

開發環境:html

jdk1.8java

Eclipse Luna Service Release 1 (4.4.1)android

運行環境:git

華爲榮耀6(Android4.4)、華爲p9(Android7.0)api

實現功能:安全

  • Android WiFi開發 (一)掃描、鏈接、信息網絡

  • Android WiFi開發 (二)Wifi熱點app

2、代碼結構

代碼包裏面,有兩個部分,一個是源碼,一個是V7支持包。ide

image.png

(源碼項目)測試

image.png

(V7包)

3、Android WiFi開發 (一)掃描、鏈接、信息

一、詳細講解

在日常開發中常常會涉及到wifi相關的內容,在此將以前所用到的整理一下,以避免忘記。

操做wifi的相關類,主要放在Android.net.wifi包下面。使用wifi相關方法須要申請一些權限:

image.png

ACCESS_WIFI_STATE 獲取WiFi狀態。

CHANGE_WIFI_STATE 改變WiFi狀態。

CHANGE_WIFI_MULTICAST_STATE 改變WiFi多播狀態

申請權限方式:在AndroidManifest.xml文件中填寫

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

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

 

wifi相關操做所須要用到的類。

image.png

先說一下wifi的基本使用狀況。

import java.util.List;  
import android.content.Context;  
import android.net.wifi.ScanResult;  
import android.net.wifi.WifiConfiguration;  
import android.net.wifi.WifiInfo;  
import android.net.wifi.WifiManager;  
import android.net.wifi.WifiManager.WifiLock;  
import android.widget.Toast;  
  
public class WifiAdmin {  
    // 定義WifiManager對象     
    private WifiManager mWifiManager;    
    // 定義WifiInfo對象     
    private WifiInfo mWifiInfo;    
    // 掃描出的網絡鏈接列表     
    private List<ScanResult> mWifiList;    
    // 網絡鏈接列表     
    private List<WifiConfiguration> mWifiConfiguration;    
    // 定義一個WifiLock     
    WifiLock mWifiLock;  
   
    // 構造器     
    public WifiAdmin(Context context) {    
        // 取得WifiManager對象     
        mWifiManager = (WifiManager) context    
                .getSystemService(Context.WIFI_SERVICE);    
        // 取得WifiInfo對象     
        mWifiInfo = mWifiManager.getConnectionInfo();    
    }    
    
    // 打開WIFI     
    public void openWifi(Context context) {    
        if (!mWifiManager.isWifiEnabled()) {    
            mWifiManager.setWifiEnabled(true);  
        }else if (mWifiManager.getWifiState() == 2) {  
            Toast.makeText(context,"親,Wifi正在開啓,不用再開了", Toast.LENGTH_SHORT).show();  
        }else{  
            Toast.makeText(context,"親,Wifi已經開啓,不用再開了", Toast.LENGTH_SHORT).show();  
        }  
    }    
    
    // 關閉WIFI     
    public void closeWifi(Context context) {    
        if (mWifiManager.isWifiEnabled()) {    
            mWifiManager.setWifiEnabled(false);    
        }else if(mWifiManager.getWifiState() == 1){  
            Toast.makeText(context,"親,Wifi已經關閉,不用再關了", Toast.LENGTH_SHORT).show();  
        }else if (mWifiManager.getWifiState() == 0) {  
            Toast.makeText(context,"親,Wifi正在關閉,不用再關了", Toast.LENGTH_SHORT).show();  
        }else{  
            Toast.makeText(context,"請從新關閉", Toast.LENGTH_SHORT).show();  
        }  
    }    
    
    // 檢查當前WIFI狀態     
    public void checkState(Context context) {    
        if (mWifiManager.getWifiState() == 0) {  
            Toast.makeText(context,"Wifi正在關閉", Toast.LENGTH_SHORT).show();  
        } else if (mWifiManager.getWifiState() == 1) {  
            Toast.makeText(context,"Wifi已經關閉", Toast.LENGTH_SHORT).show();  
        } else if (mWifiManager.getWifiState() == 2) {  
            Toast.makeText(context,"Wifi正在開啓", Toast.LENGTH_SHORT).show();  
        } else if (mWifiManager.getWifiState() == 3) {  
            Toast.makeText(context,"Wifi已經開啓", Toast.LENGTH_SHORT).show();  
        } else {  
            Toast.makeText(context,"沒有獲取到WiFi狀態", Toast.LENGTH_SHORT).show();  
        }    
    }    
    
    // 鎖定WifiLock     
    public void acquireWifiLock() {    
        mWifiLock.acquire();    
    }    
    
    // 解鎖WifiLock     
    public void releaseWifiLock() {    
        // 判斷時候鎖定     
        if (mWifiLock.isHeld()) {    
            mWifiLock.acquire();    
        }    
    }    
    
    // 建立一個WifiLock     
    public void creatWifiLock() {    
        mWifiLock = mWifiManager.createWifiLock("Test");    
    }    
    
    // 獲得配置好的網絡     
    public List<WifiConfiguration> getConfiguration() {    
        return mWifiConfiguration;    
    }    
    
    // 指定配置好的網絡進行鏈接     
    public void connectConfiguration(int index) {    
        // 索引大於配置好的網絡索引返回     
        if (index > mWifiConfiguration.size()) {    
            return;    
        }    
        // 鏈接配置好的指定ID的網絡     
        mWifiManager.enableNetwork(mWifiConfiguration.get(index).networkId,    
                true);    
    }    
    
    public void startScan(Context context) {    
        mWifiManager.startScan();    
        // 獲得掃描結果     
        mWifiList = mWifiManager.getScanResults();    
        // 獲得配置好的網絡鏈接     
        mWifiConfiguration = mWifiManager.getConfiguredNetworks();   
        if (mWifiList == null) {  
            if(mWifiManager.getWifiState()==3){  
                Toast.makeText(context,"當前區域沒有無線網絡", Toast.LENGTH_SHORT).show();  
            }else if(mWifiManager.getWifiState()==2){  
                Toast.makeText(context,"WiFi正在開啓,請稍後從新點擊掃描", Toast.LENGTH_SHORT).show();  
            }else{  
                Toast.makeText(context,"WiFi沒有開啓,沒法掃描", Toast.LENGTH_SHORT).show();  
            }  
        }  
    }    
    
    // 獲得網絡列表     
    public List<ScanResult> getWifiList() {    
        return mWifiList;    
    }    
    
    // 查看掃描結果     
    public StringBuilder lookUpScan() {    
        StringBuilder stringBuilder = new StringBuilder();    
        for (int i = 0; i < mWifiList.size(); i++) {    
            stringBuilder    
                    .append("Index_" + new Integer(i + 1).toString() + ":");    
            // 將ScanResult信息轉換成一個字符串包     
            // 其中把包括:BSSID、SSID、capabilities、frequency、level     
            stringBuilder.append((mWifiList.get(i)).toString());    
            stringBuilder.append("/n");    
        }    
        return stringBuilder;    
    }   
    
    // 獲得MAC地址     
    public String getMacAddress() {    
        return (mWifiInfo == null) ? "NULL" : mWifiInfo.getMacAddress();    
    }    
    
    // 獲得接入點的BSSID     
    public String getBSSID() {    
        return (mWifiInfo == null) ? "NULL" : mWifiInfo.getBSSID();    
    }    
    
    // 獲得IP地址     
    public int getIPAddress() {    
        return (mWifiInfo == null) ? 0 : mWifiInfo.getIpAddress();    
    }    
    
    // 獲得鏈接的ID     
    public int getNetworkId() {    
        return (mWifiInfo == null) ? 0 : mWifiInfo.getNetworkId();    
    }    
    
    // 獲得WifiInfo的全部信息包     
    public String getWifiInfo() {    
        return (mWifiInfo == null) ? "NULL" : mWifiInfo.toString();    
    }    
    
    // 添加一個網絡並鏈接     
    public void addNetwork(WifiConfiguration wcg) {    
     int wcgID = mWifiManager.addNetwork(wcg);    
     boolean b =  mWifiManager.enableNetwork(wcgID, true);    
     System.out.println("a--" + wcgID);   
     System.out.println("b--" + b);   
    }    
    
    // 斷開指定ID的網絡     
    public void disconnectWifi(int netId) {    
        mWifiManager.disableNetwork(netId);    
        mWifiManager.disconnect();    
    }  
    public void removeWifi(int netId) {  
        disconnectWifi(netId);  
        mWifiManager.removeNetwork(netId);  
    }  
    
//而後是一個實際應用方法,只驗證過沒有密碼的狀況:   
    
    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 + "\"";      
             
          WifiConfiguration tempConfig = this.IsExsits(SSID);              
          if(tempConfig != null) {     
              mWifiManager.removeNetwork(tempConfig.networkId);     
          }   
             
          if(Type == 1) //WIFICIPHER_NOPASS   
          {    
               config.wepKeys[0] = "";    
               config.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE);    
               config.wepTxKeyIndex = 0;    
          }    
          if(Type == 2) //WIFICIPHER_WEP   
          {    
              config.hiddenSSID = true;   
              config.wepKeys[0]= "\""+Password+"\"";    
              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;    
          }    
          if(Type == 3) //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.allowedProtocols.set(WifiConfiguration.Protocol.WPA);     
          config.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.CCMP);   
          config.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.CCMP);   
          config.status = WifiConfiguration.Status.ENABLED;      
          }   
           return config;    
    }    
       
    private WifiConfiguration IsExsits(String SSID)     
    {     
        List<WifiConfiguration> existingConfigs = mWifiManager.getConfiguredNetworks();     
           for (WifiConfiguration existingConfig : existingConfigs)      
           {     
             if (existingConfig.SSID.equals("\""+SSID+"\""))     
             {     
                 return existingConfig;     
             }     
           }     
        return null;      
    }   
}

如圖所示:

image.png

倆bug

這些代碼看起來沒有什麼問題,可是經過不一樣環境的測試,發現了一些問題。

1 測試到的wifi熱點,有的ssid爲」「,也就是ssid != null,獲取不到said。

2 wifi列表中有許多同名的wifi熱點,也就是掃描的結果中有重合部分,並非有多個同名的wifi熱點。

第一個問題ssid爲「」,這個看設置中並無多餘wifi,但這個熱點點其它信息能夠獲取到,說明這個熱點是存在的,應該是該熱點隱藏了,因此獲取不到。這也就是手機設置中爲何會有添加網路的按鈕了。

第二個問題,當附近wifi熱點比較少時不會出現此問題,當附近wifi網絡比較多時會出現此問題。這就須要將同名的熱點進行刪除,可是若是真有兩個ssid名相同的wifi,那就能夠經過capabilities去區分吧,若是capabilities也相同就沒辦法了,系統設置裏面也不顯示同名的。

修改上面的方法 startScan()。

public void startScan(Context context) {    
    mWifiManager.startScan();  
       //獲得掃描結果   
    List<ScanResult> results = mWifiManager.getScanResults();   
    // 獲得配置好的網絡鏈接   
    mWifiConfiguration = mWifiManager.getConfiguredNetworks();   
    if (results == null) {  
        if(mWifiManager.getWifiState()==3){  
            Toast.makeText(context,"當前區域沒有無線網絡",Toast.LENGTH_SHORT).show();  
        }else if(mWifiManager.getWifiState()==2){  
            Toast.makeText(context,"wifi正在開啓,請稍後掃描", Toast.LENGTH_SHORT).show();  
        }else{Toast.makeText(context,"WiFi沒有開啓", Toast.LENGTH_SHORT).show();  
        }  
    } else {  
    mWifiList = new ArrayList();  
    for(ScanResult result : results){   
        if (result.SSID == null || result.SSID.length() == 0 || result.capabilities.contains("[IBSS]")) {  
            continue;  
        }  
        boolean found = false;  
        for(ScanResult item:mWifiList){   
                    if(item.SSID.equals(result.SSID)&&item.capabilities.equals(result.capabilities)){  
                found = true;break;   
            }  
        }   
        if(!found){  
            mWifiList.add(result);  
        }   
    }   
    }   
}

這樣就能夠避免出現上面的兩種狀況了。

image.png

代碼:

public class MainActivity extends Activity implements OnClickListener {  
    public static final String TAG = "MainActivity";  
    private Button check_wifi,open_wifi,close_wifi,scan_wifi;  
    private ListView mlistView;  
    protected WifiAdmin mWifiAdmin;  
    private List<ScanResult> mWifiList;  
    public int level;  
    protected String ssid;  
      
    protected void onCreate(Bundle savedInstanceState) {  
        super.onCreate(savedInstanceState);  
        setContentView(R.layout.activity_main);  
        mWifiAdmin = new WifiAdmin(MainActivity.this);  
        initViews();  
        IntentFilter filter = new IntentFilter(  
                WifiManager.NETWORK_STATE_CHANGED_ACTION);  
        //="android.net.wifi.STATE_CHANGE"  監聽wifi狀態的變化  
        registerReceiver(mReceiver, filter);  
        mlistView.setOnItemClickListener(new OnItemClickListener() {  
            @Override  
            public void onItemClick(AdapterView<?> parent, View view,  
                    int position, long id) {  
                AlertDialog.Builder alert=new AlertDialog.Builder(MainActivity.this);  
                ssid=mWifiList.get(position).SSID;  
                alert.setTitle(ssid);  
                alert.setMessage("輸入密碼");  
                final EditText et_password=new EditText(MainActivity.this);  
                final SharedPreferences preferences=getSharedPreferences("wifi_password",Context.MODE_PRIVATE);  
                et_password.setText(preferences.getString(ssid, ""));  
                alert.setView(et_password);  
                //alert.setView(view1);  
                alert.setPositiveButton("鏈接", new DialogInterface.OnClickListener(){  
                    @Override  
                    public void onClick(DialogInterface dialog, int which) {  
                        String pw = et_password.getText().toString();  
                        if(null == pw  || pw.length() < 8){  
                                    Toast.makeText(MainActivity.this, "密碼至少8位", Toast.LENGTH_SHORT).show();  
                                return;      
                            }  
                            Editor editor=preferences.edit();  
                            editor.putString(ssid, pw);   //保存密碼  
                            editor.commit();          
                        mWifiAdmin.addNetwork(mWifiAdmin.CreateWifiInfo(ssid, et_password.getText().toString(), 3));  
                    }  
                });  
                alert.setNegativeButton("取消", new DialogInterface.OnClickListener(){  
                    @Override  
                    public void onClick(DialogInterface dialog, int which) {  
                        //  
                        //mWifiAdmin.removeWifi(mWifiAdmin.getNetworkId());  
                    }  
                });  
                alert.create();  
                alert.show();  
                  
            }  
        });  
    }  
      
    /* 
     * 控件初始化 
     * */  
    private void initViews() {  
        check_wifi=(Button) findViewById(R.id.check_wifi);  
        open_wifi=(Button) findViewById(R.id.open_wifi);  
        close_wifi=(Button) findViewById(R.id.close_wifi);  
        scan_wifi=(Button) findViewById(R.id.scan_wifi);  
        mlistView=(ListView) findViewById(R.id.wifi_list);                
        check_wifi.setOnClickListener(MainActivity.this);  
        open_wifi.setOnClickListener(MainActivity.this);  
        close_wifi.setOnClickListener(MainActivity.this);  
        scan_wifi.setOnClickListener(MainActivity.this);  
    }  
  
    @Override  
    public void onClick(View v) {  
        switch (v.getId()) {  
        case R.id.check_wifi:  
            mWifiAdmin.checkState(MainActivity.this);  
            break;  
        case R.id.open_wifi:  
            mWifiAdmin.openWifi(MainActivity.this);  
            break;  
        case R.id.close_wifi:  
            mWifiAdmin.closeWifi(MainActivity.this);  
            break;  
        case R.id.scan_wifi:  
            mWifiAdmin.startScan(MainActivity.this);  
            mWifiList=mWifiAdmin.getWifiList();  
            if(mWifiList!=null){  
                mlistView.setAdapter(new MyAdapter(this,mWifiList));  
                new Utility().setListViewHeightBasedOnChildren(mlistView);  
            }  
            break;  
        default:  
            break;  
        }  
    }  
      
    public class MyAdapter extends BaseAdapter{  
        LayoutInflater inflater;  
        List<ScanResult> list;  
        public MyAdapter(Context context, List<ScanResult> list){  
            this.inflater=LayoutInflater.from(context);  
            this.list=list;  
        }  
        @Override  
        public int getCount() {  
            return list.size();  
        }  
        @Override  
        public Object getItem(int position) {  
            return position;  
        }  
        @Override  
        public long getItemId(int position) {  
            return position;  
        }  
        @SuppressLint({ "ViewHolder", "InflateParams" })  
        @Override  
        public View getView(int position, View convertView, ViewGroup parent) {  
            View view=null;  
            view=inflater.inflate(R.layout.wifi_listitem, null);  
            ScanResult scanResult = list.get(position);  
            TextView wifi_ssid=(TextView) view.findViewById(R.id.ssid);  
            ImageView wifi_level=(ImageView) view.findViewById(R.id.wifi_level);  
            wifi_ssid.setText(scanResult.SSID);  
            Log.i(TAG, "scanResult.SSID="+scanResult);  
            level=WifiManager.calculateSignalLevel(scanResult.level,5);  
            if(scanResult.capabilities.contains("WEP")||scanResult.capabilities.contains("PSK")||  
                    scanResult.capabilities.contains("EAP")){  
                wifi_level.setImageResource(R.drawable.wifi_signal_lock);  
            }else{  
                wifi_level.setImageResource(R.drawable.wifi_signal_open);  
            }  
            wifi_level.setImageLevel(level);  
            //判斷信號強度,顯示對應的指示圖標    
             return view;  
        }  
    }  
  
    /*設置listview的高度*/  
    public class Utility {   
        public void setListViewHeightBasedOnChildren(ListView listView) {   
            ListAdapter listAdapter = listView.getAdapter();    
            if (listAdapter == null) {   
                return;   
            }   
            int totalHeight = 0;   
            for (int i = 0; i < listAdapter.getCount(); i++) {   
                View listItem = listAdapter.getView(i, null, listView);   
                listItem.measure(0, 0);   
                totalHeight += listItem.getMeasuredHeight();   
            }   
            ViewGroup.LayoutParams params = listView.getLayoutParams();   
            params.height = totalHeight + (listView.getDividerHeight() * (listAdapter.getCount() - 1));   
            listView.setLayoutParams(params);   
        }   
    }  
    //監聽wifi狀態  
    private BroadcastReceiver mReceiver = new BroadcastReceiver (){    
        @Override    
        public void onReceive(Context context, Intent intent) {     
            ConnectivityManager manager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);    
  
            NetworkInfo wifiInfo = manager.getNetworkInfo(ConnectivityManager.TYPE_WIFI);     
            if(wifiInfo.isConnected()){  
                WifiManager wifiManager = (WifiManager) context  
                        .getSystemService(Context.WIFI_SERVICE);  
                String wifiSSID = wifiManager.getConnectionInfo()  
                        .getSSID();  
                Toast.makeText(context, wifiSSID+"鏈接成功", 1).show();  
            }                  
        }     
        
    };   
}

二、相關類說明補充

ScanResult類

image.png

這個類主要是經過Wifi硬件的掃描來獲取一些周邊的wifi熱點(access point)的信息。該類主要有5個域,

image.png

打印信息以下所示:

image.png

WifiConfiguration類

經過該類獲取一個wifi網絡的網絡配置,包括安全配置等。它包含6個子類,以下所示:

image.png

該類內容較多,不一一例舉,須要用到的時候能夠查Android SDK。

WifiInfo類

image.png

該類能夠得到已經創建的或處於活動狀態的wifi網絡的狀態信息。經常使用方法以下:

image.png

image.png

代碼:

mWifiManager = (WifiManager)getSystemService(Context.WIFI_SERVICE);     
mWifiInfo = mWifiManager.getConnectionInfo();  
if(null != mWifiInfo && null != mWifiInfo.getSSID()){  
        String info = "getSSID()="+mWifiInfo.getSSID()+"\n"  
                +"getBSSID()="+mWifiInfo.getBSSID()+"\n"  
                +"getHiddenSSID()="+mWifiInfo.getHiddenSSID()+"\n"  
                +"getLinkSpeed()="+mWifiInfo.getLinkSpeed()+"\n"  
                +"getMacAddress()="+mWifiInfo.getMacAddress()+"\n"  
                +"getNetworkId()="+mWifiInfo.getNetworkId()+"\n"  
                +"getRssi()="+mWifiInfo.getRssi()+"\n"  
                +"getSupplicantState()="+mWifiInfo.getSupplicantState()+"\n"  
                +"getDetailedStateOf()="+mWifiInfo.getDetailedStateOf(mWifiInfo.getSupplicantState());  
        mTVWifiInfo.setText(info);  
}else {  
        mTVWifiInfo.setText("沒有鏈接到wifi");  
}

 

WifiManager類

該類用於管理Wifi鏈接,定義了許多常量和方法,這裏就不一一說了。

經常使用方法。

20160304133401314.jpg

須要指出的是getWifiState()方法是反悔wifi的狀態,有整型常量表示,

image.png

4、Android WiFi開發 (二)Wifi熱點

這個章節主要說一下手機開啓Wifi熱點。

demo的下載地址會在最下面貼出來。

image.png

一、建立WiFi熱點

經測試開啓wifi熱點(無祕密,wpa安全類型,wpa2安全類型)均可以正常開啓並使用。

須要注意的是wifi和wifi熱點不能同時打開,也就是鏈接wifi的時候,開啓熱點須要先將wifi關閉才能夠。

用到的主要代碼:

package com.vn.wifitest.utils;  
  
  
import java.lang.reflect.InvocationTargetException;  
import java.lang.reflect.Method;  
import android.content.BroadcastReceiver;  
import android.content.Context;  
import android.content.Intent;  
import android.content.IntentFilter;  
import android.net.wifi.WifiConfiguration;  
import android.net.wifi.WifiConfiguration.KeyMgmt;  
import android.net.wifi.WifiManager;  
import android.os.Handler;  
import android.util.Log;  
  
public class WifiAPUtil {  
    private static final String TAG = "WifiAPUtil";  
    public final static boolean DEBUG = true;  
  
    public static final int MESSAGE_AP_STATE_ENABLED = 1;  
    public static final int MESSAGE_AP_STATE_FAILED = 2;  
    //默認wifi祕密  
    private static final String DEFAULT_AP_PASSWORD = "12345678";     
    private static WifiAPUtil sInstance;  
    private static Handler mHandler;  
    private static Context mContext;  
    private WifiManager mWifiManager;  
    //監聽wifi熱點的狀態變化  
    public static final String WIFI_AP_STATE_CHANGED_ACTION = "android.net.wifi.WIFI_AP_STATE_CHANGED";  
    public static final String EXTRA_WIFI_AP_STATE = "wifi_state";  
    public static int WIFI_AP_STATE_DISABLING = 10;  
    public static int WIFI_AP_STATE_DISABLED = 11;  
    public static int WIFI_AP_STATE_ENABLING = 12;  
    public static int WIFI_AP_STATE_ENABLED = 13;  
    public static int WIFI_AP_STATE_FAILED = 14;  
    public enum WifiSecurityType {  
        WIFICIPHER_NOPASS, WIFICIPHER_WPA, WIFICIPHER_WEP, WIFICIPHER_INVALID, WIFICIPHER_WPA2  
    }  
    private WifiAPUtil(Context context) {  
        if(DEBUG) Log.d(TAG,"WifiAPUtils construct");   
        mContext = context;  
        mWifiManager = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);  
        IntentFilter filter = new IntentFilter();  
        filter.addAction(WIFI_AP_STATE_CHANGED_ACTION);  
        context.registerReceiver(mWifiStateBroadcastReceiver, filter);  
    }  
    protected void finalize() {  
        if(DEBUG) Log.d(TAG,"finalize");  
        mContext.unregisterReceiver(mWifiStateBroadcastReceiver);  
  
}  
    public static WifiAPUtil getInstance(Context c) {  
        if (null == sInstance)  
            sInstance = new WifiAPUtil(c);  
        return sInstance;  
    }  
  
    public boolean turnOnWifiAp(String str, String password,WifiSecurityType Type) {  
        String ssid = str;  
        //配置熱點信息。  
        WifiConfiguration wcfg = new WifiConfiguration();  
        wcfg.SSID = new String(ssid);  
        wcfg.networkId = 1;  
        wcfg.allowedAuthAlgorithms.clear();  
        wcfg.allowedGroupCiphers.clear();  
        wcfg.allowedKeyManagement.clear();  
        wcfg.allowedPairwiseCiphers.clear();  
        wcfg.allowedProtocols.clear();  
          
        if(Type == WifiSecurityType.WIFICIPHER_NOPASS) {  
            if(DEBUG)Log.d(TAG, "wifi ap----no password");  
            wcfg.allowedAuthAlgorithms.set(WifiConfiguration.AuthAlgorithm.OPEN, true);  
            wcfg.wepKeys[0] = "";      
            wcfg.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE);      
            wcfg.wepTxKeyIndex = 0;  
        } else if(Type == WifiSecurityType.WIFICIPHER_WPA) {  
            if(DEBUG)Log.d(TAG, "wifi ap----wpa");  
            //密碼至少8位,不然使用默認密碼  
            if(null != password && password.length() >= 8){  
                wcfg.preSharedKey = password;  
            } else {  
                wcfg.preSharedKey = DEFAULT_AP_PASSWORD;  
            }  
            wcfg.hiddenSSID = false;         
            wcfg.allowedAuthAlgorithms.set(WifiConfiguration.AuthAlgorithm.OPEN);         
            wcfg.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.TKIP);                               
            wcfg.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_PSK);       
            //wcfg.allowedKeyManagement.set(4);  
            wcfg.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.TKIP);                          
            wcfg.allowedProtocols.set(WifiConfiguration.Protocol.WPA);        
            wcfg.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.CCMP);      
            wcfg.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.CCMP);      
        } else if(Type == WifiSecurityType.WIFICIPHER_WPA2) {  
            if(DEBUG)Log.d(TAG, "wifi ap---- wpa2");  
            //密碼至少8位,不然使用默認密碼  
            if(null != password && password.length() >= 8){  
                wcfg.preSharedKey = password;  
            } else {  
                wcfg.preSharedKey = DEFAULT_AP_PASSWORD;  
            }       
            wcfg.hiddenSSID = true;         
            wcfg.allowedAuthAlgorithms.set(WifiConfiguration.AuthAlgorithm.OPEN);         
            wcfg.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.TKIP);                               
            wcfg.allowedKeyManagement.set(4);       
            //wcfg.allowedKeyManagement.set(4);  
            wcfg.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.TKIP);                          
            wcfg.allowedProtocols.set(WifiConfiguration.Protocol.WPA);        
            wcfg.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.CCMP);      
            wcfg.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.CCMP);      
        }         
        try {  
            Method method = mWifiManager.getClass().getMethod("setWifiApConfiguration",   
                                      wcfg.getClass());  
            Boolean rt = (Boolean)method.invoke(mWifiManager, wcfg);  
            if(DEBUG) Log.d(TAG, " rt = " + rt);  
        } catch (NoSuchMethodException e) {  
            Log.e(TAG, e.getMessage());  
        } catch (IllegalArgumentException e) {  
            Log.e(TAG, e.getMessage());  
        } catch (IllegalAccessException e) {  
            Log.e(TAG, e.getMessage());  
        } catch (InvocationTargetException e) {  
            Log.e(TAG, e.getMessage());  
        }  
        return setWifiApEnabled();  
    }  
    //獲取熱點狀態      
    public int getWifiAPState() {  
        int state = -1;  
        try {  
            Method method2 = mWifiManager.getClass().getMethod("getWifiApState");  
            state = (Integer) method2.invoke(mWifiManager);  
        } catch (Exception e) {  
            Log.e(TAG, e.getMessage());  
        }  
        if(DEBUG)Log.i("WifiAP", "getWifiAPState.state " + state);  
        return state;  
    }  
      
    private boolean setWifiApEnabled() {          
        //開啓wifi熱點須要關閉wifi  
        while(mWifiManager.getWifiState() != WifiManager.WIFI_STATE_DISABLED){  
            mWifiManager.setWifiEnabled(false);  
            try {  
                Thread.sleep(200);  
            } catch (Exception e) {  
                Log.e(TAG, e.getMessage());  
                return false;  
            }  
        }  
        // 確保wifi 熱點關閉。  
        while(getWifiAPState() != WIFI_AP_STATE_DISABLED){  
            try {  
            Method method1 = mWifiManager.getClass().getMethod("setWifiApEnabled",  
                       WifiConfiguration.class, boolean.class);  
            method1.invoke(mWifiManager, null, false);  
          
                Thread.sleep(200);  
            } catch (Exception e) {  
                Log.e(TAG, e.getMessage());  
                    return false;  
            }  
        }  
          
        //開啓wifi熱點  
        try {  
        Method method1 = mWifiManager.getClass().getMethod("setWifiApEnabled",  
                       WifiConfiguration.class, boolean.class);  
        method1.invoke(mWifiManager, null, true);         
                Thread.sleep(200);  
            } catch (Exception e) {  
                Log.e(TAG, e.getMessage());  
                    return false;  
            }  
        return true;  
    }     
     //關閉WiFi熱點     
    public void closeWifiAp() {          
        if (getWifiAPState() != WIFI_AP_STATE_DISABLED) {      
            try {      
                Method method = mWifiManager.getClass().getMethod("getWifiApConfiguration");      
                method.setAccessible(true);      
                WifiConfiguration config = (WifiConfiguration) method.invoke(mWifiManager);      
                Method method2 = mWifiManager.getClass().getMethod("setWifiApEnabled", WifiConfiguration.class, boolean.class);      
                method2.invoke(mWifiManager, config, false);      
            } catch (NoSuchMethodException e) {      
                e.printStackTrace();      
            } catch (IllegalArgumentException e) {      
                e.printStackTrace();      
            } catch (IllegalAccessException e) {      
                e.printStackTrace();      
            } catch (InvocationTargetException e) {      
                e.printStackTrace();      
            }      
        }     
    }    
  
    public void regitsterHandler(Handler handler){  
        mHandler = handler;  
    }  
    public void unregitsterHandler(){  
        mHandler = null;  
    }  
    //監聽wifi熱點狀態變化  
    private BroadcastReceiver mWifiStateBroadcastReceiver = new BroadcastReceiver() {             
        @Override  
        public void onReceive(Context context, Intent intent) {  
        if(DEBUG)Log.i(TAG,"WifiAPUtils onReceive: "+intent.getAction());  
        if(WIFI_AP_STATE_CHANGED_ACTION.equals(intent.getAction())) {  
            int cstate = intent.getIntExtra(EXTRA_WIFI_AP_STATE, -1);  
            if(cstate == WIFI_AP_STATE_ENABLED) {  
                if(mHandler != null){  
                    mHandler.sendEmptyMessage(MESSAGE_AP_STATE_ENABLED);                  
                }  
            }if(cstate == WIFI_AP_STATE_DISABLED  || cstate == WIFI_AP_STATE_FAILED) {  
            if(mHandler != null)  
                mHandler.sendEmptyMessage(MESSAGE_AP_STATE_FAILED);  
            }  
        }  
        }  
    };  
    //獲取熱點ssid  
    public String getValidApSsid() {  
        try {  
            Method method = mWifiManager.getClass().getMethod("getWifiApConfiguration");  
            WifiConfiguration configuration = (WifiConfiguration)method.invoke(mWifiManager);  
            return configuration.SSID;    
        } catch (Exception e) {  
                Log.e(TAG, e.getMessage());  
                return null;  
                }  
    }  
    //獲取熱點密碼  
    public String getValidPassword(){  
        try {  
            Method method = mWifiManager.getClass().getMethod("getWifiApConfiguration");  
            WifiConfiguration configuration = (WifiConfiguration)method.invoke(mWifiManager);  
            return configuration.preSharedKey;    
        } catch (Exception e) {  
                Log.e(TAG, e.getMessage());  
                return null;  
                }  
      
    }  
    //獲取熱點安全類型  
    public int getValidSecurity(){  
        WifiConfiguration configuration;  
        try {  
            Method method = mWifiManager.getClass().getMethod("getWifiApConfiguration");  
            configuration = (WifiConfiguration)method.invoke(mWifiManager);  
        } catch (Exception e) {  
                Log.e(TAG, e.getMessage());  
                return WifiSecurityType.WIFICIPHER_INVALID.ordinal();  
                }  
          
        if(DEBUG)Log.i(TAG,"getSecurity security="+configuration.allowedKeyManagement);  
        if(configuration.allowedKeyManagement.get(KeyMgmt.NONE)) {  
            return WifiSecurityType.WIFICIPHER_NOPASS.ordinal();  
        }else if(configuration.allowedKeyManagement.get(KeyMgmt.WPA_PSK)) {  
            return WifiSecurityType.WIFICIPHER_WPA.ordinal();  
        }else if(configuration.allowedKeyManagement.get(4)) { //4 means WPA2_PSK   
            return WifiSecurityType.WIFICIPHER_WPA2.ordinal();  
        }  
        return WifiSecurityType.WIFICIPHER_INVALID.ordinal();  
    }  
}

使用方法:

使用方法:

//初始化WifiAPUtil類  
WifiAPUtil.getInstance(getApplicationContext())  
//註冊handler  
WifiAPUtil.getInstance(this).regitsterHandler(mHandler);  
//接收message,作處理  
private Handler mHandler = new Handler(){  
    public void handleMessage(Message msg) {  
        switch (msg.what) {  
            case WifiAPUtil.MESSAGE_AP_STATE_ENABLED:  
                String ssid = WifiAPUtil.getInstance(WifiApActivity.this).getValidApSsid();  
                String pw = WifiAPUtil.getInstance(WifiApActivity.this).getValidPassword();  
                int security = WifiAPUtil.getInstance(WifiApActivity.this).getValidSecurity();  
                mWifiApState.setText("wifi熱點開啓成功"+"\n"  
                        +"SSID = "+ssid+"\n"  
                        +"Password = "+pw +"\n"  
                        +"Security = "+security);  
                break;  
            case WifiAPUtil.MESSAGE_AP_STATE_FAILED:  
                mWifiApState.setText("wifi熱點關閉");  
                break;  
            default:  
                break;  
        }  
    }  
};

在activity銷燬的時候

@Override  
protected void onDestroy() {  
    super.onDestroy();  
    WifiAPUtil.getInstance(this).unregitsterHandler();  
}

添加點擊事件

//開啓wifi熱點  
WifiAPUtil.getInstance(WifiApActivity.this).turnOnWifiAp(ssid, password, mWifiType);
//關閉wifi熱點  
WifiAPUtil.getInstance(WifiApActivity.this).closeWifiAp();

二、監聽熱點的狀態

當wifi熱點狀態發送變化,系統會發送廣播 Android.net.wifi.WIFI_AP_STATE_CHANGED,因此咱們只要註冊監聽這個廣播就能夠了。

wifi ap狀態值。

public static final String EXTRA_WIFI_AP_STATE = "wifi_state";  
public static int WIFI_AP_STATE_DISABLING = 10;  
public static int WIFI_AP_STATE_DISABLED = 11;  
public static int WIFI_AP_STATE_ENABLING = 12;  
public static int WIFI_AP_STATE_ENABLED = 13;  
public static int WIFI_AP_STATE_FAILED = 14;

動態註冊

public static final String WIFI_AP_STATE_CHANGED_ACTION = "android.net.wifi.WIFI_AP_STATE_CHANGED";  
//註冊廣播接收者  
IntentFilter filter = new IntentFilter();  
filter.addAction(WIFI_AP_STATE_CHANGED_ACTION);  
context.registerReceiver(mWifiStateBroadcastReceiver, filter);

廣播接收者

經過監聽wifiap狀態的變化,發送消息給相關activity

//監聽wifi熱點狀態變化  
private BroadcastReceiver mWifiStateBroadcastReceiver = new BroadcastReceiver() {             
    @Override  
        public void onReceive(Context context, Intent intent) {  
    if(DEBUG)Log.i(TAG,"WifiAPUtils onReceive: "+intent.getAction());  
    if(WIFI_AP_STATE_CHANGED_ACTION.equals(intent.getAction())) {  
            int cstate = intent.getIntExtra(EXTRA_WIFI_AP_STATE, -1);  
            if(cstate == WIFI_AP_STATE_ENABLED) {  
                if(mHandler != null){  
                    mHandler.sendEmptyMessage(MESSAGE_AP_STATE_ENABLED);                  
                }  
            }if(cstate == WIFI_AP_STATE_DISABLED  || cstate == WIFI_AP_STATE_FAILED) {  
            if(mHandler != null)  
                mHandler.sendEmptyMessage(MESSAGE_AP_STATE_FAILED);  
            }  
        }  
     }  
};

三、遺留問題

在配置wificonfiguration的時候有過屬性是hiddenSSID,這個是設置wifi熱點AP是否隱藏的,

可是設置wcfg.hiddenSSID = true或false並無發現有什麼不一樣,按理說設置爲true,ssid隱藏應該搜索不到這個熱點,

可是均可以搜索到。還請知道的能夠留言指教,十分感謝。

以前有朋友說5.0系統的開啓熱點有問題,我這裏沒有5.0的手機,使用華爲p9Android6.0手機測試確實開啓不了熱點,須要添加write_settings,添加上此權限就能夠成功開啓了。

5、其餘補充

沒有

 

 

注:本文著做權歸做者,由demo大師發表,拒絕轉載,轉載須要做者受權

相關文章
相關標籤/搜索