android 蓝牙模块的串口通信
16lz
2021-01-26
一直先想做一个遥控车,正好放假了,所以这些日子有时间,然后就搜集资料,找到一个博客,忘记是哪个了博主写的了,然后就试这写一下,
做完后一运行就是就Bug ,就是当终端蓝牙开启的时候,打开这个软件时,Android 顿时弹出来个大的ANR ,然后我改了改,没这种毛病了,然后又添了一些,比如当在蓝牙关闭的状态上打开软件,软件自动会打开蓝牙。
挺好玩的的。
一共分两个Activityu第一个是搜索蓝牙进行配对操作,第二个就是发送cdm了。
我用的是Android Studio写的所以不必担心添加权限的问题,如果你是用Eclipse写的那么一定不要忘了添加这两条权限:
android:name="android.permission.BLUETOOTH"/>android:name="android.permission.BLUETOOTH_ADMIN"/>
在打开、关闭搜索,配对中主要是用到了两个类:BlueToothAdapter,和 BlueToothSocket这两个类。
里面有一个UUID也不知道是什么东西查API解释是UUID是128位的不可变表示全局惟一标识符(UUID)。什么魔鬼??望指教。
看代码吧。
一、Mainactivity.xml文件往下看的
<?xml version="1.0" encoding="utf-8"?>
二、MainActivity.java
package com.example.hejingzhou.newbuledemo;import android.bluetooth.BluetoothAdapter;import android.bluetooth.BluetoothDevice;import android.bluetooth.BluetoothServerSocket;import android.bluetooth.BluetoothSocket;import android.content.BroadcastReceiver;import android.content.Context;import android.content.Intent;import android.content.IntentFilter;import android.os.*;import android.os.Process;import android.support.v7.app.AppCompatActivity;import android.util.Log;import android.view.View;import android.widget.AdapterView;import android.widget.ArrayAdapter;import android.widget.Button;import android.widget.CompoundButton;import android.widget.ListView;import android.widget.Switch;import android.widget.Toast;import java.io.IOException;import java.lang.reflect.InvocationTargetException;import java.lang.reflect.Method;import java.util.ArrayList;import java.util.List;import java.util.UUID;public class MainActivity extends AppCompatActivity { private Switch aSwitch; private Button buttonVisible,buttonSearch,buttonExit; private ListView listView; private Handler handler; private BluetoothAdapter bluetoothAdapter; static final String SPP_UUID = "00001101-0000-1000-8000-00805F9B34FB"; private UUID uuid; private List listDevice = new ArrayList<>(); private ArrayAdapter adapterDevice; private static BluetoothSocket socket; public static BluetoothSocket bluetoothSocket; private static AcceptThread acceptThread; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); findViewById(); OnClick(); bluetoothAdapter = BluetoothAdapter.getDefaultAdapter(); uuid = UUID.fromString("00001101-0000-1000-8000-00805F9B34FB"); InitBlueTooth(); } /************************************************************************************************************/ private void OnClick() { //Switch开关 aSwitch.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { @Override public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { if (isChecked == true) { if (bluetoothAdapter.getState() == BluetoothAdapter.STATE_ON) { return; } else if (bluetoothAdapter.getState() == BluetoothAdapter.STATE_OFF) { bluetoothAdapter.enable(); try { Thread.sleep(3000); } catch (InterruptedException e) { e.printStackTrace(); } if (bluetoothAdapter.getState() == BluetoothAdapter.STATE_ON) { Toast.makeText(MainActivity.this, "蓝牙已打开", Toast.LENGTH_SHORT).show(); } /***********修改修改**********/ try { acceptThread = new AcceptThread(); handler = new Handler() { public void handle(Message message) { switch (message.what) { case 0: acceptThread.start(); } } }; } catch (Exception e) { Toast.makeText(MainActivity.this, "服务监听出错", Toast.LENGTH_SHORT).show(); } } } else if (isChecked = false) { bluetoothAdapter.disable(); if (bluetoothAdapter.getState() == BluetoothAdapter.STATE_OFF) Toast.makeText(MainActivity.this, "蓝牙已关闭", Toast.LENGTH_SHORT).show(); } } }); //可见性Button buttonVisible.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { Intent discoverableIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE); discoverableIntent.putExtra(BluetoothAdapter.EXTRA_DISCOVERABLE_DURATION, 300); startActivity(discoverableIntent); } }); //搜索设备 buttonSearch.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { setTitle("本机蓝牙地址" + bluetoothAdapter.getAddress()); listDevice.clear(); bluetoothAdapter.startDiscovery();//启动搜索其他蓝牙设备 } }); //退出Button buttonExit.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { if(bluetoothSocket != null) { try { bluetoothSocket.close(); } catch (IOException e) { e.printStackTrace(); } MainActivity.this.finish(); } } }); } /************************************************************************************************************/ private void InitBlueTooth() { Toast.makeText(MainActivity.this,"正在初始化软件,请稍等...",Toast.LENGTH_SHORT).show(); /*if(bluetoothAdapter == null) { Toast.makeText(MainActivity.this,"您的蓝牙不可用,请查验您的手机是否具有此功能",Toast.LENGTH_LONG).show(); return; } else {*/ if(bluetoothAdapter.getState() == BluetoothAdapter.STATE_OFF) { aSwitch.setChecked(false); bluetoothAdapter.enable(); if(bluetoothAdapter.getState() == BluetoothAdapter.STATE_ON) { Toast.makeText(MainActivity.this,"成功帮您打开蓝牙",Toast.LENGTH_LONG).show(); }else { Toast.makeText(MainActivity.this,"打开蓝牙失败,请手动打开您的蓝牙",Toast.LENGTH_LONG).show(); } }else if(bluetoothAdapter.getState() == bluetoothAdapter.STATE_ON) { acceptThread = new AcceptThread(); handler = new Handler() { public void handleMessage(Message msg) { switch (msg.what) { case 0: acceptThread.start(); break; } } }; } //注册Receiver蓝牙设备的相关结果 //IntentFilter结构化的描述意图值匹配。IntentFilter可以匹配操作、类别和数据(通过其类型、计划和/或路径)的意图。它还包括一个“优先级”值用于订单多个匹配过滤器。 IntentFilter intentFilter = new IntentFilter(); intentFilter.addAction(BluetoothDevice.ACTION_FOUND); intentFilter.addAction(BluetoothDevice.ACTION_BOND_STATE_CHANGED);//广播操作:指示远程设备上的键状态的改变 intentFilter.addAction(BluetoothAdapter.ACTION_SCAN_MODE_CHANGED);//广播操作:指示本地适配器的蓝牙扫描模式已经改变。 intentFilter.addAction(BluetoothAdapter.ACTION_STATE_CHANGED);//广播操作:当地蓝牙适配器的状态已更改。 registerReceiver(serachDevices,intentFilter); // } } /**************************************************************************************************************/ private void findViewById() { aSwitch = (Switch)findViewById(R.id.switchOpenAndClose); buttonVisible = (Button)findViewById(R.id.buttonVisible); buttonSearch = (Button)findViewById(R.id.buttonSeraveDevice); buttonExit = (Button)findViewById(R.id.buttonExit); listView = (ListView)findViewById(R.id.listViewShow); adapterDevice = new ArrayAdapter(MainActivity.this,android.R.layout.simple_list_item_1,listDevice); listView.setAdapter(adapterDevice); listView.setOnItemClickListener(new ItemClickEvent());//设置ListView 的单击监听 } /*************************************************************************************************************/ class AcceptThread extends Thread { private final BluetoothServerSocket serverSocket;//蓝牙服务套接口 public AcceptThread() { BluetoothServerSocket BTServerSocket = null; try { Method listenMethod = bluetoothAdapter.getClass().getMethod("listenUsingRfcommOn",new Class[]{int.class}); BTServerSocket = (BluetoothServerSocket)listenMethod.invoke(bluetoothAdapter,Integer.valueOf(1)); } catch (NoSuchMethodException e) { e.printStackTrace(); } catch (InvocationTargetException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } serverSocket = BTServerSocket; } public void run() { while (true) { try { socket = serverSocket.accept(); Log.e("MainActivity","socket = serverSocket.accept();错误"); } catch (IOException e) { break; } if(socket != null) { manageConnectedSocket(); try { serverSocket.close(); } catch (IOException e) { e.printStackTrace(); } break; } } Message message = new Message(); message.what = 0; handler.sendMessage(message); } public void cancel() { try { serverSocket.close(); } catch (IOException e) { Log.e("MainActivity","注销错误"); } } } /*************************************************************************************************************/ class ItemClickEvent implements AdapterView.OnItemClickListener { @Override public void onItemClick(AdapterView<?> parent, View view, int position, long id) { String str = listDevice.get(position); String[] values = str.split("\\|"); String address = values[1]; Log.i("address",values[1]); uuid = UUID.fromString(SPP_UUID); Log.i("uuid",uuid.toString()); BluetoothDevice BtDev = bluetoothAdapter.getRemoteDevice(address);//getRemoteDevice获取BluetoothDevice对象从给定的蓝牙硬件地址 Log.i("获取的蓝牙硬件对象"," "+BtDev); Method method; try { method = BtDev.getClass().getMethod("createRfcommSocket",new Class[]{int.class}); bluetoothSocket = (BluetoothSocket) method.invoke(BtDev,Integer.valueOf(1)); } catch (NoSuchMethodException e) { e.printStackTrace(); } catch (InvocationTargetException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } bluetoothAdapter.cancelDiscovery();//对蓝牙进行信号注销 try { bluetoothSocket.connect();//蓝牙配对 Toast.makeText(MainActivity.this,"连接成功进入控制界面",Toast.LENGTH_SHORT).show(); Intent intent = new Intent(); intent.setClass(MainActivity.this, SendMessageActivity.class); startActivity(intent); } catch (IOException e) { e.printStackTrace(); Toast.makeText(MainActivity.this,"连接失败",Toast.LENGTH_SHORT).show(); } } } /*************************************************************************************************************/ /** * 基类代码,将收到发送的意图sendBroadcast()。 */ private BroadcastReceiver serachDevices = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { String action = intent.getAction(); Bundle bundle = intent.getExtras(); Object[] listName = bundle.keySet().toArray(); //显示收到的消息及细节 for(int i = 0;i < listName.length;i++) { String keyName = listName[i].toString(); Log.i(keyName,String.valueOf(bundle.get(keyName))); } if(BluetoothDevice.ACTION_FOUND.equals(action)) { BluetoothDevice BTDevice = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE); String str = BTDevice.getName()+"|"+BTDevice.getAddress(); if(listDevice.indexOf(str) == -1)//indexOf检索字符串,如果为null返回-1 { listDevice.add(str); } adapterDevice.notifyDataSetChanged();//每次改变刷新一下自己 } } }; /*************************************************************************************************************/ @Override protected void onDestroy() { this.unregisterReceiver(serachDevices); super.onDestroy(); android.os.Process.killProcess(Process.myPid());//杀死Pid acceptThread.cancel(); acceptThread.destroy(); } /*************************************************************************************************************/ private void manageConnectedSocket() { bluetoothSocket = socket; Intent newActivity = new Intent(); newActivity.setClass(MainActivity.this,SendMessageActivity.class); startActivity(newActivity); }}
三、sendMessageActivity.xml
<?xml version="1.0" encoding="utf-8"?>
四、sendMessageActivity.Java
package com.example.hejingzhou.newbuledemo;import android.os.Message;import android.support.v7.app.AppCompatActivity;import android.os.Bundle;import android.util.Log;import android.view.View;import android.widget.Button;import android.widget.CompoundButton;import android.widget.EditText;import android.widget.RadioButton;import android.widget.RadioGroup;import android.widget.TextView;import android.widget.Toast;import android.widget.ToggleButton;import java.io.IOException;import java.io.InputStream;import java.io.OutputStream;import java.io.UnsupportedEncodingException;import java.util.logging.Handler;public class SendMessageActivity extends AppCompatActivity implements RadioGroup.OnCheckedChangeListener { private RadioGroup radioGroup; private RadioButton radioPc, radioMo; private ToggleButton TB1, TB2, TB3, TB4; private EditText EtReceive, EtSend; private Button BtSend, BtBack, BtClose; private android.os.Handler handler; private String encodeType = "GBK"; private boolean isRecording = false; private OutputStream outputStream = null; private ConnectedThread connectedThread; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_send_message); findViewById(); StartThread(); onClickListener(); } private void onClickListener() { BtClose.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { try { MainActivity.bluetoothSocket.close();//关闭蓝牙接口 connectedThread.Stop(); setTitle("蓝牙连接断开"); } catch (IOException e) { e.printStackTrace(); } } }); BtBack.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { SendMessageActivity.this.finish(); } }); TB1.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { if (TB1.isChecked() == false) { sendMessage("11"); } else if (TB1.isChecked() == true) { sendMessage("10"); } } }); TB2.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { if (TB2.isChecked() == false) { sendMessage("21"); } else if (TB2.isChecked() == true) { sendMessage("20"); } } }); TB3.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { if (TB3.isChecked() == false) { sendMessage("31"); } else if (TB3.isChecked() == true) { sendMessage("30"); } } }); TB4.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { if (TB4.isChecked() == false) { sendMessage("41"); } else if (TB4.isChecked() == true) { sendMessage("40"); } } }); BtSend.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { String infoSend = EtSend.getText().toString(); sendMessage(infoSend); setTitle("发送成功"); } }); } public void sendMessage(String str) { try { outputStream = MainActivity.bluetoothSocket.getOutputStream(); } catch (IOException e) { Toast.makeText(getApplicationContext(), "输出流失败", Toast.LENGTH_SHORT); } byte[] msgBuffer = null; try { msgBuffer = str.getBytes(encodeType); } catch (UnsupportedEncodingException e) { e.printStackTrace(); Log.e("decode 错误","编码异常",e); } try { outputStream.write(msgBuffer); setTitle("成功发送命令"); Log.i("成功发送命令"," "+str); } catch (IOException e) { Toast.makeText(getApplicationContext(),"发送命令失败",Toast.LENGTH_SHORT); } } /*public static void setEditTextEnable(TextView view,Boolean able){ // view.setTextColor(R.color.read_only_color); //设置只读时的文字颜色 if (view instanceof android.widget.EditText){ view.setCursorVisible(able); //设置输入框中的光标不可见 view.setFocusable(able); //无焦点 view.setFocusableInTouchMode(able); //触摸时也得不到焦点 } }*/ @Override protected void onDestroy() { try { MainActivity.bluetoothSocket.close(); } catch (IOException e) { e.printStackTrace(); } super.onDestroy(); } private void StartThread() { connectedThread = new ConnectedThread(); handler = new MyHandler(); connectedThread.Start(); } private void findViewById() { radioGroup = (RadioGroup) findViewById(R.id.radioGroup); radioPc = (RadioButton) findViewById(R.id.radioPC); radioMo = (RadioButton) findViewById(R.id.radioMobile); TB1 = (ToggleButton) findViewById(R.id.toggleButton); TB2 = (ToggleButton) findViewById(R.id.toggleButton2); TB3 = (ToggleButton) findViewById(R.id.toggleButton3); TB4 = (ToggleButton) findViewById(R.id.toggleButton4); EtReceive = (EditText)findViewById(R.id.editTextreceive); EtSend = (EditText)findViewById(R.id.editTextsend); BtSend = (Button)findViewById(R.id.buttonsend); BtBack = (Button)findViewById(R.id.buttonback); BtClose = (Button)findViewById(R.id.buttonclose); } //单选按钮 @Override public void onCheckedChanged(RadioGroup group, int checkedId) { switch (checkedId) { case R.id.radioPC: encodeType = "GBK"; break; case R.id.radioMobile: encodeType = "UTF-1"; break; default: break; } } /** * 连接线程 */ class ConnectedThread extends Thread { private InputStream inputStream = null; private long wait; private Thread thread; public ConnectedThread() { isRecording = false; this.wait = 50; thread = new Thread(new ReadRunnable()); } public void Stop() { isRecording = false; } public void Start() { isRecording = true; State state = thread.getState(); if(state == State.NEW) { thread.start(); }else thread.resume(); } private class ReadRunnable implements Runnable { @Override public void run() { while(isRecording) { try { inputStream = MainActivity.bluetoothSocket.getInputStream(); } catch (IOException e) { Toast.makeText(getApplicationContext(),"创建input流失败",Toast.LENGTH_SHORT).show(); } int length =20; byte[] temp = new byte[length];//创建一个byte数组进行获取 if(inputStream != null) { try { int len = inputStream.read(temp,0,length-1); if(len > 0) { byte[] bluetoothbuff = new byte[len]; System.arraycopy(temp,0,bluetoothbuff,0,bluetoothbuff.length); String readStr = new String(bluetoothbuff,encodeType); handler.obtainMessage(01,len,-1,readStr).sendToTarget(); } Thread.sleep(wait); } catch (IOException e) { e.printStackTrace(); } catch (InterruptedException e) { handler.sendEmptyMessage(00); } } } } } } private class MyHandler extends android.os.Handler { @Override public void dispatchMessage(Message msg) { switch (msg.what) { case 00: isRecording = false; EtReceive.setText(""); EtSend.setHint("soclet连接已关闭"); break; case 01: String info = (String)msg.obj; EtReceive.append(info); break; default: break; } } }}
效果:
可以通过串口助手进行查看信息。
源代码:http://download.csdn.net/detail/csdnhejingzhou/9413145
更多相关文章
- Android(安卓)各种菜单,弹出菜单,打开文件子菜单,文本框的复制粘贴
- 编程回忆之Android回忆(蓝牙BluetoothAdapter的搜索和连接)
- android 蓝牙小总结
- Android(安卓)BLE与终端通信(二)——Android(安卓)Bluetooth基础科
- 【iOS-cocos2d-X 游戏开发之十六】配置你的Cocos2dx项目编译后的
- 移动端对html input标签文件选择支持
- Android(安卓)BLE蓝牙4.2数据透传操作
- Android(安卓)6.0以上权限拒绝打开权限设置界面的解决方法
- Android(安卓)智能机顶盒之蓝牙遥控器开机自动配对