android实现手机与单片机蓝牙模块通信

本文实例为大家分享了android实现手机与单片机蓝牙模块通信的具体代码,供大家参考,具体内容如下

我是参考原博客的内容去写的,由于原博客写的不全,少了关键的几个类,然后我就凭借自己扎实的功底补出来了,现在蓝牙工作正常,能发能收!在看这边文章之前你要先了解一下蓝牙的工作状态,我的代码里面可能解释的不是很详细,但是我自己是能看懂的!

package com.example.fsl.bluetooth; 

import android.app.Activity;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothSocket;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Handler;
import android.os.Message;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.support.v7.widget.Toolbar;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
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.ProgressBar;
import android.widget.TextView;
import android.widget.Toast; 

import java.util.ArrayList;
import java.util.List;
import java.util.UUID; 

public class MainActivity extends AppCompatActivity {
 private Toolbar toolbar;
 private TextView status;
 private StringBuilder mstringbuilder;
 private static final UUID MY_UUID=UUID.fromString("00001101-0000-1000-8000-00805F9B34FB");//没有用到
 BluetoothReceiver receiver;
 BluetoothAdapter mBtAdapter;
 BluetoothSocket mBtSocket;
 private BlueToothTool client;
 private ListView mListView;
 private List<String> ListDevice;
 private ArrayAdapter<String> mAdapter;
 private Button mbutton;
 private EditText editText;
 private ProgressBar progressBar;
 private LoopProgressBar loopProgressBar;
 @Override
 protected void onCreate(Bundle savedInstanceState) {
 super.onCreate(savedInstanceState);
 setContentView(R.layout.activity_main);
 toolbar=(Toolbar)findViewById(R.id.toolbar);
 status=(TextView)findViewById(R.id.textView2);
 mListView=(ListView)findViewById(R.id.listView);
 mbutton=(Button)findViewById(R.id.button);
 editText=(EditText)findViewById(R.id.editText);
 progressBar=(ProgressBar)findViewById(R.id.progressBar);
 progressBar.setVisibility(View.INVISIBLE);
 loopProgressBar=(LoopProgressBar)findViewById(R.id.loop);
 ListDevice=new ArrayList<String>();
 mstringbuilder=new StringBuilder();
 setSupportActionBar(toolbar);
 enablebluetooth();
 mbutton.setOnClickListener(new View.OnClickListener() {
 @Override
 public void onClick(View v) {
 BlueToothTool.WriteTask W=client.new WriteTask(editText.getText().toString());
 W.start();
 }
 });
 mListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
 @Override
 public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
 mBtAdapter.cancelDiscovery();//停止搜索
 progressBar.setVisibility(View.INVISIBLE);
 String str = ListDevice.get(position);
 String macAdress = str.split("\\|")[1];
 BluetoothDevice device = mBtAdapter.getRemoteDevice(macAdress);
 client=new BlueToothTool(device,handler);
 try{
  client.connect();
 }catch (Exception e){
  e.printStackTrace();
 }
 }
 });
 } 

 /**
 *开启蓝牙且被发现
 */
 private void enablebluetooth(){
 mBtAdapter=BluetoothAdapter.getDefaultAdapter(); 

 /**
 *if(!mBtAdapter.isEnabled()){这里可以先使能,可以在REQUEST_DISCOVERABLE处使能,这样的话可以连使能和请求被发现一块完成
 // mBtAdapter.enable();
 Intent enableIntent=new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
 startActivityForResult(enableIntent,REQUEST_ENABLE);
 }
 else {
 show("蓝牙已开启");
 }*/
 Intent enable = new Intent(BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE);
 enable.putExtra(BluetoothAdapter.EXTRA_DISCOVERABLE_DURATION, 300);
 startActivityForResult(enable, REQUEST_DISCOVERABLE);
 } 

 /**
 * 销毁事件,注销广播
 */
 @Override
 protected void onDestroy() {
 unregisterReceiver(receiver);
 super.onDestroy();
 }
 private final Handler handler = new Handler() {
 @Override
 public void handleMessage(Message msg) {
 switch (msg.what) {
 case BlueToothTool.CONNECT_FAILED:
  show("连接失败");
  try {
  client.connect();
  } catch (Exception e) {
  Log.e("TAG", e.toString());
  }
  break;
 case BlueToothTool.CONNECT_SUCCESS:
  show("连接成功");
  mListView.setVisibility(View.INVISIBLE);
  break;
 case BlueToothTool.READ_FAILED:
  show("读取失败");
  break;
 case BlueToothTool.WRITE_FAILED:
  show("写入失败");
  break;
 case BlueToothTool.DATA:
  mstringbuilder.append(msg.obj.toString());
  show(mstringbuilder.toString());
  break;
 }
 }
 };
 /**
 * 请求响应结果
 * @param requestCode
 * @param resultCode
 * @param data
 */
 @Override
 protected void onActivityResult(int requestCode, int resultCode, Intent data) {
 switch (requestCode){ 

 /**
 *case REQUEST_ENABLE:
 if(requestCode!= Activity.RESULT_OK){
  show("蓝牙未开启");
 }
 else
  show("蓝牙已开启");
 break;*/
 case REQUEST_DISCOVERABLE:
 if(resultCode==Activity.RESULT_CANCELED){
  show("蓝牙未开启");
 }
 else
  show("蓝牙已开启");
 break;
 default:
  break;
 }
 }
 public boolean onCreateOptionsMenu(Menu menu){
 getMenuInflater().inflate(R.menu.menu,menu);
 return true;
 }
 private static final int REQUEST_ENABLE=1;
 private static final int REQUEST_DISCOVERABLE=2; 

 /**
 * 注册广播事件
 */
 @Override
 public 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);
 } 

 /**
 * 广播
 */
 private class BluetoothReceiver extends BroadcastReceiver {
 @Override
 public 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); // 获取设备名称和mac地址
 if (mAdapter != null) {
  mAdapter.notifyDataSetChanged();
 }
 showDevices();
 }
 else if(BluetoothAdapter.ACTION_DISCOVERY_FINISHED.equals(action)){
 progressBar.setVisibility(View.INVISIBLE);
 show("已停止寻找");
 } 

 }
 };
 /**
 * 菜单栏点击事件
 * @param item
 * @return
 */
 @Override
 public boolean onOptionsItemSelected(MenuItem item) {
 switch (item.getItemId()){
 case R.id.search:
 if(!mBtAdapter.isEnabled()){
  show("蓝牙未开启");
 }
 else {
  mBtAdapter.startDiscovery();
  show("正在寻找设备");
  progressBar.setVisibility(View.VISIBLE);
 }
 break;
 case R.id.about:
 Toast.makeText(MainActivity.this,"关于我们",Toast.LENGTH_SHORT).show();
 break;
 default:
 }
 return true;
 }
 private void showDevices() {
 mAdapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1,
 ListDevice);
 mListView.setAdapter(mAdapter);
 }
 /**
 * 更新UI方法
 * @param string
 */
 private void show(final String string){
 runOnUiThread(new Runnable() {
 @Override
 public void run() {
 status.setText(string);
 }
 });
 }
}

然后我的读任务和写任务以及连接任务是在另一个类里面实现的,也就是BlueToothTool类,这个类一个原博客是没有写的,只是MainActivity中用到了这个类的一些方法,但是没有给出,所以就让一些同学很蛋疼。我看完之后是自己补全的这个类!

package com.example.fsl.bluetooth; 

import android.app.Notification;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothSocket;
import android.content.Context;
import android.os.Handler;
import android.os.Message;
import android.support.v4.app.NotificationCompat;
import android.util.Log; 

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.lang.reflect.Method; 

import java.util.logging.LogRecord; 

/**
 * Created by Fsl on 2017/12/22.
 */ 

public class BlueToothTool {
 private BluetoothDevice device;
 private Handler mhandler;
 BluetoothSocket socket;
 static final int CONNECT_FAILED=1;
 static final int CONNECT_SUCCESS=5;
 static final int READ_FAILED=2;
 static final int WRITE_FAILED=3;
 static final int DATA=4;
 private boolean isConnect=false; 

 public BlueToothTool(BluetoothDevice device,Handler handler){
 this.device=device;
 this.mhandler=handler;
 }
 /**
 *开辟连接线程任务
 */
 public void connect(){
 Thread thread = new Thread(new Runnable() {
 @Override
 public void run() {
 BluetoothSocket tmp = null;
 Method method;
 try {
  method = device.getClass().getMethod("createRfcommSocket", new Class[]{int.class});
  tmp = (BluetoothSocket) method.invoke(device, 1);
 } catch (Exception e) {
  setState(CONNECT_FAILED);
  Log.e("TAG", e.toString());
 }
 socket = tmp;
 try {
  socket.connect();
  isConnect = true;
  setState(CONNECT_SUCCESS);
  Readtask readtask = new Readtask(); //连接成功后开启读取数据的线程
  readtask.start();
 } catch (Exception e) {
  setState(CONNECT_FAILED);
  Log.e("TAG", e.toString());
 }
 }
 });
 new Thread(thread).start();
 }
 /**
 *开辟线程读任务
 */
 public class Readtask extends Thread{
 @Override
 public 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);
  Message msg = mhandler.obtainMessage();
  msg.what = DATA;
  msg.obj = s;
  mhandler.sendMessage(msg);
  }
 } catch (IOException e) {
  setState(READ_FAILED);
  Log.e("TAG", e.toString());
  break;
 }
 } 

 if (socket != null) {
 try {
  socket.close();
 } catch (IOException e) {
  Log.e("TAG", e.toString());
 }
 }
 }
 }
 /**
 *开辟线程写任务
 */
 public class WriteTask extends Thread{
 private String srt;
 public WriteTask(String str){
 this.srt=str;
 }
 @Override
 public void run(){
 OutputStream outputStream=null;
 byte[] st=srt.getBytes();
 try{
  outputStream=socket.getOutputStream();
  outputStream.write(st);
  }catch (Exception e){
  setState(WRITE_FAILED);
  e.printStackTrace();
 }
 } 

 } 

 private void setState(int mes){
 Message message=new Message();
 message.what=mes;
 mhandler.sendMessage(message); 

 }
 /**
 *下面这个方法目前还没有用到
 */
 private byte[] getHexBytes(String message) {
 int len = message.length() / 2;
 char[] chars = message.toCharArray();
 String[] hexStr = new String[len];
 byte[] bytes = new byte[len];
 for (int i = 0, j = 0; j < len; i += 2, j++) {
 hexStr[j] = "" + chars[i] + chars[i + 1];
 bytes[j] = (byte) Integer.parseInt(hexStr[j], 16);
 }
 return bytes;
 } 

} 

以上就是我的蓝牙与单片机连接通信的全过程,顺便说一下,这个连接是自动连接的,不需要什么秘钥什么的,直接搜索到HC-05蓝牙直接就可以确定连接,亲测有效。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • 关于单片机按键问题性能提升总结

    最近看了一本书<8051单片机创新教程>,这本书比大学课本写得好,在大学的课本中,我们常见的按键扫描程序如下: unsinged char KeyScan(void) { unsigned char KeyValue=0; if(KEY_IO != 0xFF) //检测到有按键按下 { DelayNms(20); //延时 20 毫秒(严重影响单片机的运行效率) if(KEY_IO != 0xFF)//确认按键按下 { switch(KEY_IO) { case 0xFE: KeyValue=

  • C语言宏定义结合全局变量的方法实现单片机串口透传模式

    何谓透传? 根据百度百科给出的定义如下: 透传,即透明传输(pass-through),指的是在通讯中不管传输的业务内容如何,只负责将传输的内容由源地址传输到目的地址,而不对业务数据内容做任何改变. 在现实单片机产品开发过程中,如果存在多个串口,在调试打印某个模块信息的时候,大多数人的做法是将所有模块的TX.RX.GND引出来,分别接到不同的调试口去,通过PC终端去将这些信息分别打印出来.这样子做难免会弄错,甚至非常繁琐,万一不小心还会接错导致模块烧坏. 于是,透传模式的出现就是为了解决这样的问

  • Android Socket 线程连接openwrt与arduino单片机串口双向通信的实例解析

    废话不多说了,直接给大家贴代码了,具体代码如下所示: package zcd.netanything; import java.io.BufferedReader; import java.io.InputStreamReader; import java.io.PrintWriter; import java.net.Socket; import android.app.Fragment; import android.content.BroadcastReceiver; import and

  • Android单片机与蓝牙模块通信实例代码

    啦啦毕业了,毕业前要写毕业设计,需要写一个简单的蓝牙APP进行交互,通过参考网上资料,问题顺利搞定,下面小编把具体实现思路分享给大家,供大家参考. 1.Android蓝牙编程 蓝牙3.0及以下版本编程需要使用UUID,UUID是通用唯一识别码(Universally Unique Identifier),这是一个软件构建的标准,也是被开源基金会组织应用在分布式计算环境领域的一部分.在蓝牙3.0及下一版本中,UUID被用于唯一标识一个服务,比如文件传输服务,串口服务.打印机服务等,如下: #蓝牙串

  • Android与单片机通信常用数据转换方法总结

    Android与单片机通信常用数据转换方法 1.  将GB2312转化为中文,如BAFAC2DCB2B7→胡萝卜,两个字节合成一个文字 public static String stringToGbk(String string) throws Exception { byte[] bytes = new byte[string.length() / 2]; for (int j = 0; j < bytes.length; j++) { byte high = Byte.parseByte(s

  • c#实现51单片机频率计的代码分享(数字频率计设计)

    复制代码 代码如下: #include <reg51.h>#define uchar unsigned char#define uint unsigned int#define ulong unsigned long //按键sbit button=P1^7;//LEDsbit led2=P3^5;sbit led3=P3^7;//数码管位选sbit c0 = P3^0;sbit c1 = P3^1;sbit c2 = P3^2;sbit c3 = P3^3;//数码管段码uchar code

  • 使用UART与PC通信实现msp430g2553单片机超声波测距示例

    适用于msp430g2553单片机  使用到了hc-sr04超声测距模块,使用UART与PC通信. 复制代码 代码如下: #include <msp430.h>long current_time;//最近一次测得时间/*MyPro*/#define LED_1 BIT0                      #define SW_2 BIT3                       #define TA1_1 BIT2                      //TA0.1 HC-S

  • android实现手机与单片机蓝牙模块通信

    本文实例为大家分享了android实现手机与单片机蓝牙模块通信的具体代码,供大家参考,具体内容如下 我是参考原博客的内容去写的,由于原博客写的不全,少了关键的几个类,然后我就凭借自己扎实的功底补出来了,现在蓝牙工作正常,能发能收!在看这边文章之前你要先了解一下蓝牙的工作状态,我的代码里面可能解释的不是很详细,但是我自己是能看懂的! package com.example.fsl.bluetooth; import android.app.Activity; import android.blue

  • Android React Native原生模块与JS模块通信的方法总结

    Android React Native原生模块与JS模块通信的方法总结 前言: 在做React Native开发的时候避免不了的需要原生模块和JS之间进行数据传递,这篇文章将向大家分享原生模块向JS传递数据的几种方式. 方式一:通过Callbacks的方式 说起Callbacks大家都不陌生,它是最常用的设计模式之一.无论是Java,Object-c,C#,还是JavaScript等都会看到Callbacks的身影. 原生模块支持Callbacks类型的参数,该Callbacks对应JS中的f

  • Android UI手机信息页面设计

    本文实例为大家分享了Android UI 手机信息页面展示的具体代码,供大家参考,具体内容如下 1. 运行效果图 2. 设计思路(实现原理) 1.将准备好的八个图标复制到res/drawable文件夹下 2.创建一个垂直的线性布局,并在线性布局中创建4个相对布局 3.在相对布局中添加相应的TextView 4.在values文件下的style.xml文件中存放抽取出来的样式 5.创建values-zh-rCN.values-en-rUS文件夹,并在文件夹中创建strings.xml文件夹 3.案

  • Android开发实现实时检测蓝牙连接状态的方法【附源码下载】

    本文实例讲述了Android开发实现实时检测蓝牙连接状态的方法.分享给大家供大家参考,具体如下: 本程序能实时监听并检测Android蓝牙的连接状态,无论是通过界面上的switch按钮打开/关闭手机蓝牙,还是手动打开/关闭手机蓝牙,程序都能监听当前的状态. 一.软件界面 二.程序实现 ① switch开关--打开/关闭蓝牙 Switch switchTest = (Switch) findViewById(R.id.switch1); switchTest.setOnCheckedChangeL

  • Android获取手机屏幕宽高、状态栏高度以及字符串宽高信息的方法

    本文实例讲述了Android获取手机屏幕宽高.状态栏高度以及字符串宽高信息的方法.分享给大家供大家参考.具体如下: 首先定义TextView对象commentText 获取文字的宽高: TextPaint textPaint = new TextPaint(Paint.ANTI_ALIAS_FLAG); textPaint.setTextSize(commentText.getTextSize()); textPaint.setColor(Color.WHITE); FontMetrics fo

  • 基于python select.select模块通信的实例讲解

    要理解select.select模块其实主要就是要理解它的参数, 以及其三个返回值. select()方法接收并监控3个通信列表, 第一个是所有的输入的data,就是指外部发过来的数据,第2个是监控和接收所有要发出去的data(outgoing data),第3个监控错误信息在网上一直在找这个select.select的参数解释, 但实在是没有, 哎...自己硬着头皮分析了一下. readable, writable, exceptional = select.select(inputs, ou

  • android 获取手机内存及 内存可用空间的方法

    实例如下: //1.获取内存可用大小,内存路径 String path=Environment.getDataDirectory().getAbsolutePath(); String memoryAvaliSpace= Formatter.formatFileSize(this,getAvailSpace(path)); //2.获取sd卡可用大小,sd卡路径 String sdPath=Environment.getExternalStorageDirectory().getAbsolute

  • Android实现手机振动设置的方法

    本文实例讲述了Android实现手机振动设置的方法.分享给大家供大家参考.具体如下: main.xml布局文件: <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" androi

  • Android调用手机拍照功能的方法

    本文实例讲述了Android调用手机拍照功能的方法.分享给大家供大家参考.具体如下: 一.main.xml布局文件: <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" andr

随机推荐