帮同学写一个连接小车蓝牙模块遥控小车的APP,在网上搜阅了很多资料,大概了解了蓝牙的工作原理,再经历了种种BUG后终于是成功连上了小车蓝牙,并可以发送数据,小车可以接收到,测试的蓝牙是Arduino小车的蓝牙模块,应该通用所有板子的蓝牙模块。

开发环境:Android9.0 API28 AS3.3.2

另外AVD是没有蓝牙模块的,要到真机上跑

大概流程是:
1.开启权限
2.开启蓝牙被检测
3.根据mac地址获取Device连接蓝牙设备
4.发送和接收数据
其中要自己自己定义一个广播接收器来接收蓝牙发现设备时所传来的广播

首先要在manifest中加下列权限
 <uses-permission android:name="android.permission.BLUETOOTH"/><uses-permission android:name="android.permission.BLUETOOTH_ADMIN"/><uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" /><uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />

不要问为什么,网上的资料很多。

MainActivity
public class MainActivity extends AppCompatActivity {private static final int LOCATION_PERMISSION = 1;private static final int REQUEST_DISCOVERABLE = 2;private ListView listView;private Button mButton;private TextView status;private TextView address;private List<String> listDevice;private ArrayAdapter<String> mAdapter;private BluetoothAdapter mBluetoothAdapter;private BluetoothReceiver receiver;private BlueToothTool client; //成功连接配对的设备private RelativeLayout relativeLayout;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);initPeimission();initView();}private void initPeimission() {if(ContextCompat.checkSelfPermission(MainActivity.this,Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED){ActivityCompat.requestPermissions(MainActivity.this,new String[]{Manifest.permission.ACCESS_FINE_LOCATION},LOCATION_PERMISSION);}else{}}@Overridepublic void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {switch (requestCode){case LOCATION_PERMISSION:if(grantResults.length >0 && grantResults[0] == PackageManager.PERMISSION_GRANTED){Toast.makeText(this,"权限开启成功",Toast.LENGTH_SHORT).show();}else{Toast.makeText(this,"权限开启失败",Toast.LENGTH_SHORT).show();}break;default:}}private void initView() {status = (TextView)findViewById(R.id.connectiontext);address = (TextView)findViewById(R.id.address);mButton = (Button)findViewById(R.id.button_connect);listView = (ListView)findViewById(R.id.listview);relativeLayout = (RelativeLayout)findViewById(R.id.layout);listDevice = new ArrayList<>();mButton.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {EnableBluetooth();}});listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {@Overridepublic void onItemClick(AdapterView<?> parent, View view, int position, long id) {String str = listDevice.get(position);String macAdress = str.split("\\|")[1];BluetoothDevice device = mBluetoothAdapter.getRemoteDevice(macAdress);client = new BlueToothTool(device,handler); //创建一个客户端try{client.connect();}catch (Exception e){Log.e("TAG", e.toString());}}});}private void EnableBluetooth() {mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();Intent enable = new Intent(BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE);enable.putExtra(BluetoothAdapter.EXTRA_DISCOVERABLE_DURATION,300);startActivityForResult(enable,REQUEST_DISCOVERABLE);}@Overrideprotected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {switch (requestCode){case REQUEST_DISCOVERABLE:if(resultCode == Activity.RESULT_CANCELED){Toast.makeText(this,"蓝牙未开启",Toast.LENGTH_SHORT).show();}else{Toast.makeText(this,"蓝牙开启成功",Toast.LENGTH_SHORT).show();mBluetoothAdapter.startDiscovery();}break;default:break;}}private class BluetoothReceiver extends BroadcastReceiver {@Overridepublic void onReceive(Context context, Intent intent) {String action = intent.getAction();if(BluetoothDevice.ACTION_FOUND.equals(action)){BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);String str = device.getName() + "|" +device.getAddress();if(listDevice.indexOf(str) == -1){  //防止重复添加listDevice.add(str);}if(mAdapter != null){mAdapter.notifyDataSetChanged();}showDevices();}else if(BluetoothAdapter.ACTION_DISCOVERY_FINISHED.equals(action)){}}}private void showDevices(){mAdapter = new ArrayAdapter<String>(this,android.R.layout.simple_list_item_1,listDevice);listView.setAdapter(mAdapter);}private final Handler handler = new Handler(){@Overridepublic void handleMessage(Message msg) {switch (msg.what){case BlueToothTool.CONNECT_FAILED:Toast.makeText(MainActivity.this,"连接失败",Toast.LENGTH_SHORT).show();break;case BlueToothTool.CONNECT_SUCCESS:Toast.makeText(MainActivity.this,"连接成功",Toast.LENGTH_SHORT).show();listView.setVisibility(View.GONE);  //连接成功后移除listview 设置其他布局可见status.setText("已连接");address.setText(client.getAddress());relativeLayout.setVisibility(View.VISIBLE);break;case BlueToothTool.READ_FAILED:Toast.makeText(MainActivity.this,"读取失败",Toast.LENGTH_SHORT).show();break;case BlueToothTool.WRITE_FAILED:Toast.makeText(MainActivity.this,"发送失败",Toast.LENGTH_SHORT).show();break;case BlueToothTool.PIPEI_SUCCESS:Toast.makeText(MainActivity.this,"正在连接",Toast.LENGTH_SHORT).show();break;case BlueToothTool.PIPEI_FAILED:Toast.makeText(MainActivity.this,"连接失败",Toast.LENGTH_SHORT).show();break;case BlueToothTool.DATA:break;}}};@Overrideprotected void onResume() {  //注册广播接收器super.onResume();IntentFilter filter = new IntentFilter(BluetoothDevice.ACTION_FOUND);receiver = new BluetoothReceiver();registerReceiver(receiver,filter);filter = new IntentFilter(BluetoothAdapter.ACTION_DISCOVERY_FINISHED);registerReceiver(receiver,filter);}@Overrideprotected void onDestroy() {  //注销广播接收器,关闭蓝牙unregisterReceiver(receiver);mBluetoothAdapter.disable();super.onDestroy();}
}

PS:在这里因为是Demo就没有写具体连接成功后的功能,只是放了一个布局,说一下发送数据怎么写,例如单击某个控件的话可以这样写

     XXX.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {BlueToothTool.Writetask w = client.new Writetask(str);w.start();}});

使用连接的设备 client 创建一个发送数据的线程并传入数据并 start 即可。

工具类BluetoothTool
public class BlueToothTool {private BluetoothDevice device;private Handler mhandler;BluetoothSocket socket;private BluetoothAdapter adapter;static final int CONNECT_FAILED = -1;static final int CONNECT_SUCCESS = 1;static final int PIPEI_SUCCESS = 2;static final int PIPEI_FAILED = -2;static final int READ_FAILED = -11;static final int WRITE_FAILED = -22;static final int DATA = 99;private boolean isConnect = false;private static final String MY_UUID ="00001101-0000-1000-8000-00805F9B34FB";public BlueToothTool(BluetoothDevice device, Handler handler){this.device = device;this.mhandler = handler;}public String getAddress(){return device.getAddress();}/*** 开辟连接线程任务*/public void connect(){Thread thread = new Thread(new Runnable() {@Overridepublic void run() {BluetoothSocket tmp = null;adapter = BluetoothAdapter.getDefaultAdapter();try{tmp = device.createRfcommSocketToServiceRecord(UUID.fromString(MY_UUID));}catch (Exception e){setState(PIPEI_FAILED);Log.d("TAG", e.toString());}setState(PIPEI_SUCCESS);socket = tmp;adapter.cancelDiscovery();try{socket.connect();isConnect = true;setState(CONNECT_SUCCESS);//Readtask readtask = new Readtask(); //连接之后开启立即开启读取线程//readtask.start();}catch (Exception e){setState(CONNECT_FAILED);Log.d("TAG", e.toString());}}});new Thread(thread).start();}/*** 开辟线程读任务*/public class Readtask extends Thread{@Overridepublic void run() {byte[] buffer = new byte[1024];int bytes;InputStream inputStream;while(true){try{inputStream = socket.getInputStream();if((bytes = inputStream.read(buffer)) > 0){byte[] buf_data = new byte[bytes];for(int i = 0;i < bytes;i++){buf_data[i] = buffer[i];}String s = new String(buf_data);//TODO//读取的数据进行处理Message msg = mhandler.obtainMessage();msg.what = DATA;msg.obj = s;mhandler.sendMessage(msg);}}catch (IOException e){setState(READ_FAILED);Log.d("TAG", e.toString());break;}}if(socket!= null){try{socket.close();}catch (IOException e){Log.d("TAG", e.toString());}}}}/*** 开辟线程写任务*/public class Writetask extends Thread{  //将字符串参数转换为字节数组发送出去private String srt;public Writetask(String str){this.srt = str;}@Overridepublic void run() {OutputStream outputStream = null;byte[] st = srt.getBytes();try{outputStream = socket.getOutputStream();outputStream.write(st);}catch(Exception e){setState(WRITE_FAILED);Log.d("TAG", e.toString());}}}private void setState(int mes){Message message = new Message();message.what = mes;mhandler.sendMessage(message);}}

至此就可以连接上了,如果有什么不懂得可以在下方评论大家一起交流

测试图:后期补图

Demo地址:https://github.com/GYongJia/BluetoothDemoWith32

Android开发-连接开发板蓝牙模块发送和接收数据相关推荐

  1. Android-Ble蓝牙开发Demo示例–扫描,连接,发送和接收数据

    万物互联的物联网时代的已经来临,ble蓝牙开发在其中扮演着举重若轻的角色.最近刚好闲一点,抽时间梳理下这块的知识点. 涉及ble蓝牙通讯的客户端(开启.扫描.连接.发送和接收数据.分包解包)和服务端( ...

  2. Android端 同 单片机 利用蓝牙模块的通信实现

    这次期末的课程设计做了一个智能灯光控制系统,系统整体的功能不在此赘述,系统主要是要实现下位机同上位机的通信,上位机选用的是Android手机端,下位机是52单片机,通过蓝牙模块实现通信.虽然系统很简单 ...

  3. 25. Python语言 Web 开发 之 Socket 编程 · 第一章 UDP发送与接收数据

    UDP发送与接收数据 本章主题 关键词 前导: 计算机网络的发展及基础网络概念 两台电脑的通信 IP地址介绍及分类 IP地址与IP协议 Windows 和 Linux 查看网卡信息 IP地址分类 以太 ...

  4. 手把手教你Android手机与BLE终端通信--连接,发送和接收数据

    假设你还没有看上一篇 手把手教你Android手机与BLE终端通信--搜索,你就先看看吧,由于这一篇要接着讲搜索到蓝牙后的连接.和连接后的发送和接收数据. 评论里有非常多人问假设一条信息特别长,怎么不 ...

  5. 嵌入式单片机基础篇(二十七)之Stm32F103单片机给蓝牙模块发送AT指令程序

    Stm32F103单片机给蓝牙模块发送AT指令程序 #include "stm32f10x.h" #include "string.h" #include &q ...

  6. 【TL8266】APP接收蓝牙模块发送过来的消息

    前一篇文章讲述了如何向蓝牙模块发送数据,这一篇讲述如何接收数据,点击开关按钮发送AT指令,模块会返回OK 先做一个广播接收器,按Ctrl+F关注mBluetoothLeService的操作 publi ...

  7. 计算机网络没有接收数据,本地连接有发送无接收数据的解决方法

    "本地连接"有发送无接收数据的解决方法 发布时间:2013-07-23 23:34:03   作者:佚名   我要评论 在日常的网络维护中,常常出现"本地连接" ...

  8. 无线发射器c语言程序代码,单片机编码 无线模块发送与接收 程序

    单片机编码 无线模块发送与接收 程序 模块型号,可在万能的某宝搜索[超再生无线模块] 接收距离:空旷200米[这是卖家说的,有待考验] 接收端在没有收到讯号,会生成间歇性尖状脉冲,data接LED负极 ...

  9. 单片机无线模块编码和解码c语言,单片机编码 无线模块发送与接收 程序

    单片机编码 无线模块发送与接收 程序 模块型号,可在万能的某宝搜索[超再生无线模块] 接收距离:空旷200米[这是卖家说的,有待考验] 接收端在没有收到讯号,会生成间歇性尖状脉冲,data接LED负极 ...

最新文章

  1. 过滤请求绝技,布隆过滤器与布谷鸟过滤器
  2. Linux常用命令——paste
  3. 三步骤定位Windows崩溃进程
  4. python网站服务器好麻烦_python写的网站,云服务器经常无法访问
  5. 成信大c语言答案P239.C,2011秋季江苏省计算机二级C语言试题与答案.doc
  6. list某字段去重再合并统计_java mapreduce实现数据去重
  7. 【转】OAuth的改变
  8. html大小和浏览器可视区域一样吗,浏览器窗口可视区域大小和网页尺寸和网页卷去的距离与偏移量...
  9. GIS地理空间数据免费获取
  10. DS1302时钟芯片(SPI协议)
  11. 医疗CT断层图像DICOM标准和工业CT断层图像DICONDE标准
  12. 美团面试-2016校园招聘
  13. Provision not found. A provision is required for deploying your app to the device. 解决方案
  14. CPU内存乱序访问与内存屏障
  15. LeetCode 37. 解数独 Sudoku Solver
  16. 数学基础 - 第十八章 平行四边形
  17. Dnspod域名设置
  18. css实现固定的图片比例
  19. sourcetree 与 命令对比
  20. eps倾斜摄影矢量化采集毕业设计_eps倾斜摄影矢量化dlg采集难点.docx

热门文章

  1. 【Java】流(Stream)快速入门
  2. 获取cookie时返回RequestsCookieJar的解决方法
  3. 使用JS批量爬取抖音视频无水印链接
  4. 国产PAN3501三通道低功耗ASK接收125K底片唤醒芯片兼容替代AS3933
  5. 公安机关查处了100款违法采集个人信息的APP
  6. access中除号意思_2017年信息技术(学考)必背知识点整理
  7. java-php-python-ssm预防接种服务平台计算机毕业设计
  8. AttributeError: module ‘matplotlib’ has no attribute ‘figure’
  9. threejs基本知识5 (贴图)
  10. 苹果电脑 Mac 下终端中删除文件的命令