package com.example.hlm6.service;
import static android.content.ContentValues.TAG;
import android.annotation.SuppressLint;
import android.app.Service;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothGatt;
import android.bluetooth.BluetoothGattCharacteristic;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.os.Handler;
import android.os.IBinder;
import android.os.Message;
import android.util.Log;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
public class BLEService extends Service {
private BluetoothAdapter mBluetoothAdapter = null;
private BluetoothDevice curBluetoothDevice = null; //当前连接的设备
public static BLEManager bleManager;
private static StringBuilder weighRecord;
public static final String SERVICE_UUID = "0000ffe0-0000-1000-8000-00805f9b34fb"; //蓝牙通讯服务
public static final String READ_UUID = "0000ffe1-0000-1000-8000-00805f9b34fb"; //读特征
public static final String WRITE_UUID = "0000ffe2-0000-1000-8000-00805f9b34fb"; //写特征
private static final int CONNECT_SUCCESS = 0x01;
private static final int RECEIVE_SUCCESS = 0x02;
private static final int CONNECT_DIS = 0x03;
private static final int CONNECT_Failure = 0x04;
private boolean curConnState = false;//当前连接状态
private String bleAddress;
private Intent intentHomeActivity = new Intent("hl.example.hlbluetoothapp.homeActivity");
// 添加广播Action常量
public static final String ACTION_BLE_CONNECTED = "com.example.hlm6.ACTION_BLE_CONNECTED";
public static final String ACTION_BLE_DISCONNECTED = "com.example.hlm6.ACTION_BLE_DISCONNECTED";
public static final String EXTRA_DEVICE_ADDRESS = "device_address";
public static final String EXTRA_DEVICE_NAME = "device_name";
@Nullable
@Override
public IBinder onBind(Intent intent) {
return null;
}
@Override
public void onCreate() {
super.onCreate();
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
if (intent != null) {
Bundle bundle = intent.getExtras();
if (bundle != null) {
bleAddress = bundle.getString("bleAddress");
initializeBluetooth(bleAddress);
}
}
weighRecord = new StringBuilder();
return super.onStartCommand(intent, flags, startId);
}
@SuppressLint("HandlerLeak")
private Handler mHandler = new Handler() {
@Override
public void handleMessage(@NonNull Message msg) {
super.handleMessage(msg);
switch (msg.what) {
case CONNECT_SUCCESS:
Log.d(TAG, "连接成功...");
Integer status3 = (Integer) msg.obj;
intentHomeActivity.putExtra("status", status3);
sendBroadcast(intentHomeActivity);
break;
case RECEIVE_SUCCESS:
break;
case CONNECT_DIS:
Integer status1 = (Integer) msg.obj;
intentHomeActivity.putExtra("status", status1);
sendBroadcast(intentHomeActivity);
break;
case CONNECT_Failure:
Integer status2 = (Integer) msg.obj;
intentHomeActivity.putExtra("status", status2);
sendBroadcast(intentHomeActivity);
break;
}
}
};
//初始化蓝牙连接
public boolean initializeBluetooth(String bleAddress) {
Log.d(TAG, "initializeBluetooth : bleAddress " + bleAddress);
mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
if (mBluetoothAdapter == null) {
Log.e(TAG, "设备不支持蓝牙");
return false;
}
try {
curBluetoothDevice = mBluetoothAdapter.getRemoteDevice(bleAddress);
} catch (IllegalArgumentException e) {
Log.e(TAG, "蓝牙地址不正确");
return false;
}
bleManager = new BLEManager();
btConnect(curBluetoothDevice); // 传递curBluetoothDevice
return true;
}
/// /////////////////////////////// 连接蓝牙 /////////////////////////////////////////////
public void btConnect(BluetoothDevice bluetoothDevice) {
Log.d(TAG, "btConnect: 开始连接蓝牙 "+curConnState);
if (!curConnState) {
Log.d(TAG, "btConnect: 开始连接蓝牙 测试"+bleManager);
if (bleManager != null) {
bleManager.connectBleDevice(BLEService.this, bluetoothDevice, 10000, SERVICE_UUID, READ_UUID, WRITE_UUID, onBleConnectListener);
}
} else {
Log.d(TAG, "btConnect:当前设备已连接 ");
}
Log.d(TAG, "btConnect: 连接蓝牙结束");
}
//连接回调
private OnBleConnectListener onBleConnectListener = new OnBleConnectListener() {
@Override
public void onConnecting(BluetoothGatt bluetoothGatt, BluetoothDevice bluetoothDevice) {
//正在连接
}
@Override
public void onConnectSuccess(BluetoothGatt bluetoothGatt, BluetoothDevice bluetoothDevice, int status) {
//因为服务发现成功之后,才能通讯,所以在成功发现服务的地方表示连接成功,不在此表示连接成功
System.out.println("因为服务发现成功之后,才能通讯,所以在成功发现服务的地方表示连接成功,不在此表示连接成功");
}
@Override
public void onConnectFailure(BluetoothGatt bluetoothGatt, BluetoothDevice bluetoothDevice, String exception, int status) {
//连接失败
Message message = new Message();
message.what = CONNECT_Failure;
message.obj = status;
mHandler.sendMessage(message);
}
@Override
public void onDisConnecting(BluetoothGatt bluetoothGatt, BluetoothDevice bluetoothDevice) {
//正在断开
}
@Override
public void onDisConnectSuccess(BluetoothGatt bluetoothGatt, BluetoothDevice bluetoothDevice, int status) {
System.out.println("断开连接");
// 断开连接
Message message = new Message();
message.what = CONNECT_DIS;
message.obj = status;
mHandler.sendMessage(message);
curConnState = false; // 设置连接状态为断开
}
@Override
public void onServiceDiscoverySucceed(BluetoothGatt bluetoothGatt, BluetoothDevice bluetoothDevice, int status) {
//因为服务发现成功之后,才能通讯,所以在成功发现服务的地方表示连接成功
System.out.println("因为服务发现成功之后,才能通讯,所以在成功发现服务的地方表示连接成功");
Message message = new Message();
message.what = CONNECT_SUCCESS;
message.obj = -2;
mHandler.sendMessage(message);
curConnState = true; // 设置连接状态为已连接
// 发送连接成功广播
Intent connectedIntent = new Intent(ACTION_BLE_CONNECTED);
connectedIntent.putExtra(EXTRA_DEVICE_ADDRESS, bluetoothDevice.getAddress());
connectedIntent.putExtra(EXTRA_DEVICE_NAME, bluetoothDevice.getName());
sendBroadcast(connectedIntent);
}
@Override
public void onServiceDiscoveryFailed(BluetoothGatt bluetoothGatt, BluetoothDevice bluetoothDevice, String failMsg) {
//发现服务失败
}
@Override
public void onReceiveMessage(BluetoothGatt bluetoothGatt, BluetoothDevice bluetoothDevice, BluetoothGattCharacteristic characteristic, byte[] msg) {
//收到消息
Message message = new Message();
message.what = RECEIVE_SUCCESS;
message.obj = msg;
mHandler.sendMessage(message);
}
@Override
public void onReceiveError(String errorMsg) {
//接收数据出错
}
@Override
public void onWriteSuccess(BluetoothGatt bluetoothGatt, BluetoothDevice bluetoothDevice, byte[] msg) {
//写入成功
}
@Override
public void onWriteFailure(BluetoothGatt bluetoothGatt, BluetoothDevice bluetoothDevice, byte[] msg, String errorMsg) {
//写入失败
}
@Override
public void onReadRssi(BluetoothGatt bluetoothGatt, int Rssi, int status) {
//成功读取到连接信号强度
}
@Override
public void onMTUSetSuccess(String successMTU, int newMtu) {
//MTU设置成功
}
@Override
public void onMTUSetFailure(String failMTU) {
//MTU设置失败
}
};
}
package com.example.hlm6.controller;
import static android.content.ContentValues.TAG;
import android.annotation.SuppressLint;
import android.bluetooth.BluetoothDevice;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Bundle;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentActivity;
import androidx.fragment.app.FragmentManager;
import androidx.fragment.app.FragmentTransaction;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.LinearLayout;
import android.widget.ListView;
import android.widget.Toast;
import com.example.hlm6.R;
import com.example.hlm6.adapter.LVDevicesAdapter;
import com.example.hlm6.adapter.OnDeviceClickListener;
import com.example.hlm6.service.BLEDevice;
import com.example.hlm6.service.BLEManager;
import com.example.hlm6.service.BLEService;
import com.example.hlm6.service.OnBleConnectListener;
import com.example.hlm6.service.OnDeviceSearchListener;
public class MessageFragment extends Fragment implements View.OnClickListener {
private static final String ARG_PARAM1 = "param1";
private static final String ARG_PARAM2 = "param2";
private LVDevicesAdapter lvDevicesAdapter;
private BLEManager bleManager;
private Button btSearchBluetooth;
private LinearLayout llDeviceList;
private ListView lvDevices;
private boolean curConnState = false;
private String address;
private String mParam1;
private String mParam2;
private static final int CONNECT_SUCCESS = 0x01;
private static final int RECEIVE_SUCCESS = 0x02;
private static final int DISCOVERY_DEVICE = 0x05;
public MessageFragment() {
}
public static MessageFragment newInstance(String param1, String param2) {
MessageFragment fragment = new MessageFragment();
Bundle args = new Bundle();
args.putString(ARG_PARAM1, param1);
args.putString(ARG_PARAM2, param2);
fragment.setArguments(args);
return fragment;
}
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
IntentFilter filter = new IntentFilter();
filter.addAction("hl.example.hlbluetoothapp.homeActivity");
requireActivity().registerReceiver(mBroadcastReceiver, filter);
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
return inflater.inflate(R.layout.fragment_message, container, false);
}
@Override
public void onViewCreated(View view, Bundle savedInstanceState) {
Log.d(TAG, "onViewCreated: -------初始化onViewCreated-------");
super.onViewCreated(view, savedInstanceState);
//初始化视图
btSearchBluetooth = view.findViewById(R.id.bt_searchBluetooth);
llDeviceList = view.findViewById(R.id.ll_device_list);
lvDevices = view.findViewById(R.id.lv_devices);
//初始化数据
initData();
//初始化监听
btSearchBluetooth.setOnClickListener(this);
}
private BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if ("hl.example.hlbluetoothapp.homeActivity".equals(action)) {
int status = intent.getIntExtra("status", -1);
if (status == -2) {
// 连接成功,切换到称重页面
System.out.println("连接成功,切换到称重页面");
toWeighFragment();
}
}
}
};
@Override
public void onDestroy() {
super.onDestroy();
requireActivity().unregisterReceiver(mBroadcastReceiver);
}
@Override
public void onClick(View view) {
if (view.getId() == R.id.bt_searchBluetooth) {
System.out.println("onClick R.id.bt_search 点击开始搜索蓝牙");
llDeviceList.setVisibility(View.VISIBLE);//显示llDeviceList布局
searchBtDevice();
}
}
/**
* 初始化数据
*/
private void initData() {
FragmentActivity activity = getActivity();
System.out.println("初始化数据");
//列表适配器
lvDevicesAdapter = new LVDevicesAdapter(getActivity());
//绘制列表适配器
lvDevices.setAdapter(lvDevicesAdapter);
//初始化ble管理器 bleManager.initBle判断设备是否支持蓝牙,设备支持蓝牙后用bleManager.openBluetooth开启设备蓝牙。
bleManager = new BLEManager();
if (!bleManager.initBle(activity)) {
Log.d(TAG, "该设备不支持低功耗蓝牙");
Toast.makeText(activity, "该设备不支持低功耗蓝牙", Toast.LENGTH_SHORT).show();
} else {
if (!bleManager.isEnable()) {
//去打开蓝牙
bleManager.openBluetooth(activity, false);
}
}
System.out.println("初始化数据结束");
}
/// /////////////////////////////// 搜索设备 /////////////////////////////////////////////
private void searchBtDevice() {
System.out.println("搜索设备");
if (bleManager == null) {
Log.d(TAG, "searchBtDevice()-->bleManager == null");
return;
}
//判断是否正在扫描,如果当前正在搜索设备,先停止搜索
if (bleManager.isDiscovery()) {
bleManager.stopDiscoveryDevice();
}
//判读蓝牙列表是否为空
if (lvDevicesAdapter != null) {
lvDevicesAdapter.clear(); //清空列表
}
//开始搜索
bleManager.startDiscoveryDevice(onDeviceSearchListener, 1000);
}
//扫描结果回调
private OnDeviceSearchListener onDeviceSearchListener = new OnDeviceSearchListener() {
@Override
public void onDeviceFound(BLEDevice bleDevice) {
System.out.println("扫描结果回调 onDeviceFound ");
Message message = new Message();
message.what = DISCOVERY_DEVICE;
message.obj = bleDevice;
mHandler.sendMessage(message);
}
@Override
public void onDiscoveryOutTime() {
}
};
@SuppressLint("HandlerLeak")
private Handler mHandler = new Handler() {
@SuppressLint("SetTextI18n")
@Override
public void handleMessage(@NonNull Message msg) {
super.handleMessage(msg);
switch (msg.what) {
case DISCOVERY_DEVICE://扫描到设备
System.out.println("handle 扫描到设备");
BLEDevice bleDevice = (BLEDevice) msg.obj;
lvDevicesAdapter.addDevice(bleDevice);
lvDevicesAdapter.setOnDeviceClickListener(new OnDeviceClickListener() {
@Override
public void onConnect(BLEDevice bleDevice) {
BluetoothDevice bluetoothDevice = bleDevice.getBluetoothDevice();
address = bluetoothDevice.getAddress();
//启动服务,传递蓝牙地址,连接蓝牙
Bundle bundle = new Bundle();
bundle.putString("bleAddress", address);
Intent serviceIntent = new Intent(getActivity(), BLEService.class);
serviceIntent.putExtras(bundle);
//需判断蓝牙是否连接成功
getActivity().startService(serviceIntent);
// 不再立即跳转,等待连接成功后再跳转
// 可以显示一个加载对话框或提示用户正在连接
//showConnectingDialog();
}
});
break;
}
}
};
private void toWeighFragment(){
// 创建weighFragment的实例
WeighFragment weighFragment = new WeighFragment();
// 获取FragmentManager
FragmentManager fragmentManager = getActivity().getSupportFragmentManager();
// 开启事务
FragmentTransaction transaction = fragmentManager.beginTransaction();
// 替换Fragment,其中R.id.fcv_operation是放置Fragment的容器
transaction.replace(R.id.fcv_operation, weighFragment);
// 可选:添加到返回栈,这样按返回键可以回到上一个Fragment
transaction.addToBackStack(null);
// 提交事务
transaction.commit();
}
}
在MessageFragment搜索蓝牙列表,并点击指定蓝牙进行连接。总是失败,分析原因
2025-09-19 16:27:54.789 13765-13765 ContentValues com.example.hlm6 D btConnect: 开始连接蓝牙 false
2025-09-19 16:27:54.789 13765-13765 ContentValues com.example.hlm6 D btConnect: 开始连接蓝牙 测试com.example.hlm6.service.BLEManager@7424b22
2025-09-19 16:27:54.789 13765-13765 BLEManager com.example.hlm6 D connectBleDevice: --------------通过蓝牙设备连接------------
2025-09-19 16:27:54.790 13765-13765 BluetoothDevice com.example.hlm6 I get remote device name: ABCD12
2025-09-19 16:27:54.790 13765-13765 BLEManager com.example.hlm6 D 开始准备连接:ABCD12-->11:89:9A:A1:61:E8
2025-09-19 16:27:54.790 13765-13765 BluetoothDevice com.example.hlm6 I connectGatt: callingPid=13765 callingUid=10366
2025-09-19 16:27:54.790 13765-13765 BluetoothDevice com.example.hlm6 I callingApp=com.example.hlm6
2025-09-19 16:27:54.791 13765-13765 BluetoothGatt com.example.hlm6 D connect() - device: 11:89:**:**:**:E8, auto: false
2025-09-19 16:27:54.791 13765-13765 BluetoothGatt com.example.hlm6 D registerApp()
2025-09-19 16:27:54.791 13765-13765 BluetoothGatt com.example.hlm6 D registerApp() - UUID=073dcedf-8a72-4b79-a06e-0fa0542d174a
2025-09-19 16:27:54.792 13765-13765 BluetoothGatt com.example.hlm6 I connect is called
2025-09-19 16:27:54.793 13765-17170 BluetoothGatt com.example.hlm6 D onClientRegistered() - status=0 clientIf=17
2025-09-19 16:27:54.793 13765-13765 ContentValues com.example.hlm6 D btConnect: 连接蓝牙结束
2025-09-19 16:27:55.578 13765-17213 HwViewRootImpl com.example.hlm6 D [DetectViewsLocationRunner] start to get views' rect, type = SCENE_GESTURE_SINGLE_TAP
2025-09-19 16:27:55.579 13765-17213 HwViewRootImpl com.example.hlm6 D [DetectViewsLocationRunner] windowModeType: 1
2025-09-19 16:27:55.579 13765-17213 HwViewRootImpl com.example.hlm6 D [DetectViewsLocationRunner] displayPoint: Point(1260, 2720)
2025-09-19 16:27:55.579 13765-17213 HwViewRootImpl com.example.hlm6 D [DetectViewsLocationRunner] windowModeType: 1
2025-09-19 16:27:55.579 13765-17213 HwViewRootImpl com.example.hlm6 D [DetectViewsLocationRunner] lazyMode:
2025-09-19 16:27:55.579 13765-17213 HwViewRootImpl com.example.hlm6 D [DetectViewsLocationRunner] current mode is full screen
2025-09-19 16:27:55.580 13765-13765 HwViewRootImpl com.example.hlm6 D [DetectViewsLocationRunner] start to getViewHierarchy
2025-09-19 16:27:55.581 13765-17213 HwViewRootImpl com.example.hlm6 D [DetectViewsLocationRunner] deviceOrientation: 0
2025-09-19 16:27:55.581 13765-17213 HwViewRootImpl com.example.hlm6 D [DetectViewsLocationRunner-ScreenDirection] ROTATION_0
2025-09-19 16:27:55.581 13765-17213 HwViewRootImpl com.example.hlm6 D [DetectViewsLocationRunner] get views' rect = 13, SCENE_GESTURE_SINGLE_TAP#52,137,338,267#457,1381,799,1537#958,153,1244,309#958,360,1244,516#958,567,1244,723#958,774,1244,930#958,981,1244,1137#958,1188,1244,1344#958,1395,1244,1551#958,1602,1244,1758#958,1809,1244,1965#958,2016,1244,2172#958,2223,1244,2379
2025-09-19 16:28:02.504 13765-17162 BluetoothGatt com.example.hlm6 D onClientConnectionState() - status=133 clientIf=17 device=11:89:**:**:**:E8
2025-09-19 16:28:02.505 13765-17162 BLEManager com.example.hlm6 D onConnectionStateChange: --------链接成功回调---------
2025-09-19 16:28:02.505 13765-17162 BLEManager com.example.hlm6 D status:133
2025-09-19 16:28:02.505 13765-17162 BLEManager com.example.hlm6 D newState:0
2025-09-19 16:28:02.507 13765-17162 BluetoothDevice com.example.hlm6 I get remote device name: ABCD12
2025-09-19 16:28:02.507 13765-17162 BLEManager com.example.hlm6 D 连接的设备:ABCD12 11:89:9A:A1:61:E8
2025-09-19 16:28:02.509 13765-17162 om.example.hlm com.example.hlm6 W Accessing hidden method Landroid/bluetooth/BluetoothGatt;->refresh()Z (unsupported, reflection, allowed)
2025-09-19 16:28:02.510 13765-17162 BluetoothGatt com.example.hlm6 D refresh() - device: 11:89:**:**:**:E8
2025-09-19 16:28:02.512 13765-17162 BLEManager com.example.hlm6 E 断开连接status:133
2025-09-19 16:28:02.513 13765-17162 BluetoothGatt com.example.hlm6 D close()
2025-09-19 16:28:02.513 13765-17162 BluetoothGatt com.example.hlm6 D unregisterApp() - mClientIf=17
2025-09-19 16:28:02.515 13765-17162 BluetoothGatt com.example.hlm6 D close()
2025-09-19 16:28:02.515 13765-17162 BluetoothGatt com.example.hlm6 D unregisterApp() - mClientIf=0
2025-09-19 16:28:02.515 13765-17162 BLEManager com.example.hlm6 E 连接失败status:133 11:89:9A:A1:61:E8