前言:项目已上传到 https://download.youkuaiyun.com/download/jscsd226/15781441直接下载即可。
如果没有积分,也可发送邮件给我索要:305591377@qq.com
1.项目需求:实现Ble蓝牙客户端,可复用。
2.项目时间:2020.11.01-2021.3.12
3.项目环境:
软件:AndroidStuio3.2 grade4.6 汇承蓝牙串口助手HID(黄色)
硬件:汇承HC-42蓝牙5.0模块。
连接:使用模块自带小开发板进行连接,插入电脑,打开助手和app即可。
经测试,战舰开发板和串口助手+蓝牙模块也可以实现通讯。
手机是荣耀/vivo/oppo,如果搜索不到设备,打开手机设置,应用,权限,找到app,打开位置权限即可。
4.项目功能:本项目是基于物联网的控制——蓝牙技术,进行开发的。app主要实现蓝牙的扫描、连接、发送数据、接收数据功能。 蓝牙模块插入电脑,通过串口助手进行通讯。 最终实现app与模块之间的数据传输。
5.项目遇到的关键问题:
1.接收数据:可以使用Locat调试工具
2.接收数据显示到列表:使用适配器。
3.发送数据:获取GATT的写,然后发送,具体看代码。
4.定位权限:在旧版本手机下,可以默认打开。在荣耀手机下,很多时候需要手动打开。这可能是个BUG,暂时不影响使用。刚开始测试的时候,荣耀手机总是不能扫描,点击没反应,排查了很久都没有发现问题,最终发现是应用定位的问题。根据惯性,我们手动打开蓝牙和位置信息,但是app的定位默认是静止的,所以一直没有找到问题。
6.实现效果:
7.项目技术实现细节:
对于蓝牙开发,大致以下步骤
1.打开蓝牙
2.蓝牙扫描,列出可用设备
3.关闭蓝牙扫描(不关闭会一直扫描)
4.找到目标蓝牙设备进行连接
5.连接成功,进行通信
6.关闭蓝牙释放资源
接下来我们要根据上面6个步骤进行API的说明:
(1)Service蓝牙功能集合,每一个Service都有一个UUID,
(2)Characteristic 在service中也有好多个Characteristic 独立数据项,其中也有独立UUID
上面的两个uuid需要从硬件工程师中获取,我才用南京沁恒微电子股份有限公司的蓝牙助手获取模块的UUID,此处说明一下,人家这个在不知道UUID的情况下可以连接并且发送数据,原理暂时还没有弄懂。
(3)BluetoothAdapter 蓝牙的打开关闭等基本操作
(4)BluetoothDevice 蓝牙设备,扫描到的
(5)BluetoothGatt 蓝牙连接重连断开连接等操作的类
(6)BluetoothGattCharacteristic 数据通信操作类,读写等操作
```xml
activity_main.xml:
里面定义了两个列表,1个编辑框,3个按钮,使用线性布局。
array_item.xml:
这里面是接收列表的布局,暂时只用了一个控件。
MainActivity.java
1.首先定义一个函数,此函数是进行所有控件的初始化,还有搜索列表的点击事件。
Init_Item();
2.蓝牙初始化。
Init_Bluetooth();
mAdapter.enable();打开蓝牙
mAdapter.startDiscovery();开始扫描
扫描到设备之后,添加到list view,然后列表点击事件。
此时可以进行bluetoothGatt.getServices();操作了,此时连接就OK了。
通过bluetoothGatt可以获取设备的通知和读写。
setNotify(notifyCharacteristic);
setEnableNotify(notifyCharacteristic, true);
通过10.11行两个函数判断是否具有写的功能,如果是,传值
writeCharacteristic.setValue(str);
bluetoothGatt.writeCharacteristic(writeCharacteristic);
通过13.14行进行给模块发送数据,此时发送数据就OK了
接收数据函数onCharacteristicChanged
新建一个类bytesHexStrTranslate,用来处理value值,反正不处理就打印不出来。
接收到值 bytesHexStrTranslate.bytesToHexFun1(value)
然后把接收到的这个值放到list view里面打印出来,这样接收就OK了
至于接收的数据处理过程,暂时就理解为格式处理把。
**8.项目心得:**历时时间最长的一个项目。经过反思,一是自己基础薄弱,二是每次找网上的。 从没有想着自己写。 这次根据看的资料,一步一步实现,先实现打开关闭蓝牙,然后搜索,然后传输数据。
**9.项目代码:**
(使用方法:直接使用即可)
**MainActivity**
```java
package com.example.augenstern.ble_04;
import android.Manifest;
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.BluetoothManager;
import android.bluetooth.BluetoothProfile;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.support.v4.app.ActivityCompat;
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.EditText;
import android.widget.ListView;
import android.widget.SimpleAdapter;
import android.widget.SimpleCursorAdapter;
import android.widget.TextView;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.UUID;
public class MainActivity extends AppCompatActivity implements View.OnClickListener {
private static final String servicesUUID = "0000ffe0-0000-1000-8000-00805f9b34fb";
private static final String writeUUID = "0000ffe1-0000-1000-8000-00805f9b34fb";
private static final String notifyUUID = "0000ffe0-0000-1000-8000-00805f9b34fb";
public SimpleAdapter adapter;
private static final String TAG = "TAG";
public ListView mListView;
public Button disConnected,scan,sendButton;
public EditText sendDataEdit;
public TextView statusConnected;
public ListView receiveList;
public BluetoothDevice device;
public BluetoothManager mManager;
public BluetoothAdapter mAdapter;
private BluetoothGatt bluetoothGatt;
public ArrayAdapter<String> mStringArrayAdapter;
public List<String> mStringList = new ArrayList<>();
//2021.03.12 listview接收
private List<String> listDevices = new ArrayList<String>();
private ArrayAdapter<String> adtDevices;//显示搜索到的设备信息
private BytesHexStrTranslate bytesHexStrTranslate;
private BluetoothGattService bluetoothGattService;
private BluetoothGattCharacteristic writeCharacteristic;
private BluetoothGattCharacteristic notifyCharacteristic;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Init_Item();
Init_Bluetooth();
}
//控件初始化
private void Init_Item(){
disConnected = findViewById(R.id.disConnected);
disConnected.setOnClickListener(this);
scan = findViewById(R.id.scan);
scan.setOnClickListener(this);
statusConnected = findViewById(R.id.status);
statusConnected.setText("未连接...");
sendDataEdit = findViewById(R.id.sendDataEdit);
sendButton = findViewById(R.id.sendButton);
sendButton.setOnClickListener(this);
mListView = findViewById(R.id.devicesList);
mListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
if(mAdapter.isDiscovering()) mAdapter.cancelDiscovery();
String info = ((TextView)view).getText().toString();
Log.d(TAG, "onCreate: in