Android实现和下位机蓝牙通讯
内容导读
互联网集市收集整理的这篇技术教程文章主要介绍了Android实现和下位机蓝牙通讯,小编现在分享给大家,供广大互联网技能从业者学习和参考。文章包含10681字,纯文字阅读大概需要16分钟。
内容图文
1.在程序配置文件中声明蓝牙权限。
< uses-permission android:name ="android.permission.BLUETOOTH" /> < uses-permission android:name ="android.permission.BLUETOOTH_ADMIN" /> < uses-permission android:name ="android.permission.BLUETOOTH_PRIVILEGED" />
2.新建通用的扫描选择蓝牙设备的布局和活动。
activity_bt.xml
<? xml version="1.0" encoding="utf-8" ?> < LinearLayout xmlns:android ="http://schemas.android.com/apk/res/android" android:orientation ="vertical" android:layout_width ="match_parent" android:layout_height ="match_parent" > < Button android:id ="@+id/btnQueryBt" android:layout_width ="match_parent" android:layout_height ="wrap_content" android:text ="直接进入软件" android:layout_marginTop ="16dp" /> < Button android:id ="@+id/btnSearchBt" android:layout_width ="match_parent" android:layout_height ="wrap_content" android:text ="扫描蓝牙设备" android:layout_marginTop ="16dp" /> < TextView android:id ="@+id/txtConnectState" android:layout_width ="match_parent" android:layout_height ="wrap_content" android:layout_marginTop ="16dp" /> < ListView android:id ="@+id/lstBtName" android:layout_width ="match_parent" android:layout_height ="wrap_content" android:layout_marginTop ="16dp" > </ ListView > </ LinearLayout >
BtActivity.java
public class BtActivity extends BaseActivity { private Button btnSearchBt;//初始界面的扫描按钮private Button btnIntoQuery;//初始界面的进入查询按钮private TextView txtConnectState; private ListView lstBtName; private BtOperation btOperation = new BtOperation(); private BluetoothReceiver mBluetoothReceiver = new BluetoothReceiver(); ArrayList<String> btNameList = new ArrayList<>(); @Override protectedvoid onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_bt); // checkBtUnable(); // initButton(); } @Override protectedvoid onDestroy() { super.onDestroy(); // unregisterReceiver(mBluetoothReceiver); } class BluetoothReceiver extends BroadcastReceiver{ @Override publicvoid onReceive(Context context, Intent intent) { String action = intent.getAction(); if(BluetoothDevice.ACTION_FOUND.equals(action)){ BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE); btNameList.add(device.getName()); btNameList.add(device.getAddress()); //如果设备还没绑定,则将设备显示到列表中,并提醒用户配对if(device.getBondState()!=BluetoothDevice.BOND_BONDED){ ArrayAdapter<String> adapter = new ArrayAdapter<String>( BtActivity.this,android.R.layout.simple_list_item_1,btNameList); lstBtName.setAdapter(adapter); txtConnectState.setText("选择设备进行配对"); } //如果设备已经配对,直接显示在列表中,然后直接跳转到主界面else { ArrayAdapter<String> adapter = new ArrayAdapter<String>( BtActivity.this,android.R.layout.simple_list_item_1,btNameList); lstBtName.setAdapter(adapter); txtConnectState.setText("配对成功"); // RunActivity.actionStart(BtActivity.this,device.getAddress()); } } elseif (BluetoothAdapter.ACTION_DISCOVERY_FINISHED.equals(action)) { txtConnectState.setText("蓝牙设备搜索完毕"); } elseif (BluetoothAdapter.ACTION_DISCOVERY_STARTED.equals(action)) { txtConnectState.setText("正在扫描蓝牙设备"); } elseif(BluetoothDevice.ACTION_BOND_STATE_CHANGED.equals(action)){ BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE); if(device.getBondState()== BluetoothDevice.BOND_BONDING){ txtConnectState.setText("正在配对中"); }elseif(device.getBondState() == BluetoothDevice.BOND_BONDED){ txtConnectState.setText("配对成功"); // RunActivity.actionStart(BtActivity.this,device.getAddress()); } } } } /** * 检查用户设备是否支持蓝牙,如果不支持,就退出程序,并提示用户。如果支持,直接打开蓝牙。 */privatevoid checkBtUnable(){ if(!btOperation.checkBt()){ Toast.makeText(this,"你的设备不支持蓝牙!请更换设备!",Toast.LENGTH_LONG).show(); // finish(); } } /** * 初始化启动界面的两个按钮 */privatevoid initButton(){ txtConnectState = (TextView)findViewById(R.id.txtConnectState); //蓝牙设备清单,点击特定名称,可以连接设备 lstBtName = (ListView)findViewById(R.id.lstBtName); lstBtName.setOnItemClickListener(new AdapterView.OnItemClickListener() { @Override publicvoid onItemClick(AdapterView<?> adapterView, View view, int i, long l) { if(btNameList.get(i).equals("HC-05")){ btOperation.devBond(btNameList.get(i+1)); } } }); //蓝牙操作按钮 btnSearchBt = (Button)findViewById(R.id.btnSearchBt); btnSearchBt.setOnClickListener(new View.OnClickListener() { @Override publicvoid onClick(View view) { btOperation.openBt(); } }); btnIntoQuery = (Button)findViewById(R.id.btnQueryBt); //进入查询数据界面 btnIntoQuery.setOnClickListener(new View.OnClickListener() { @Override publicvoid onClick(View view) { // Intent intent = new Intent(BtActivity.this,QueryActivity.class); // startActivity(intent); } }); btOperation.registerBtReceiver(this,mBluetoothReceiver); //初始化最后直接打开蓝牙,如果之前绑定过蓝牙,会直接进入,否则需要点击扫描按钮来打开蓝牙 btOperation.openBt(); } }
设备配对后,还需要开启后台蓝牙消息服务
SerialBtService.java
/** * 的到一个远程设备地址后,和地址建立连接,建立输入输出流, * <p>提供发送蓝牙信息的封装</p> * <p>将接收的蓝牙信息拆包并用内部广播发送出去</p> */ public class SerialBtService extends Service { privatestaticfinal UUID SerialBlueToothDev_UUID = UUID.fromString("00001101-0000-1000-8000-00805F9B34FB"); private String devAddr = null; private OutputStream mOutputStream=null; private InputStream mInputStream=null; private BluetoothAdapter mBluetoothAdapter=null; private BluetoothSocket mBluetoothSocket=null; privateboolean mFlag=true; privateint[] dataRec = newint[100]; privateint couts = 0; /** * 启动蓝牙传输服务类所需要的蓝牙设备地址 */publicstaticfinal String DEV_ADDR = "devAddr"; /** * 向外发送蓝牙信息的广播Intent中,信息的标识符 */publicstaticfinal String BT_SEND_MESS = "BT_CMD"; /** * 从外部接收的蓝牙信息的广播Intent中,信息的标识符 * <p>表示一个拆包的信息已经发送了,需要的模块可以接收</p> */publicstaticfinal String BT_RECEIVE_MESS = "BT_DATA"; /** * 向外发送蓝牙信息时的注册广播标识符 */publicstaticfinal String BT_SEND_BROADCAST = "com.jiaweiqiang.tools.SEND_MSG"; /** * 接收外部蓝牙信息时的注册广播标识符 */publicstaticfinal String BT_RECEIVE_BROADCAST = "com.jiaweiqiang.fycdy.RECEIVE_MSG"; public SerialBtService() { } //接收其他活动传来的要发送的蓝牙信息的广播接收器private BroadcastReceiver mReceiver = new BroadcastReceiver() { @Override publicvoid onReceive(Context context, Intent intent) { // String btMessage = intent.getStringExtra(BT_SEND_MESS);int[] btMessage = intent.getIntArrayExtra(BT_SEND_MESS); if(btMessage==null||btMessage.equals("")){ Toast.makeText(MyApplication.getContext(),"无效输入",Toast.LENGTH_SHORT).show(); }else { writeSingleData(btMessage); } } }; @Override publicvoid onDestroy() { super.onDestroy(); try{ mBluetoothSocket.close(); }catch (IOException e){ e.printStackTrace(); } MyApplication.getLocalBroadcastManager().unregisterReceiver(mReceiver); } /** * 启动本服务的启动函数 * @param context 启动服务的上下位 * @param devAddr 蓝牙设备的mac地址 */publicstaticvoid startService(Context context,String devAddr){ Intent intent = new Intent(MyApplication.getContext(),SerialBtService.class); intent.putExtra(DEV_ADDR,devAddr); context.startService(intent); } publicstaticvoid stopService(Context context){ Intent intent = new Intent(context,SerialBtService.class); context.stopService(intent); } /** * 通过服务发送蓝牙数据 * @param mess 要发送的字符串数据 */publicstaticvoid sendStringMess(String mess){ int[] data = Convert.stringToIntArray(mess); sendIntArrayMess(data,data.length); } /** * 发送byte数组出去,将每个byte的值存入int数组中,将字节数组发送出去 * @param mess 要发送的字节数组 * @param lenth 发送字节的长度 */publicstaticvoid sendIntArrayMess(int[] mess, int lenth){ int[] copyMess = newint[lenth]; System.arraycopy(mess,0,copyMess,0,lenth); Intent intent = new Intent(BT_SEND_BROADCAST); intent.putExtra(SerialBtService.BT_SEND_MESS,copyMess); MyApplication.getLocalBroadcastManager().sendBroadcast(intent); } @Override publicint onStartCommand(Intent intent, int flags, int startId) { devAddr = intent.getStringExtra(DEV_ADDR);//通过建立Service,Intent传入蓝牙地址 //声明并注册发送蓝牙信息的广播接收器,以便接收到广播后,将信息发送出去 IntentFilter intentFilter = new IntentFilter(); intentFilter.addAction(BT_SEND_BROADCAST); MyApplication.getLocalBroadcastManager().registerReceiver(mReceiver,intentFilter); mBluetoothAdapter=BluetoothAdapter.getDefaultAdapter(); //为接收蓝牙信息单独开启一个线程 SerialBtThread thread = new SerialBtThread(); thread.start(); // Toast.makeText(MyApplication.getContext(),"服务已经启动",Toast.LENGTH_SHORT).show();returnsuper.onStartCommand(intent, flags, startId); } @Override public IBinder onBind(Intent intent) { // TODO: Return the communication channel to the service.thrownew UnsupportedOperationException("Not yet implemented"); } /** * 向外发送蓝牙信息,这是以string的形式发送的 * @param msg 要发送的信息 */privatevoid writeSerialBt(String msg){ try{ mOutputStream.write(msg.getBytes()); mOutputStream.flush(); }catch (IOException e){ e.printStackTrace(); } } /** * 传入int数组,以单个字节形式循环把数组发送出去 * @param msg */privatevoid writeSingleData(int[] msg){ try{ for (int i= 0;i<msg.length;i++){ mOutputStream.write(msg[i]); } mOutputStream.flush(); }catch (IOException e){ e.printStackTrace(); } } privateclass SerialBtThread extends Thread{ @Override publicvoid run() { super.run(); //在线程中初始化蓝牙设备,和sockettry{ BluetoothDevice device=mBluetoothAdapter.getRemoteDevice(devAddr); mBluetoothSocket=device.createRfcommSocketToServiceRecord(SerialBlueToothDev_UUID); }catch (Exception e){ e.printStackTrace(); mFlag=false; } mBluetoothAdapter.cancelDiscovery(); //连接远程设备,建立sockettry{ mBluetoothSocket.connect(); }catch (IOException e){ e.printStackTrace(); try{ mBluetoothSocket.close(); mFlag=false; }catch (IOException e1){ e1.printStackTrace(); } } //如果建立过程没有异常,则得到输入流和输出流if(mFlag){ try { mInputStream=mBluetoothSocket.getInputStream(); mOutputStream=mBluetoothSocket.getOutputStream(); }catch (IOException e){ e.printStackTrace(); } } //开启循环接收蓝牙信息,间隔30mswhile(true){ readSerialBlueTooth(); try { Thread.sleep(30); }catch (Exception e){ e.printStackTrace(); } } } } /** * 在线程中读取蓝牙数据 */privatevoid readSerialBlueTooth() { int ret=0; int data; try { ret=mInputStream.available(); for(int i=0;i<ret;i++){ data = mInputStream.read(); readPackage(data); } }catch (IOException e){ e.printStackTrace(); } } /** * 接收单个的byte数据,不断添加到数组中,不断判断是否数据包已经完成 * 进行拆包,把拆包后的信息发送出去 * @param n */privatevoid readPackage(int n){ dataRec[couts] = n; couts++; if(couts >= 4){ if(dataRec[couts-1] == 0x3c){ if(dataRec[couts-2] == 0xc3){ Log.d("btTest", "readPackage: 收到包"); int[] copyDataRec = newint[couts-3]; //将数据包拆包,并取得包内数据,复制到新的数组中 System.arraycopy(dataRec,1,copyDataRec,0,couts-3); couts = 0; //将包内数据通过蓝牙发送出去 Intent intent = new Intent(BT_RECEIVE_BROADCAST); intent.putExtra(BT_RECEIVE_MESS,copyDataRec); Log.d("btTest", "readPackage: 把数组放入intent"); MyApplication.getLocalBroadcastManager().sendBroadcast(intent); } } } } }
别忘了在程序配置文件中注册活动和服务
< activity android:name =".BtActivity" android:launchMode ="singleInstance" > </ activity > < service android:name ="com.jiaweiqiang.tools.SerialBtService" />
原文:https://www.cnblogs.com/JMatrix/p/8336816.html
内容总结
以上是互联网集市为您收集整理的Android实现和下位机蓝牙通讯全部内容,希望文章能够帮你解决Android实现和下位机蓝牙通讯所遇到的程序开发问题。 如果觉得互联网集市技术教程内容还不错,欢迎将互联网集市网站推荐给程序员好友。
内容备注
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 gblab@vip.qq.com 举报,一经查实,本站将立刻删除。
内容手机端
扫描二维码推送至手机访问。