蓝牙共享网络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);
            }