生活随笔
收集整理的這篇文章主要介紹了
蓝牙模块--OTA升级
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
? 藍牙固件升級模塊:OAT升級又稱空中升級、DFU 升級,
這里使用的是Nordic Semiconductor公司開源提供的第三方升級庫:https://github.com/NordicSemiconductor/Android-DFU-Library
官方的使用文檔:https://github.com/NordicSemiconductor/Android-DFU-Library/blob/5c2d28e9db2ba28b3df67fd61d01a2ce1419fcf0/documentation/README.md
參考的其他博主的博客:https://www.jianshu.com/p/4017e7389804
OAT升級的流程:
1、使硬件設備進入DFU升級模式,進入升級模式的方式有很多,(每個項目可能都不一樣,需要與硬件進行協商確定)
例如目前的項目:
? ? ? ? ?1.設置設備的Indication
public boolean enableIndication(boolean enable) {BluetoothGattService RxService = mBluetoothGatt.getService(UUID.fromString("0000fe59-0000-1000-8000-00805f9b34fb"));if (RxService == null) {showMessage("Rx service not found!");broadcastUpdate(DEVICE_DOES_NOT_SUPPORT_UART);}BluetoothGattCharacteristic characteristic = RxService.getCharacteristic(UUID.fromString("8ec90003-f315-4f60-9fb8-838830daea50"));if (characteristic == null) {showMessage("Tx charateristic not found!");broadcastUpdate(DEVICE_DOES_NOT_SUPPORT_UART);}if (mBluetoothGatt == null || characteristic == null)return false;if (!mBluetoothGatt.setCharacteristicNotification(characteristic,enable))return false;BluetoothGattDescriptor clientConfig = characteristic.getDescriptor(UUID.fromString("00002902-0000-1000-8000-00805f9b34fb"));if (clientConfig == null)return false;if (enable) {clientConfig.setValue(BluetoothGattDescriptor.ENABLE_INDICATION_VALUE);} else {clientConfig.setValue(BluetoothGattDescriptor.DISABLE_NOTIFICATION_VALUE);}return mBluetoothGatt.writeDescriptor(clientConfig);}
? ? ? ? ? ?2.發送進入設備DFU模式的指令
byte[] value = new byte[1];value[0] =0x01;mService.writeDFUCharacteristic(value);
@RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN_MR2)public void writeDFUCharacteristic(byte[] value){
// Log.e("藍牙寫入查看工作狀態的命令", "寫入的命令:" +value.toString());if (mBluetoothGatt == null) {showMessage("mBluetoothGatt null" + mBluetoothGatt);broadcastUpdate(DEVICE_DOES_NOT_SUPPORT_UART);return;}BluetoothGattService RxService = mBluetoothGatt.getService(UUID.fromString("0000fe59-0000-1000-8000-00805f9b34fb"));showMessage("mBluetoothGatt null"+ mBluetoothGatt);if (RxService == null) {showMessage("Rx service not found!");broadcastUpdate(DEVICE_DOES_NOT_SUPPORT_UART);return;}BluetoothGattCharacteristic RxChar = RxService.getCharacteristic(UUID.fromString("8ec90003-f315-4f60-9fb8-838830daea50"));if (RxChar == null) {showMessage("Rx charateristic not found!");broadcastUpdate(DEVICE_DOES_NOT_SUPPORT_UART);return;}RxChar.setValue(value);boolean status = mBluetoothGatt.writeCharacteristic(RxChar);Log.d(TAG, "write TXchar - status=" + status);}
2、重新掃描,獲取DFU模式下的MAC地址
? ? ?重新進行掃描操作,因為當進入到DFU模式的時候,藍牙的名稱和MAC地址都會發生改變,獲取DFU模式下的MAC地址。
3、使用Android-DFU-Library,發送升級包,進行DFU升級
? ? ?使用Android-DFU-Library的流程:
? ? ?添加依賴 implementation 'no.nordicsemi.android:dfu:1.10.3' 新建服務:DfuService ,并注冊 package com.gzp.smartclothing.page.equipment.service;import android.app.Activity;
import android.app.Service;
import android.content.Intent;
import android.os.IBinder;import androidx.annotation.NonNull;
import androidx.core.app.NotificationCompat;import com.gzp.smartclothing.BuildConfig;
import com.gzp.smartclothing.page.equipment.view.NotificationActivity;import no.nordicsemi.android.dfu.DfuBaseService;public class DfuService extends DfuBaseService {@Overrideprotected Class<? extends Activity> getNotificationTarget() {return NotificationActivity.class;}@Overrideprotected boolean isDebug() {// Here return true if you want the service to print more logs in LogCat.// Library's BuildConfig in current version of Android Studio is always set to DEBUG=false, so// make sure you return true or your.app.BuildConfig.DEBUG here.return BuildConfig.DEBUG;}@Overrideprotected void updateForegroundNotification(@NonNull final NotificationCompat.Builder builder) {// Customize the foreground service notification here.}
}
?
通知Activity設置 package com.gzp.smartclothing.page.equipment.view;import androidx.appcompat.app.AppCompatActivity;import android.content.Intent;
import android.os.Bundle;/*** @author lk*/
public class NotificationActivity extends AppCompatActivity {@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);// If this activity is the root activity of the task, the app is not runningif (isTaskRoot()) {// Start the app before finishingfinal Intent intent = new Intent(this, ProductSetUpActivity.class);intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);intent.putExtras(getIntent().getExtras()); // copy all extrasstartActivity(intent);}// Now finish, which will drop you to the activity at which you were at the top of the task stackfinish();}
}
?
在需要使用固件升級的Activity中創建一個 DfuProgressListener 并進行注冊和反注冊 private final DfuProgressListener mDfuProgressListener = new DfuProgressListener() {@Overridepublic void onDeviceConnecting(String deviceAddress) {Log.i("dfu", "onDeviceConnecting");}@Overridepublic void onDeviceConnected(String deviceAddress) {Log.i("dfu", "onDeviceConnected");}@Overridepublic void onDfuProcessStarting(String deviceAddress) {Log.i("dfu", "onDfuProcessStarting");}@Overridepublic void onDfuProcessStarted(String deviceAddress) {Log.i("dfu", "onDfuProcessStarted");}@Overridepublic void onEnablingDfuMode(String deviceAddress) {Log.i("dfu", "onEnablingDfuMode");}@Overridepublic void onProgressChanged(String deviceAddress, int percent, float speed, float avgSpeed, int currentPart, int partsTotal) {Log.i("dfu", "onProgressChanged");Log.i("dfu", "onProgressChanged" + percent);}@Overridepublic void onFirmwareValidating(String deviceAddress) {Log.i("dfu", "onFirmwareValidating");}@Overridepublic void onDeviceDisconnecting(String deviceAddress) {Log.i("dfu", "onDeviceDisconnecting");}@Overridepublic void onDeviceDisconnected(String deviceAddress) {Log.i("dfu", "onDeviceDisconnected");mState = UART_PROFILE_DISCONNECTED;}@Overridepublic void onDfuCompleted(String deviceAddress) {Log.i("dfu", "onDfuCompleted");//升級成功,重新連接設備mSexualMuscleScanHandler.postDelayed(mSexualMuscleScanRunnable, 100);//延時100毫秒}@Overridepublic void onDfuAborted(String deviceAddress) {Log.i("dfu", "onDfuAborted");//升級流產,失敗Toast.makeText(mContext, "升級流產,失敗", Toast.LENGTH_SHORT).show();}@Overridepublic void onError(String deviceAddress, int error, int errorType, String message) {Log.i("dfu", "onError");Toast.makeText(mContext, "升級失敗。", Toast.LENGTH_SHORT).show();}}; @Overrideprotected void onResume() {DfuServiceListenerHelper.registerProgressListener(this, mDfuProgressListener);super.onResume();}@Overrideprotected void onPause() {DfuServiceListenerHelper.unregisterProgressListener(this, mDfuProgressListener);super.onPause();} ?
開啟 DfuService 進行升級 writeRXCharacteristicHandler = new Handler(Looper.getMainLooper());writeRXCharacteristicHandler.postDelayed(new Runnable() {@Overridepublic void run() {if (!curDfuTargMac.equals(dfuTargMac)){curDfuTargMac = dfuTargMac;new Thread(new Runnable() {@Overridepublic void run() {DfuServiceInitiator dfuServiceInitiator = new DfuServiceInitiator(curDfuTargMac);dfuServiceInitiator.createDfuNotificationChannel(ProductSetUpActivity.this);dfuServiceInitiator.setDisableNotification(false).setZip(R.raw.test_file).start((getBaseContext()), DfuService.class);}}).start();}}}, 1500); ?
坐等升級完成
? ? ? ? ?升級完成后,藍牙會自動斷開,若需使用,重新進行連接。
?
PS:在開啟設備的Indication和進行升級操作的時候在可以的情況下,盡量的一些延遲(在升級的過程中會出現各種意外、升級失敗、或者無法開啟升級的情況)。
?
?
總結
以上是生活随笔 為你收集整理的蓝牙模块--OTA升级 的全部內容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔 網站內容還不錯,歡迎將生活随笔 推薦給好友。