藍牙共享網絡BluetoothPan

在Android手機的設置->無線和網絡->更多->移動網絡共享裏有一個藍牙共享網絡的功能。此功能的主要做用是經過藍牙鏈接將一部手機的網絡共享給另一臺手機。在Android手機中的操做步驟以下(其中A手機做爲網絡的提供方,B手機做爲網絡的接收方):android

1.A手機連上網絡(wifi或者流量),並在設置頁面打開「藍牙共享網絡」的開關;
2.B手機打開藍牙搜索設備,在鏈接A手機的藍牙時打開配置項裏的「互聯網訪問」開關;
3.而後B手機就能夠經過藍牙來利用A手機的網絡進行上網了。

在界面上操做就是這麼簡單,但有時候可能會出現這種狀況:一臺沒有屏幕的Android設備(A)有網絡,另外一部手機(B)想要鏈接上A設備進行上網,這時候因爲A沒有屏幕,就沒法在界面上打開「藍牙共享網絡」的開關。此時咱們就只能利用代碼來打開此開關。
因爲此開關咱們能夠在設置中進行打開,因此咱們能夠下載Android Setting的源碼,經過搜索「藍牙共享網絡」找到在String文件中的命名,而後在根據命名找到使用此文本的位置,最後經過讀Settting的源碼就能夠找到打開「藍牙共享網絡」的代碼實現。在此我就忽略了讀Setting源碼的過程,有興趣的同窗能夠按照上面的步驟本身讀下。
當你讀完代碼時候就會發現其實「藍牙共享網絡」的開關是經過BluetoothPan這個類的setBluetoothTethering方法來實現的。BlutoothPan是Bluetooth Personal Area Networking的簡稱,顧名思義其實就是藍牙的我的局域網絡。PAN的功能是經過藍牙協議將幾個PC或手機或其餘支持PAN的設備連成一個小局域網,互相之間能夠訪問,傳輸數據。固然,數據走的藍牙協議,經過藍牙傳輸。PAN中有3種角色:web

NAP(Network Access Point): 若是你的藍牙設備支持NAP,那麼你能夠經過共享網絡鏈接來給別的PAN Network內的PC提供上網功能。
GN(Group Ad-hoc Network): 使你能夠在小局域網內給其它設備提供數據轉發的功能。
PANU(PAN User):與NAP,GN相對的角色,使用NAP,GN提供的功能的設備。

然而當你照着Setting中的源碼來實現此功能的時候會發現一個問題,找不到BluetoothPan這個類,所以只能使用反射來作,實現此功能的主要代碼以下:
1.定義存儲BluetoothPan的成員變量網絡

private AtomicReference<Object> mBluetoothPan = new AtomicReference<Object>();

2.建立內部類BluetoothProfile.ServiceListenersvg

private BluetoothProfile.ServiceListener mProfileServiceListener = new BluetoothProfile.ServiceListener() {
        public void onServiceConnected( int profile , BluetoothProfile proxy ) {
            Log. e( "zbw", "onServiceConnected" );
            mBluetoothPan .set(proxy );
            try {
                Object bluetoothPan = mBluetoothPan .get();
                Class bluetoothPanClass = Class.forName( "android.bluetooth.BluetoothPan");
                if (bluetoothPan != null) {
                    Method methodIsTetheringOn = bluetoothPanClass .getMethod( "isTetheringOn" );
                    Log. e( "zbw", "isTetheringOn = " + methodIsTetheringOn .invoke(bluetoothPan ));
                    Method methodSetBluetoothTethering = bluetoothPanClass .getMethod( "setBluetoothTethering" , boolean . class) ;
                    methodSetBluetoothTethering .invoke(bluetoothPan , true);
                    Log. e( "zbw", "isTetheringOn = " + methodIsTetheringOn .invoke(bluetoothPan ));
                }

            } catch (Exception e ) {
                e.printStackTrace();
                Log. e( "zbw", "error = " + e .getLocalizedMessage());
            }
        }

        public void onServiceDisconnected( int profile ) {
            Log. e( "zbw", "onServiceDisconnected" );
            mBluetoothPan.set( null);
        }
    };

3.在onCreate方法或者其餘合適的地方設置監聽ui

BluetoothAdapter adapter = BluetoothAdapter. getDefaultAdapter();
            if (adapter != null) {
                adapter .getProfileProxy(getApplicationContext(), mProfileServiceListener ,5);
            }