什么是MTU
MTU(Maximum Transmission Unit),最大傳輸單元,是指一種通信協(xié)議的某一層上面所能通過的最大數(shù)據(jù)報(bào)大?。ㄒ宰止?jié)為單位)。而在Android BLE開發(fā)中,則指每包數(shù)據(jù)能攜帶的最大字節(jié)上限。
為什么要設(shè)置MTU
Android BLE傳送數(shù)據(jù)時(shí),MTU的默認(rèn)值是23byte,除掉GATT協(xié)議往包頭加上的3個(gè)字節(jié),留給開發(fā)人員的就是20byte,也就是說正常情況下,App通過BLE每包傳輸?shù)臄?shù)據(jù)最多只能是20byte。當(dāng)某個(gè)功能需要傳輸大量的數(shù)據(jù)時(shí),比如固件升級(jí),我們的固件雖然只有幾百KB大小,卻居然要分上萬個(gè)包,傳輸需要十多分鐘,顯然效率太低。而通過設(shè)置MTU,最高可以將MTU調(diào)整到512Byte,從而大大提高數(shù)據(jù)傳輸?shù)男省?/p>
前提條件
動(dòng)態(tài)設(shè)置MTU,需要傳輸?shù)碾p方都支持才行,此外還有一些前提條件:
- 軟件層面,Android API版本>=21(Android 5.0),才支持設(shè)置MTU。
- 硬件層面,藍(lán)牙4.2及以上的模塊,才支持設(shè)置MTU。
對(duì)于第一個(gè)限制,比較好適配,編碼時(shí)只需要判斷手機(jī)系統(tǒng)版本,API>=21才走動(dòng)態(tài)設(shè)置MTU的邏輯即可。
對(duì)于第二個(gè)限制,稍微麻煩,因?yàn)槟壳皼]有接口可以查詢手機(jī)藍(lán)牙的版本,只能在請(qǐng)求設(shè)置MTU的回調(diào)里進(jìn)行判斷,如果設(shè)置失敗,則仍然走默認(rèn)的邏輯,相當(dāng)于仍然使用默認(rèn)的20byte。
代碼實(shí)例
private void setMtu(int setMtu) {
BluetoothManager bluetoothManager = (BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE);
BluetoothAdapter bluetoothAdapter = bluetoothManager.getAdapter();
bluetoothAdapter.startLeScan(new BluetoothAdapter.LeScanCallback() {
@Override
public void onLeScan(BluetoothDevice device, int rssi, byte[] scanRecord) {
device.connectGatt(DemoActivity.this, true, new BluetoothGattCallback() {
@Override
public void onServicesDiscovered(BluetoothGatt gatt, int status) {
super.onServicesDiscovered(gatt, status);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
if (setMtu > 23 && setMtu < 512) {
gatt.requestMtu(setMtu);
}
}
}
@Override
public void onMtuChanged(BluetoothGatt gatt, int mtu, int status) {
super.onMtuChanged(gatt, mtu, status);
mMtu = mtu;
if (BluetoothGatt.GATT_SUCCESS == status && setMtu == mtu) {
LogUtils.d("MTU change success = " + mtu);
} else {
LogUtils.d("MTU change fail!");
}
}
});
}
});
}