声波配网研究

最近公司再做智能音箱项目。准备airkiss和声波配网进行二选一。airkiss是通过wifi广播的形式进行传输ssid和pwd。测试下来抗干扰性好。声波配网简单。不需要有wifi只要有mic输入解码即可,所以自己移植了网址
http://www.sinvoice.com/上面的Android sdk进行声波联网测试。
这里写图片描述
这个公司由于收费牵扯到版权。所以有商业化用到他们公司产品请联系sinvoice公司。本人开发只是做简单的测试。
有关声波配网的原理和介绍网上很多。所以这里不多介绍。
本文代码主要由两部分组成–声波编码和解码 和 wifi联网,声波编解码主要是sinvoice公司的代码可以到这个网址下载http://www.sinvoice.com/。我下载的是
SinVoice_Android_v2.2
这个SinVoice_Android_v2.2 版本。

package com.example.sinvoicedemo;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.text.SimpleDateFormat;
import java.util.Date;
import android.net.wifi.WifiConfiguration;
import android.net.wifi.WifiInfo;
import android.net.wifi.WifiManager;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.os.Bundle;
import android.os.Environment;
import android.os.Handler;
import android.os.Message;
import android.os.PowerManager;
import android.text.method.ScrollingMovementMethod;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.CompoundButton;
import android.widget.CompoundButton.OnCheckedChangeListener;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;

import com.libra.sinvoice.Common;
import com.libra.sinvoice.LogHelper;
import com.libra.sinvoice.SinVoicePlayer;
import com.libra.sinvoice.SinVoiceRecognition;
import com.libra.sinvoice.WifiAutoConnectManager;

public class MainActivity extends Activity implements
        SinVoiceRecognition.Listener, SinVoicePlayer.Listener ,WifiAutoConnectManager.WifiConnectListenner{
    private final static String TAG = "MainActivityxx";

    private final static int MSG_SET_RECG_TEXT = 1;
    private final static int MSG_RECG_START = 2;
    private final static int MSG_RECG_END = 3;
    private final static int MSG_PLAY_TEXT = 4;

    private final static int[] TOKENS = { 32, 32, 32, 32, 32, 32 };
    private final static String TOKENS_str = "Beeba20141";
    private final static int TOKEN_LEN = TOKENS.length;

    private final static String BAKCUP_LOG_PATH = "/sinvoice_backup";

    private Handler mHanlder;
    private SinVoicePlayer mSinVoicePlayer;
    private SinVoiceRecognition mRecognition;
    private WifiAutoConnectManager mWifiConnectManager;
    //这个是我自己加的主要用于wifi联网的管理
    private boolean mIsReadFromFile;
    private String mSdcardPath;
    private PowerManager.WakeLock mWakeLock;
    private EditText mPlayTextView;
    private EditText mPlayTextView1;
    private TextView mRecognisedTextView;
    // private TextView mRegState;
    private String mPlayText;
    private char mRecgs[] = new char[100];
    private int mRecgCount;

    static {
        System.loadLibrary("sinvoice");
        LogHelper.d(TAG, "sinvoice jnicall loadlibrary");
    }
//真正的编解码主要通过c语音库进行处理的。java代码只是做逻辑处理
//所以这里加载编解码库
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        mIsReadFromFile = false;
        WifiManager wifiManager = (WifiManager) getSystemService(Context.WIFI_SERVICE); 
        PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE);
        mWakeLock = pm.newWakeLock(PowerManager.SCREEN_DIM_WAKE_LOCK, TAG);

        mSdcardPath = Environment.getExternalStorageDirectory().getPath();

        mSinVoicePlayer = new SinVoicePlayer();
        mSinVoicePlayer.init(this);
        mSinVoicePlayer.setListener(this);
//编码器初始化
        mWifiConnectManager = new WifiAutoConnectManager(wifiManager);
        mWifiConnectManager.setListenner(this);
        //wifi管理初始化
        mRecognition = new SinVoiceRecognition();
        mRecognition.init(this);
        mRecognition.setListener(this);
        mRecognition.start(TOKEN_LEN, mIsReadFromFile);
//解码器初始化
        mPlayTextView = (EditText) findViewById(R.id.playtext);
        mPlayTextView.setMovementMethod(ScrollingMovementMethod.getInstance());
        mPlayTextView1 = (EditText) findViewById(R.id.playtext1);
        mPlayTextView1.setMovementMethod(ScrollingMovementMethod.getInstance());
        mRecognisedTextView = (TextView) findViewById(R.id.regtext);
        mHanlder = new RegHandler(this);

        Button playStart = (Button) findViewById(R.id.start_play);
        playStart.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View arg0) {
                try {
             //      mWifiConnectManager.connect("lvbiao","lb123456",WifiCipherType.WIFICIPHER_WPA);
                    Log.e("PP","come here");
                    StringBuilder sb=new StringBuilder();
                    byte[] strs = mPlayTextView.getText().toString().getBytes("UTF8");
                    byte[] strs1 = mPlayTextView1.getText().toString().getBytes("UTF8");

                    if ( null != strs ) {
                        int len = strs.length + strs1.length + 2;
                        int []tokens = new int[len];
                        int maxEncoderIndex = mSinVoicePlayer.getMaxEncoderIndex();
                        LogHelper.d(TAG, "maxEncoderIndex:" + maxEncoderIndex);
                        String encoderText = mPlayTextView.getText().toString();
                        sb.append(encoderText);
                        String encoderText1 = mPlayTextView1.getText().toString();
                        sb.append("A@");
                        sb.append(encoderText1);
                        for ( int i = 0; i < len; ++i ) {
                            if ( maxEncoderIndex < 255 ) {
                                tokens[i] = Common.DEFAULT_CODE_BOOK.indexOf(sb.charAt(i));
                            } else {
                                tokens[i] = strs[i];
                            }
                        }
                        mSinVoicePlayer.play(tokens, len, false, 2000);
                    } else {
                        mSinVoicePlayer.play(TOKENS, TOKEN_LEN, false, 2000);
                    }
                } catch (UnsupportedEncodingException e) {
                    e.printStackTrace();
                }
            }
        });

sinvoice 解码和编码是一个程序。都在主界面上。通过按键可以开启和关闭解码和编码。
这里的SinVoiceRecognition 主要完成声波的解码辅助工作,前面说过 真正的解码在so库中完成。所以SinVoiceRecognition 主要功能是录音声波。并将录音声波的文件发送给so库。然后接收解码完成的声波结果ascii装成相应的字符。

 Button recognitionStart = (Button) findViewById(R.id.start_reg);
        recognitionStart.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View arg0) {
                mRecognition.start(TOKEN_LEN, mIsReadFromFile);
            }
        });

这里打开语音识别

    public void start(final int tokenCount, final boolean isReadFromFile) {
        if (STATE_STOP == mState) {
            mState = STATE_START;

            mBufferQueue.set();

            mRecognitionThread = new Thread() {
                @Override
                public void run() {
                    mRecognition.start(tokenCount);
                }
            };
            if (null != mRecognitionThread) {
                mRecognitionThread.start();
            }

            mRecordThread = new Thread() {
                @Override
                public void run() {
                    mRecord.start(isReadFromFile);
                }
            };
            if (null != mRecordThread) {
                mRecordThread.start();
            }
        }
    }

mRecognition.start(TOKEN_LEN, mIsReadFromFile)通过开启mRecordThread进行录音和mRecognition进行解码两个线程做大部分工作。
先看mRecordThread的代码

    public void start(boolean isReadFromFile) {
        if (STATE_STOP == mState) {
            if (isReadFromFile) {
                recordFromFile();
            } else {
                recordFromDevice();
            }
        }
    }

这里没有特殊选择的话会执行recordFromDevice

private void recordFromDevice() {
        LogHelper.d(TAG, "recordFromDevice Start");

        if (mBufferSize > 0) {
            AudioRecord record = new AudioRecord(MediaRecorder.AudioSource.MIC, mSampleRate, mChannelConfig, mAudioEncoding, mBufferSize * 5);
            if (null != record) {
                try {
                    mState = STATE_START;
                    LogHelper.d(TAG, "record start");
                    record.startRecording();
                    LogHelper.d(TAG, "record start 1");

                    if (null != mCallback) {
                        if (null != mListener) {
                            mListener.onStartRecord();
                        }

                        while (STATE_START == mState) {
                            BufferData data = mCallback.getRecordBuffer();
                            if (null != data) {
                                if (null != data.mData) {
                                    int bufferReadResult = record.read(data.mData, 0, mBufferSize);
                                    LogHelper.d(TAG, "read record:" + bufferReadResult);
                                    data.setFilledSize(bufferReadResult);

                                    mCallback.freeRecordBuffer(data);
                                } else {
                                    // end of input
                                    LogHelper.d(TAG, "get end input data, so stop");
                                    break;
                                }
                            } else {
                                LogHelper.e(TAG, "get null data");
                                break;
                            }
                        }

                        if (null != mListener) {
                            mListener.onStopRecord();
                        }
                    }

                    LogHelper.d(TAG, "stop record");
                    record.stop();
                    LogHelper.d(TAG, "release record");
                    record.release();

                    LogHelper.d(TAG, "record stop");
                } catch (IllegalStateException e) {
                    e.printStackTrace();
                    LogHelper.e(TAG, "start record error");
                }
                mState = STATE_STOP;
            }
        } else {
            LogHelper.e(TAG, "bufferSize is too small");
        }

        LogHelper.d(TAG, "recordFromDevice End");
    }

主要工作就是打开一个new AudioRecord进行录音
data.setFilledSize(bufferReadResult);会把录音数据放到BufferData中
解码库会从BufferData获取录音数据进行解码。

 public void start(int tokenCount) {
        if (STATE_STOP == mState) {
            mConsumedSize = 0;

            mVoiceDecoder.initVR(mContext, "com.sinvoice.demo", "SinVoice");
            //开启语音识别器。这是native方法。打开的是c语言中的解码器
            LogHelper.d(
                    TAG,
                    "Voice Recogintiono start threadid:"
                            + Thread.currentThread());
            if (null != mCallback) {
                mState = STATE_START;

                if (null != mListener) {
                    mListener.onStartRecognition();
                }
                try {
                    String sdcardPath = Environment.getExternalStorageDirectory().getPath();
                    if ( !TextUtils.isEmpty(sdcardPath) ) {
                        mFileOut = new FileOutputStream(String.format("%s/record.pcm", sdcardPath));
                    }
                } catch (FileNotFoundException e) {
                    e.printStackTrace();
                }
                LogHelper.d(TAG, "Voice Recogintion startVR");
                mVoiceDecoder.startVR(mSampleRate, tokenCount);//配置识别采样率和采样数
                LogHelper.d(TAG, "Voice Recogintion start VR End");
                while (STATE_START == mState) {
                    BufferData data = mCallback.getRecognitionBuffer();//获取录音数据
                    if (null != data) {
                        if (null != data.mData) {
                            LogHelper.d(TAG, "putData data:" + data + " filledSize:" + data.getFilledSize());
                            mConsumedSize += data.getFilledSize();
                            LogHelper.d(TAG, "VoiceRecognition putData data mConsumedSize:" + mConsumedSize);
                            mVoiceDecoder.putData(data.mData, data.getFilledSize());
//进行解码
                            mCallback.freeRecognitionBuffer(data);
                            if (null != mFileOut) {
                                try {
                                    mFileOut.write(data.mData);
                                } catch (IOException e) {
                                    e.printStackTrace();
                                }
                            }
                        } else {
                            LogHelper.d(TAG, "end input buffer, so stop");
                            break;
                        }
                    } else {
                        LogHelper.e(TAG, "get null recognition buffer");
                        break;
                    }
                }

                mVoiceDecoder.stopVR();
                if (null != mFileOut) {
                    try {
                        mFileOut.close();
                        mFileOut = null;
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }

                mState = STATE_STOP;
                if (null != mListener) {
                    mListener.onStopRecognition();
                }
            }

            mVoiceDecoder.uninitVR();
        }
    }

解码的结果会通过VoiceDecoder.java的onRecognized 返回结果

  private void onRecognized(int index) {
        LogHelper.d("VoiceRecognition", "onRecognized:" + index);
        if (null != mCallback) {
            mCallback.onVoiceDecoderResult(index);
        }
    }

这里处理返回结果显示到手机上和数据处理

    private static class RegHandler extends Handler {
        private StringBuilder mTextBuilder = new StringBuilder();
        private MainActivity mAct;

        public RegHandler(MainActivity act) {
            mAct = act;
        }

        @Override
        public void handleMessage(Message msg) {
            switch (msg.what) {
            case MSG_SET_RECG_TEXT:
                char ch = (char) msg.arg1;
//                mTextBuilder.append(ch);
                mAct.mRecgs[mAct.mRecgCount++] = ch;
                break;

            case MSG_RECG_START:
//                mTextBuilder.delete(0, mTextBuilder.length());
                mAct.mRecgCount = 0;
                break;

            case MSG_RECG_END:
                Log.e("PP", "recognition end gIsError:" + msg.arg1);
                if ( mAct.mRecgCount > 0 ) {
                    byte[] strs = new byte[mAct.mRecgCount];
                    for ( int i = 0; i < mAct.mRecgCount; ++i ) {
                        strs[i] = (byte)mAct.mRecgs[i];
                    }
                    try {
                    //解码结果
                        String strReg = new String(strs, "UTF8");
                        String[] wifi_info = strReg.split("A@");
                    //  解码分割。我这边是以A@作为分隔符。比如
                        //sandiskA@lb12345 则 sandisk为ssid lb12345 为pwd
                        String ssid = wifi_info[0];
                        String pwd = wifi_info[1];
                        Log.e("PP","recv ssid ==" + ssid);
                        Log.e("PP","recv pwd ==" + pwd);
                        mAct.call(ssid, pwd);//进行wifi连接
                    //  Log.e("PP","recv ssid ==" + ssid);
                    //  Log.e("PP","recv pwd ==" + pwd);
                        if (msg.arg1 >= 0) {
                            Log.d(TAG, "reg ok!!!!!!!!!!!!");
                            if (null != mAct) {
                                mAct.mRecognisedTextView.setText(strReg);
                                // mAct.mRegState.setText("reg ok(" + msg.arg1 + ")");
                            }
                        } else {
                            Log.d(TAG, "reg error!!!!!!!!!!!!!");
                            mAct.mRecognisedTextView.setText(strReg);
                            // mAct.mRegState.setText("reg err(" + msg.arg1 + ")");
                            // mAct.mRegState.setText("reg err");
                        }
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
                break;

            case MSG_PLAY_TEXT:
//                mAct.mPlayTextView.setText(mAct.mPlayText);
                break;
            }
            super.handleMessage(msg);
        }
    }
 private void call(String ssid, String pwd) {
        mWifiConnectManager.connect(ssid,pwd, WifiCipherType.WIFICIPHER_WPA);
    }

WifiAutoConnectManager主要工作是在SinVoiceRecognition 获取到解码的ssid和pwd后。进行wifi主动连接

package com.libra.sinvoice;

import java.lang.reflect.Method;
import java.util.List;

//import com.lgshouyou.vrclient.config.//DebugUtils;

import android.content.Context;
import android.net.wifi.WifiConfiguration;
import android.net.wifi.WifiInfo;
import android.net.wifi.WifiManager;
import android.os.Build;

import com.example.sinvoicedemo.WifiCipherType;

public class WifiAutoConnectManager {
    private static String TAG = WifiAutoConnectManager.class.getName();

    private WifiManager wifiManager;
    private WifiConnectListenner listenner;
    public interface WifiConnectListenner{
        void connectFail();
        void connectSuc();
    }

    public void setListenner(WifiConnectListenner listener){
        this.listenner = listener;
    }


    // 构造函数
    public WifiAutoConnectManager(WifiManager wifiManager) {
        this.wifiManager = wifiManager; 
    }

    // 提供一个外部接口,传入要连接的无线网
    public void connect(String ssid, String password, WifiCipherType type) {
        Thread thread = new Thread(new ConnectRunnable(ssid, password, type));
        thread.start();
    }

    // 查看以前是否也配置过这个网络
    private WifiConfiguration isExsits(String SSID) {
        List<WifiConfiguration> existingConfigs = wifiManager.getConfiguredNetworks();
        if(existingConfigs != null){
            for (WifiConfiguration existingConfig : existingConfigs) {
                if (existingConfig.SSID.equals("\"" + SSID + "\"")) {
                    return existingConfig;
                }
            }
        }
        return null;
    }

    private WifiConfiguration createWifiInfo(String SSID, String Password, WifiCipherType 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 == WifiCipherType.WIFICIPHER_NOPASS) {//modify 20161219加上屏蔽的两行会导致返回netId为-1
//            config.wepKeys[0] = "";   
            config.hiddenSSID = true;
            config.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE);
//            config.wepTxKeyIndex = 0;
            //DebugUtils.printInfo(TAG, "无密配置");
        }else if (Type == WifiCipherType.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 == WifiCipherType.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;

        }else if(Type == WifiCipherType.WIFICIPHER_WPA2){
            config.preSharedKey = "\"" + Password + "\"";

            config.allowedAuthAlgorithms.set(WifiConfiguration.AuthAlgorithm.OPEN);
            config.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.TKIP);
            config.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.CCMP);
            config.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_PSK);
            config.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.TKIP);
            config.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.CCMP);
            config.allowedProtocols.set(WifiConfiguration.Protocol.RSN);
            config.status = WifiConfiguration.Status.ENABLED;
        }else{
             return null;
        }
        return config;
    }

    // 打开wifi功能
    private boolean openWifi() {
        boolean bRet = true;
        if (!wifiManager.isWifiEnabled()) {
            bRet = wifiManager.setWifiEnabled(true);
            //DebugUtils.debug(TAG, "openWifi  bRet: " + bRet);
        }
        return bRet;
    }

    class ConnectRunnable implements Runnable {
        private String ssid;

        private String password;

        private WifiCipherType type;

        public ConnectRunnable(String ssid, String password, WifiCipherType type) {
            this.ssid = ssid;
            this.password = password;
            this.type = type;

            //DebugUtils.debug(TAG, "ssid: " + ssid + " password: " + password + " type: " + type);
        }

        @Override
        public void run() {
            // 打开wifi
            openWifi();
            // 开启wifi功能需要一段时间(我在手机上测试一般需要1-3秒左右),所以要等到wifi
            // 状态变成WIFI_STATE_ENABLED的时候才能执行下面的语句
            while (wifiManager.getWifiState() == WifiManager.WIFI_STATE_ENABLING) {
                try {
                    // 为了避免程序一直while循环,让它睡个100毫秒检测……
                    Thread.sleep(100);
                    //DebugUtils.debug(TAG, "wifi已经打开");
                } catch (InterruptedException ie) {
                }
            }

            WifiConfiguration wifiConfig = createWifiInfo(ssid, password, type);
            //DebugUtils.debug(TAG, "wifiConfig: " + wifiConfig);

            if (wifiConfig == null) {
                return;
            }
            WifiConfiguration tempConfig = isExsits(ssid);

            if (tempConfig != null) {
                //DebugUtils.debug(TAG, "配置过ssid");
                wifiManager.removeNetwork(tempConfig.networkId);
            }

            int netID = wifiManager.addNetwork(wifiConfig);

            //DebugUtils.printInfo(TAG, "netID: " + netID);

            /*
             * DisableOthers 为true的时候就表示在连接networkId的时候,拒绝连接其他的wifiap,
             * 也就是说只连接当前的wifiap,如果连不上也不会去连接其他的wifiap
             * 而为false的时候就表示连接当前wifiap,如果连不上,就去连接其他的wifiap
             * */

            if (-1 != netID){// 表示可以分配新的ID成功
                Method connectMethod = connectWifiByReflectMethod(netID);  //解决部分手机不能连接热点的情况不能单纯的使用enableNetwork方法
                if (connectMethod == null) {
                    //DebugUtils.printInfo(TAG, "connect wifi by enableNetwork method");
                    // 通用API
                    boolean b = wifiManager.enableNetwork(netID, true);
                    if (b){// 链接成功

                        listenner.connectSuc();
                        //DebugUtils.printInfo(TAG, "成功连接热点");
                    }else{
                        listenner.connectFail();
                    }
                }else{
                    listenner.connectSuc();
                }

//              boolean b = wifiManager.enableNetwork(netID, true);
//              if (b){// 链接成功
//                  
//                  listenner.connectSuc();
//                  //DebugUtils.debug(TAG, "成功连接热点");
//              }else{
//                  listenner.connectFail();
//              }
            }else{
                listenner.connectFail();
            }
        }
    }

    /**
     * 通过反射出不同版本的connect方法来连接Wifi
     * 
     * @author jiangping.li
     * @param netId
     * @return
     * @since MT 1.0
     *
     */
    private Method connectWifiByReflectMethod(int netId) {
        Method connectMethod = null;
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {

            //DebugUtils.printInfo(TAG, "connectWifiByReflectMethod road 1");
            // 反射方法: connect(int, listener) , 4.2 <= phone‘s android version
            for (Method methodSub : wifiManager.getClass().getDeclaredMethods()) {
                if ("connect".equalsIgnoreCase(methodSub.getName())) {
                    Class<?>[] types = methodSub.getParameterTypes();
                    if (types != null && types.length > 0) {
                        if ("int".equalsIgnoreCase(types[0].getName())) {
                            connectMethod = methodSub;
                        }
                    }
                }
            }
            if (connectMethod != null) {
                try {
                    connectMethod.invoke(wifiManager, netId, null);
                } catch (Exception e) {
                    e.printStackTrace();
                    //DebugUtils.printInfo(TAG, "connectWifiByReflectMethod Android "
                         //   + Build.VERSION.SDK_INT + " error!");

                    return null;
                }
            }
        } else if (Build.VERSION.SDK_INT == Build.VERSION_CODES.JELLY_BEAN) {
            // 反射方法: connect(Channel c, int networkId, ActionListener listener)
            // 暂时不处理4.1的情况 , 4.1 == phone‘s android version
            //DebugUtils.printInfo(TAG, "connectWifiByReflectMethod road 2");
        } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH
                && Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN) {
            //DebugUtils.printInfo(TAG, "connectWifiByReflectMethod road 3");
            // 反射方法:connectNetwork(int networkId) ,
            // 4.0 <= phone‘s android version < 4.1
            for (Method methodSub : wifiManager.getClass()
                    .getDeclaredMethods()) {
                if ("connectNetwork".equalsIgnoreCase(methodSub.getName())) {
                    Class<?>[] types = methodSub.getParameterTypes();
                    if (types != null && types.length > 0) {
                        if ("int".equalsIgnoreCase(types[0].getName())) {
                            connectMethod = methodSub;
                        }
                    }
                }
            }
            if (connectMethod != null) {
                try {
                    connectMethod.invoke(wifiManager, netId);
                } catch (Exception e) {
                    e.printStackTrace();
                    //DebugUtils.printInfo(TAG, "connectWifiByReflectMethod Android "
                        //    + Build.VERSION.SDK_INT + " error!");
                    return null;
                }
            }
        } else {
            // < android 4.0
            return null;
        }
        return connectMethod;
    }

    public String getCurrentWifiname() {
        try {
            if(wifiManager.getWifiState() == WifiManager.WIFI_STATE_ENABLED){  //wifi已经打开
                WifiInfo info = wifiManager.getConnectionInfo();
                String wifiId = info != null ? info.getSSID() : null;

                //DebugUtils.printInfo("", "getCurrentWifiname wifiId: " + wifiId);
                return wifiId;
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

}

代码已经测试ok
整个项目源码

猜你喜欢

转载自blog.csdn.net/lb5761311/article/details/78052657
今日推荐