在Android手机的设置->无线和网络->更多->移动网络共享里有一个蓝牙共享网络的功能。此功能的主要作用是通过蓝牙连接将一部手机的网络共享给另外一台手机。在Android手机中的操作步骤如下(其中A手机作为网络的提供方,B手机作为网络的接收方):
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种角色:
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.ServiceListener
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方法或者其他合适的地方设置监听
BluetoothAdapter adapter = BluetoothAdapter. getDefaultAdapter();
if (adapter != null) {
adapter .getProfileProxy(getApplicationContext(), mProfileServiceListener ,5);
}