Android BLE蓝牙4.2数据透传操作
短信预约 -IT技能 免费直播动态提醒
BLE蓝牙4.2数据透传操作蓝牙模块服务查看测试代码新建工程添加权限初始化几个工具控件代码流程
Android版本有网友提到需要7.0以上(未求证)
本文所测试的蓝牙模块是CC2640,不适用蓝牙2.0版本。
作者:~会飞的蜗牛~
代码流程
蓝牙的操作流程网友介绍得比较详细,这里不再做重复介绍,上面的演示效果除了布局,写的代码其余都在这一个MainActivity类里,也就没有做太多优化(抄起来方便),其中比较关键的就是一定要检查那两个UUID:
package com.example.bluetooth4;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothGatt;
import android.bluetooth.BluetoothGattCallback;
import android.bluetooth.BluetoothGattCharacteristic;
import android.bluetooth.BluetoothGattDescriptor;
import android.bluetooth.BluetoothGattService;
import android.bluetooth.BluetoothProfile;
import android.bluetooth.le.BluetoothLeScanner;
import android.bluetooth.le.ScanCallback;
import android.bluetooth.le.ScanResult;
import android.os.Build;
import android.os.Handler;
import android.os.Message;
import android.support.annotation.RequiresApi;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import java.util.UUID;
public class MainActivity extends AppCompatActivity implements View.OnClickListener {
// 布局控件
private Button scanBtn;
private Button sendBtn;
private TextView reTv;
// 蓝牙相关的变量
private BluetoothAdapter mBluetoothAdapter;
private BluetoothLeScanner mBluetoothManager;
private List mBluetoothDevice;
private BluetoothGatt mBluetoothGatt;
private BluetoothGattCharacteristic mWriteCharacteristic;
// 用于显示搜索到的蓝牙列表
private ArrayAdapter arrayAdapter;
private ListView bluetoothLv;
private LinkedList bluetoothList = new LinkedList();
@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// 初始化控件
scanBtn = findViewById(R.id.scan_btn);
sendBtn = findViewById(R.id.send_btn);
bluetoothLv = findViewById(R.id.bluetooth_lv);
reTv = findViewById(R.id.re_tv);
// 设置监听事件
scanBtn.setOnClickListener(this);
sendBtn.setOnClickListener(this);
mBluetoothDevice = new ArrayList();
arrayAdapter = new ArrayAdapter(this, android.R.layout.simple_list_item_1, bluetoothList);
bluetoothLv.setAdapter(arrayAdapter);
bluetoothLv.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView parent, View view, int position, long id) {
Log.d("Bluetooth", "选择的蓝牙名称:" +mBluetoothDevice.get(position).getName());
mBluetoothGatt = mBluetoothAdapter.getRemoteDevice(mBluetoothDevice.get(position).getAddress()).connectGatt(getApplicationContext(), true, mGattCallback);
Message msg = new Message();
msg.obj = "正在连接...";
mHandlerLog.sendMessage(msg);
}
});
// 直接获取手机蓝牙是配置,没有再写判断蓝牙的状态(用软件之前那先把蓝牙打开)
mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
mBluetoothManager = mBluetoothAdapter.getBluetoothLeScanner();
}
// 刷新蓝牙列表
private Handler mHandler = new Handler(){
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
BluetoothDevice device = (BluetoothDevice)msg.obj;
Log.d("Bluetooth", "蓝牙名称:" + device.getAddress()+" "+device.getName());
String temp = device.getAddress()+" "+device.getName();
if(bluetoothList.contains(temp)==false) {
mBluetoothDevice.add(device);
bluetoothList.add(temp);
arrayAdapter.notifyDataSetChanged();
}
}
};
// 提示连接状态
private Handler mHandlerLog = new Handler(){
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
Toast.makeText(MainActivity.this, (String)msg.obj, Toast.LENGTH_SHORT).show();
}
};
// 用来刷新接收控件
private Handler mHandlerRes = new Handler(){
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
reTv.setText((String)msg.obj);
}
};
// 扫描蓝牙的回调,把扫描到的用mHandler刷新到界面上
private ScanCallback scanCallback = new ScanCallback() {
@Override
public void onScanResult(int callbackType, ScanResult result) {
BluetoothDevice device = result.getDevice();
Message msg = new Message();
msg.obj = device;
mHandler.sendMessage(msg);
}
};
// 两个按钮的点击事件
@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
@Override
public void onClick(View v) {
if(v.getId()==R.id.scan_btn) {
if(scanBtn.getText().toString().equals("扫描"))
{
mBluetoothDevice.clear();
scanBtn.setText("停止");
mBluetoothManager.startScan(scanCallback);
}
else
{
scanBtn.setText("扫描");
mBluetoothManager.stopScan(scanCallback);
}
}
if(v.getId()==R.id.send_btn) {
mWriteCharacteristic.setValue("bluetest");
Log.d("Bluetooth", "发送数据");
mBluetoothGatt.writeCharacteristic(mWriteCharacteristic);
}
}
// 蓝牙的服务回调
private BluetoothGattCallback mGattCallback = new BluetoothGattCallback() {
@RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN_MR2)
@Override
public void onConnectionStateChange(BluetoothGatt gatt, int status, int newState) {
super.onConnectionStateChange(gatt, status, newState);
if (newState == BluetoothProfile.STATE_CONNECTED) { //连接成功
Log.d("Bluetooth", "连接成功");
Message msg = new Message();
msg.obj = "连接成功";
mHandlerLog.sendMessage(msg);
mBluetoothGatt.discoverServices(); //连接成功后就去找出该设备中的服务 private BluetoothGatt mBluetoothGatt;
} else if (newState == BluetoothProfile.STATE_DISCONNECTED) { //连接失败
}
}
@RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN_MR2)
@Override
public void onServicesDiscovered(BluetoothGatt gatt, int status) {
if (status == BluetoothGatt.GATT_SUCCESS) { //找到服务了
List serviceList= mBluetoothGatt.getServices();
//在这里可以对服务进行解析,寻找到你需要的服务
Log.d("Bluetooth", "找到服务了"+serviceList.size());
for(int i=0;i<serviceList.size();i++)
{
Log.d("Bluetooth", "服务:"+serviceList.get(i).getUuid().toString());
List gattCharacteristics = serviceList.get(i).getCharacteristics();
for (BluetoothGattCharacteristic gattCharacteristic : gattCharacteristics) { // 遍历每条服务里的所有Characteristic
Log.d("Bluetooth", "服务Characteristic:"+gattCharacteristic.getUuid().toString());
if (gattCharacteristic.getUuid().toString().equals("f000fff1-0451-4000-b000-000000000000")) {
mBluetoothGatt.setCharacteristicNotification(gattCharacteristic,true);
//获取一个描述符
BluetoothGattDescriptor descriptor = gattCharacteristic.getDescriptor(UUID.fromString("00002902-0000-1000-8000-00805f9b34fb"));
descriptor.setValue(BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE);
mBluetoothGatt.readCharacteristic(gattCharacteristic);
mBluetoothGatt.writeDescriptor(descriptor);
mWriteCharacteristic = gattCharacteristic;
}
}
}
} else {
Log.d("Bluetooth", "onServicesDiscovered received: " + status);
}
}
@Override
public void onCharacteristicRead(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status) {
if (status == BluetoothGatt.GATT_SUCCESS) {
}
}
@Override
public void onCharacteristicWrite(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status) {
Log.d("Bluetooth", "onDescriptorWriteonDescriptorWrite = " + status + ", descriptor =" + characteristic.getUuid().toString());
}
//有数据过来就会回调到这个方法
@Override
public void onCharacteristicChanged(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic) {
Log.d("Bluetooth", "接收数据:"+ characteristic.getStringValue(0));
if (characteristic.getValue() != null) {
Message msg = new Message();
msg.obj = characteristic.getStringValue(0);
mHandlerRes.sendMessage(msg);
}
}
@Override
public void onDescriptorWrite(BluetoothGatt gatt, BluetoothGattDescriptor descriptor, int status) {
Log.d("Bluetooth", "--------onDescriptorWrite-----");
}
@Override
public void onReadRemoteRssi(BluetoothGatt gatt, int rssi, int status) {
Log.d("Bluetooth", "--------onReadRemoteRssi-----"+rssi);
}
};
}
提供demo以作参考
作者:~会飞的蜗牛~
免责声明:
① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。
② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341