插件地址 https://github.com/852172891/XposedBLE
实现之前先了解一下android BLE的数据读写流程。
BluetoothGatt mGatt = device.connectGatt(mContext, false, gattCallback);
boolean result = mGatt.writeCharacteristic(characteristic);
mGatt.readCharacteristic(characteristic)
从上边的代码可以看出,蓝牙的读写都是调用BluetoothGatt 中的方法。
下边分别看一下BluetoothGatt 的writeCharacteristic和readCharacteristic实现。这两个方法中参数都是BluetoothGattCharacteristic ,在BluetoothGattCharacteristic 中有两个最重要的参数 protected byte[] mValue;
protected UUID mUuid;一个是传输的内容,一个是对应的UUID,做过蓝牙开发的都知道这2 个参数的重要性。
/**
* Writes a given characteristic and its values to the associated remote device.
*
* Once the write operation has been completed, the
* {@link BluetoothGattCallback#onCharacteristicWrite} callback is invoked,
* reporting the result of the operation.
*
*
Requires {@link android.Manifest.permission#BLUETOOTH} permission.
*
* @param characteristic Characteristic to write on the remote device
* @return true, if the write operation was initiated successfully
*/
public boolean writeCharacteristic(BluetoothGattCharacteristic characteristic) {
if ((characteristic.getProperties() & BluetoothGattCharacteristic.PROPERTY_WRITE) == 0
&& (characteristic.getProperties() &
BluetoothGattCharacteristic.PROPERTY_WRITE_NO_RESPONSE) == 0) return false;
if (VDBG) Log.d(TAG, "writeCharacteristic() - uuid: " + characteristic.getUuid());
if (mService == null || mClientIf == 0 || characteristic.getValue() == null) return false;
BluetoothGattService service = characteristic.getService();
if (service == null) return false;
BluetoothDevice device = service.getDevice();
if (device == null) return false;
synchronized(mDeviceBusy) {
if (mDeviceBusy) return false;
mDeviceBusy = true;
}
try {
mService.writeCharacteristic(mClientIf, device.getAddress(),
characteristic.getInstanceId(), characteristic.getWriteType(),
AUTHENTICATION_NONE, characteristic.getValue());
} catch (RemoteException e) {
Log.e(TAG,"",e);
mDeviceBusy = false;
return false;
}
return true;
}
readCharacteristic 方法
/**
* Reads the requested characteristic from the associated remote device.
*
* This is an asynchronous operation. The result of the read operation
* is reported by the {@link BluetoothGattCallback#onCharacteristicRead}
* callback.
*
*
Requires {@link android.Manifest.permission#BLUETOOTH} permission.
*
* @param characteristic Characteristic to read from the remote device
* @return true, if the read operation was initiated successfully
*/
public boolean readCharacteristic(BluetoothGattCharacteristic characteristic) {
if ((characteristic.getProperties() &
BluetoothGattCharacteristic.PROPERTY_READ) == 0) return false;
if (VDBG) Log.d(TAG, "readCharacteristic() - uuid: " + characteristic.getUuid());
if (mService == null || mClientIf == 0) return false;
BluetoothGattService service = characteristic.getService();
if (service == null) return false;
BluetoothDevice device = service.getDevice();
if (device == null) return false;
synchronized(mDeviceBusy) {
if (mDeviceBusy) return false;
mDeviceBusy = true;
}
try {
mService.readCharacteristic(mClientIf, device.getAddress(),
characteristic.getInstanceId(), AUTHENTICATION_NONE);
} catch (RemoteException e) {
Log.e(TAG,"",e);
mDeviceBusy = false;
return false;
}
return true;
}
关键代码:首先获取 BluetoothGatt,hook readCharacteristic 和writeCharacteristic方法。
Class bluetooth = lpparam.classLoader.loadClass("android.bluetooth.BluetoothGatt");
try {
if (bluetooth != null) {
XposedHelpers.findAndHookMethod(bluetooth, "writeCharacteristic", BluetoothGattCharacteristic.class, new XC_MethodHook() {
protected void afterHookedMethod(MethodHookParam param) throws Throwable {
super.afterHookedMethod(param);
BluetoothGattCharacteristic bluetoothGattCharacteristic = (BluetoothGattCharacteristic) param.args[0];
byte[] mValue = bluetoothGattCharacteristic.getValue();
String str = "";
if (mValue != null) {
for (int i = 0; i < mValue.length; i++) {
str += String.format("%x ", mValue[i]);
}
}
Log.e("packageName" + lpparam.packageName, "writeCharacteristic str :" + str + " bluetoothGattCharacteristic" + bluetoothGattCharacteristic.getUuid().toString());
}
});
XposedHelpers.findAndHookMethod(bluetooth, "readCharacteristic", BluetoothGattCharacteristic.class, new XC_MethodHook() {
protected void afterHookedMethod(MethodHookParam param) throws Throwable {
super.afterHookedMethod(param);
BluetoothGattCharacteristic bluetoothGattCharacteristic = (BluetoothGattCharacteristic) param.args[0];
byte[] mValue = bluetoothGattCharacteristic.getValue();
String str = "";
if (mValue != null) {
for (int i = 0; i < mValue.length; i++) {
str += String.format("%x ", mValue[i]);
}
}
Log.e("packageName" + lpparam.packageName, "readCharacteristic str :" + str + " bluetoothGattCharacteristic" + bluetoothGattCharacteristic.getUuid().toString());
}
});
}
} catch (Exception e) {
Log.e("wanghaha", e.toString());
}
分析蓝牙传输过程,当你没有协议的时候。