Android开发之BlueTooth--最简单的Andorid传统蓝牙通讯Demo
来源:互联网 发布:行业分析 知乎 编辑:程序博客网 时间:2024/06/08 10:57
又到了Android小白的开发之路上写笔记的时间了~~
开篇都不知道说什么好... ...前两个月写了WIFI,后来也想写一下蓝牙的,可惜公司产品不给力,出现了很多BUG,一直在修啊修,最近终于有点空闲时间了。那就来简单的尝试一下
关于蓝牙开发,优秀博客一大片,你能来看我这篇辣鸡文章真是不胜感激。基础知识/理论什么的我就不说了,我也是一边看着官方文档来的,想深入了解去看看官方文档也是极好的。
我们知道Andorid的蓝牙分为两种,一种是传统的一种是低功耗蓝牙(BLE),一步一步来,这里先写一下传统蓝牙~
功能实现
主要是实现两台手机能通过蓝牙相互发送消息。两手机可以任意一台充当服务端,一台充当客户端。过程尽量越简单,让大家看的更清楚!
代码-准备工作
1.首先我们需要一个蓝牙适配器,用于搜索设备/连接设备;一个UUID,用于创建服务端;一个广播接收器,用于监听搜索结果。
public static final String BT_UUID = "00001101-0000-1000-8000-00805F9B34FB";//uuid private BluetoothAdapter mBluetoothAdapter;//蓝牙适配器 private BlueToothStateReceiver mReceiver;//广播接收器 private ConnectThread mConnectThread; //客户端线程 private AcceptThread mAcceptThread; //服务端线程
2.然后先打开蓝牙
private void openBT() { if (mBluetoothAdapter == null) { mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter(); } //1.设备不支持蓝牙,结束应用 if (mBluetoothAdapter == null) { finish(); return; } //2.判断蓝牙是否打开 if (!mBluetoothAdapter.enable()) { //没打开请求打开 Intent btEnable = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE); startActivityForResult(btEnable, REQUEST_BT_ENABLE_CODE); } }
3.注册广播接收器
private void registerRec() { //3.注册蓝牙广播 mReceiver = new BlueToothStateReceiver(); IntentFilter filter = new IntentFilter(); filter.addAction(BluetoothDevice.ACTION_FOUND);//搜多到蓝牙 filter.addAction(BluetoothAdapter.ACTION_DISCOVERY_FINISHED);//搜索结束 registerReceiver(mReceiver, filter); }
4.开始搜索设备
if (mBluetoothAdapter != null) { mBluetoothAdapter.startDiscovery();}
5.获取搜索结果
class BlueToothStateReceiver extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { Toast.makeText(MainActivity.this, "触发广播", Toast.LENGTH_SHORT).show(); String action = intent.getAction(); switch (action) { case BluetoothDevice.ACTION_FOUND: BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE); Toast.makeText(MainActivity.this, "找到设备" + device.getName(), Toast.LENGTH_SHORT).show(); if (mRvAdapter != null) { mRvAdapter.addDevice(device); } break; case BluetoothAdapter.ACTION_DISCOVERY_FINISHED: mMessageAdapter.addMessage("搜索结束"); break; } } }
额~~还忘了一步,搜索完到指定设备后要记得关闭搜索
if (mBluetoothAdapter != null && mBluetoothAdapter.isDiscovering()) { mBluetoothAdapter.cancelDiscovery(); }
----------------------------然后基础的就到这里了----------------------------------
接下来,是点击列表,然后连接对应的蓝牙。
开头说了,要实现两台手机任意充当客户端或者服务端,所以在程序中应该包含有服务端也要有客户端,因此我们需要两个线程,分别处理这两种情况。
6.首先服务端线程代码--里面有些没用到或者注释的代码还有一些通知UI更新的代码,大家可以忽略
class AcceptThread extends Thread { private BluetoothServerSocket mServerSocket; private BluetoothSocket mSocket; private InputStream btIs; private OutputStream btOs; private PrintWriter writer; private boolean canAccept; private boolean canRecv; public AcceptThread() { canAccept = true; canRecv = true; } @Override public void run() { try { //获取套接字 BluetoothServerSocket temp = mBluetoothAdapter.listenUsingInsecureRfcommWithServiceRecord("TEST", UUID.fromString(BT_UUID)); mServerSocket = temp; //监听连接请求 -- 作为测试,只允许连接一个设备 if (mServerSocket != null) { // while (canAccept) { mSocket = mServerSocket.accept();//阻塞等待客户端连接 sendHandlerMsg("有客户端连接"); // } } //获取输入输出流 btIs = mSocket.getInputStream(); btOs = mSocket.getOutputStream(); //通讯-接收消息 BufferedReader reader = new BufferedReader(new InputStreamReader(btIs, "UTF-8")); String content = null; while (canRecv) { content = reader.readLine(); sendHandlerMsg("收到消息:" + content); } } catch (IOException e) { e.printStackTrace(); } finally { try { if (mSocket != null) { mSocket.close(); } // btIs.close();//两个输出流都依赖socket,关闭socket即可 // btOs.close(); } catch (IOException e) { e.printStackTrace(); sendHandlerMsg("错误:" + e.getMessage()); } } } private void sendHandlerMsg(String content) { Message msg = mHandler.obtainMessage(); msg.what = 1001; msg.obj = content; mHandler.sendMessage(msg); } public void write(String msg) { if (btOs != null) { try { if (writer == null) { writer = new PrintWriter(new OutputStreamWriter(btOs, "UTF-8"), true); } writer.println(msg); } catch (UnsupportedEncodingException e) { e.printStackTrace(); writer.close(); sendHandlerMsg("错误:" + e.getMessage()); } } } }
7.连接线程代码--用于点击某个设备后建立连接--同样里面有些没用到或者注释的代码用于以后拓展的,还有一些通知UI更新的代码,大家可以忽略
class ConnectThread extends Thread { private BluetoothDevice mDevice; private BluetoothSocket mSocket; private InputStream btIs; private OutputStream btOs; private boolean canRecv; private PrintWriter writer; public ConnectThread(BluetoothDevice device) { mDevice = device;//被点击设备 canRecv = true; } @Override public void run() { if (mDevice != null) { try { //获取套接字 BluetoothSocket temp = mDevice.createInsecureRfcommSocketToServiceRecord(UUID.fromString(BT_UUID)); //mDevice.createRfcommSocketToServiceRecord(UUID.fromString(BT_UUID));//sdk 2.3以下使用 mSocket = temp; //发起连接请求 if (mSocket != null) { mSocket.connect(); } sendHandlerMsg("连接 " + mDevice.getName() + "成功!"); //获取输入输出流 btIs = mSocket.getInputStream(); btOs = mSocket.getOutputStream(); //通讯-接收消息 BufferedReader reader = new BufferedReader(new InputStreamReader(btIs, "UTF-8")); String content = null; while (canRecv) { content = reader.readLine(); sendHandlerMsg("收到消息:" + content); } } catch (IOException e) { e.printStackTrace(); sendHandlerMsg("错误:" + e.getMessage()); } finally { try { if (mSocket != null) { mSocket.close(); } //btIs.close();//两个输出流都依赖socket,关闭socket即可 //btOs.close(); } catch (IOException e) { e.printStackTrace(); sendHandlerMsg("错误:" + e.getMessage()); } } } } private void sendHandlerMsg(String content) { Message msg = mHandler.obtainMessage(); msg.what = 1001; msg.obj = content; mHandler.sendMessage(msg); } public void write(String msg) { if (btOs != null) { try { if (writer == null) { writer = new PrintWriter(new OutputStreamWriter(btOs, "UTF-8"), true); } writer.println(msg); } catch (UnsupportedEncodingException e) { e.printStackTrace(); writer.close(); sendHandlerMsg("错误:" + e.getMessage()); } } } }
8.然后这个两个线程的开启时机我是这么来设置的:服务端是开启蓝牙后立马启动,连接线程是点击了某个设备发起连接请求时启动。
openBT(); mMessageAdapter.addMessage("打开蓝牙"); if (mAcceptThread == null && mBluetoothAdapter != null) { mAcceptThread = new AcceptThread(); mAcceptThread.start(); mMessageAdapter.addMessage("启动服务线程"); }
mRvAdapter.setOnItemClickListener(new RvAdapter.OnItemClickListener() { @Override public void onClick(BluetoothDevice device) { mConnectThread = new ConnectThread(device); mConnectThread.start(); } });
9.连接上别人或者别人连接我们之后就可以进行通讯了。要发送消息,直接调用对应线程的write()方法即可。大致流程就这样。还是挺简单的。接下来给大家看一下全部的代码:
看全部代码前给大家先看运行效果图,我怕大家没耐心看到后面。操作:两个设备都点击打开蓝牙,然后搜索,找出设备点击停止。最后设备1点击结果中的设备2,互发消息。 ps:设备1 Android 4.0 设备2(OnePlus3T) Android 7.1
设备1截图:
设备2截图:
-放全部代码:
首先是我的布局:消息列表显示的是各种消息,什么有客户端连接,收到什么消息,发送什么消息等。截图如下:
<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical"> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="horizontal"> <Button android:id="@+id/open" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="打开" /> <Button android:id="@+id/close" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="关闭" /> <Button android:id="@+id/start" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="搜索" /> <Button android:id="@+id/stop" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="停止" /> </LinearLayout> <TextView android:layout_width="match_parent" android:layout_height="wrap_content" android:text="设备列表" /> <android.support.v7.widget.RecyclerView android:id="@+id/devices" android:layout_width="match_parent" android:layout_height="0dp" android:layout_weight="1" > </android.support.v7.widget.RecyclerView> <TextView android:layout_width="match_parent" android:layout_height="wrap_content" android:text="消息列表" /> <android.support.v7.widget.RecyclerView android:id="@+id/msglist" android:layout_width="match_parent" android:layout_height="0dp" android:layout_weight="1" > </android.support.v7.widget.RecyclerView> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="horizontal" > <EditText android:id="@+id/input" android:layout_width="0dp" android:layout_weight="1" android:layout_height="wrap_content" /> <Button android:id="@+id/send" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="发送" /> </LinearLayout></LinearLayout>
然后是Activity代码,这里代码可能有点多而且乱,大家按照上面的步骤来看就清楚多了。本来大部分都是交给服务来做的,谷歌文档官方就是这么干的。我这里为了直观看到所有代码,就没用服务。大家将就看看
package cn.small_qi.bluetoothtest;import android.Manifest;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.Build;import android.os.Handler;import android.os.Message;import android.support.v7.app.AppCompatActivity;import android.os.Bundle;import android.support.v7.widget.LinearLayoutManager;import android.support.v7.widget.RecyclerView;import android.text.TextUtils;import android.view.View;import android.widget.EditText;import android.widget.Toast;import java.io.BufferedReader;import java.io.IOException;import java.io.InputStream;import java.io.InputStreamReader;import java.io.OutputStream;import java.io.OutputStreamWriter;import java.io.PrintWriter;import java.io.UnsupportedEncodingException;import java.util.UUID;public class MainActivity extends AppCompatActivity implements View.OnClickListener { public static final int REQUEST_BT_ENABLE_CODE = 200; public static final String BT_UUID = "00001101-0000-1000-8000-00805F9B34FB";//uuid private BluetoothAdapter mBluetoothAdapter;//蓝牙适配器 private BlueToothStateReceiver mReceiver;//广播接收器 private ConnectThread mConnectThread; //客户端线程 private AcceptThread mAcceptThread; //服务端线程 private RecyclerView mRecyclerView; private RvAdapter mRvAdapter; private RecyclerView mMessageView; private static MsgAdapter mMessageAdapter; private EditText inputEt; private static Handler mHandler = new Handler() { @Override public void dispatchMessage(Message msg) { mMessageAdapter.addMessage((String) msg.obj); } }; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); //这是我是为了6.0以上的设备能搜索到结果,动态申请了位置权限。但是没有处理结果,因为我测试肯定点同意~- - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { requestPermissions(new String[]{Manifest.permission.ACCESS_COARSE_LOCATION, Manifest.permission.ACCESS_FINE_LOCATION}, 1001); } initUI(); registerRec(); } private void initUI() { findViewById(R.id.open).setOnClickListener(this); findViewById(R.id.close).setOnClickListener(this); findViewById(R.id.start).setOnClickListener(this); findViewById(R.id.stop).setOnClickListener(this); findViewById(R.id.send).setOnClickListener(this); inputEt = (EditText) findViewById(R.id.input); mRecyclerView = (RecyclerView) findViewById(R.id.devices); mRecyclerView.setLayoutManager(new LinearLayoutManager(this)); mRvAdapter = new RvAdapter(this); mRecyclerView.setAdapter(mRvAdapter); mRvAdapter.setOnItemClickListener(new RvAdapter.OnItemClickListener() { @Override public void onClick(BluetoothDevice device) { mConnectThread = new ConnectThread(device); mConnectThread.start(); } }); mMessageView = (RecyclerView) findViewById(R.id.msglist); mMessageView.setLayoutManager(new LinearLayoutManager(this)); mMessageAdapter = new MsgAdapter(this); mMessageView.setAdapter(mMessageAdapter); } private void openBT() { if (mBluetoothAdapter == null) { mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter(); } //1.设备不支持蓝牙,结束应用 if (mBluetoothAdapter == null) { finish(); return; } //2.判断蓝牙是否打开 if (!mBluetoothAdapter.enable()) { //没打开请求打开 Intent btEnable = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE); startActivityForResult(btEnable, REQUEST_BT_ENABLE_CODE); } } private void registerRec() { //3.注册蓝牙广播 mReceiver = new BlueToothStateReceiver(); IntentFilter filter = new IntentFilter(); filter.addAction(BluetoothDevice.ACTION_FOUND);//搜多到蓝牙 filter.addAction(BluetoothAdapter.ACTION_DISCOVERY_FINISHED);//搜索结束 registerReceiver(mReceiver, filter); } @Override protected void onDestroy() { if (mReceiver != null) { unregisterReceiver(mReceiver); } super.onDestroy(); } @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { if (requestCode == REQUEST_BT_ENABLE_CODE) { if (resultCode == RESULT_OK) { //用户允许打开蓝牙 mMessageAdapter.addMessage("用户同意打开蓝牙"); } else if (resultCode == RESULT_CANCELED) { //用户取消打开蓝牙 mMessageAdapter.addMessage("用户拒绝打开蓝牙"); } } super.onActivityResult(requestCode, resultCode, data); } @Override public void onClick(View view) { switch (view.getId()) { case R.id.open: openBT(); mMessageAdapter.addMessage("打开蓝牙"); if (mAcceptThread == null && mBluetoothAdapter != null) { mAcceptThread = new AcceptThread(); mAcceptThread.start(); mMessageAdapter.addMessage("启动服务线程"); } break; case R.id.close: mBluetoothAdapter.disable(); break; case R.id.start: if (mBluetoothAdapter != null) { mRvAdapter.clearDevices();//开始搜索前清空上一次的列表 mBluetoothAdapter.startDiscovery(); mMessageAdapter.addMessage("开始搜索蓝牙"); } else { openBT(); if (mBluetoothAdapter != null) { mRvAdapter.clearDevices();//开始搜索前清空上一次的列表 mBluetoothAdapter.startDiscovery(); mMessageAdapter.addMessage("开始搜索蓝牙"); } } break; case R.id.stop: if (mBluetoothAdapter != null && mBluetoothAdapter.isDiscovering()) { mBluetoothAdapter.cancelDiscovery(); } break; case R.id.send: /** * 如何区分我是使用服务端的socket还是使用客户端的socket发送消息 * 1. 在单一环境下,手机一般作为客户端,外围设备是服务器。所以手机完全可以不用创建服务器,不存在这个问题。 * 2. 假如是两台手机用来聊天,可分别充当服务器和客户端,那就是发起连接方(即点击设备列表连接)作为客户端。 * 3. 假如我链接了别人,另一个人又连接了我,那我怎么区分?那你写两个界面啊~你要回复其他客户端发来的消息就用服务器的socket * 否则就用客户端的。我这里偷懒了,一但我主动连接别人,相当于我就关闭服务端了,不给别人连我了。 * 4. 那那些蓝牙对战游戏都怎么区分的?你发现蓝牙对战需要一个人先创建房间没?那个人就是服务端,其他都是客户端,没这个问题。 */ String msg = inputEt.getText().toString(); if (TextUtils.isEmpty(msg)) { Toast.makeText(this, "消息为空", Toast.LENGTH_SHORT).show(); return; } if (mConnectThread != null) {//证明我主动去链接别人了 mConnectThread.write(msg); } else if (mAcceptThread != null) { mAcceptThread.write(msg); } mMessageAdapter.addMessage("发送消息:" + msg); break; } } class BlueToothStateReceiver extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { Toast.makeText(MainActivity.this, "触发广播", Toast.LENGTH_SHORT).show(); String action = intent.getAction(); switch (action) { case BluetoothDevice.ACTION_FOUND: BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE); Toast.makeText(MainActivity.this, "找到设备" + device.getName(), Toast.LENGTH_SHORT).show(); if (mRvAdapter != null) { mRvAdapter.addDevice(device); } break; case BluetoothAdapter.ACTION_DISCOVERY_FINISHED: mMessageAdapter.addMessage("搜索结束"); break; } } } class ConnectThread extends Thread { private BluetoothDevice mDevice; private BluetoothSocket mSocket; private InputStream btIs; private OutputStream btOs; private boolean canRecv; private PrintWriter writer; public ConnectThread(BluetoothDevice device) { mDevice = device; canRecv = true; } @Override public void run() { if (mDevice != null) { try { //获取套接字 BluetoothSocket temp = mDevice.createInsecureRfcommSocketToServiceRecord(UUID.fromString(BT_UUID)); //mDevice.createRfcommSocketToServiceRecord(UUID.fromString(BT_UUID));//sdk 2.3以下使用 mSocket = temp; //发起连接请求 if (mSocket != null) { mSocket.connect(); } sendHandlerMsg("连接 " + mDevice.getName() + "成功!"); //获取输入输出流 btIs = mSocket.getInputStream(); btOs = mSocket.getOutputStream(); //通讯-接收消息 BufferedReader reader = new BufferedReader(new InputStreamReader(btIs, "UTF-8")); String content = null; while (canRecv) { content = reader.readLine(); sendHandlerMsg("收到消息:" + content); } } catch (IOException e) { e.printStackTrace(); sendHandlerMsg("错误:" + e.getMessage()); } finally { try { if (mSocket != null) { mSocket.close(); } //btIs.close();//两个输出流都依赖socket,关闭socket即可 //btOs.close(); } catch (IOException e) { e.printStackTrace(); sendHandlerMsg("错误:" + e.getMessage()); } } } } private void sendHandlerMsg(String content) { Message msg = mHandler.obtainMessage(); msg.what = 1001; msg.obj = content; mHandler.sendMessage(msg); } public void write(String msg) { if (btOs != null) { try { if (writer == null) { writer = new PrintWriter(new OutputStreamWriter(btOs, "UTF-8"), true); } writer.println(msg); } catch (UnsupportedEncodingException e) { e.printStackTrace(); writer.close(); sendHandlerMsg("错误:" + e.getMessage()); } } } } class AcceptThread extends Thread { private BluetoothServerSocket mServerSocket; private BluetoothSocket mSocket; private InputStream btIs; private OutputStream btOs; private PrintWriter writer; private boolean canAccept; private boolean canRecv; public AcceptThread() { canAccept = true; canRecv = true; } @Override public void run() { try { //获取套接字 BluetoothServerSocket temp = mBluetoothAdapter.listenUsingInsecureRfcommWithServiceRecord("TEST", UUID.fromString(BT_UUID)); mServerSocket = temp; //监听连接请求 -- 作为测试,只允许连接一个设备 if (mServerSocket != null) { // while (canAccept) { mSocket = mServerSocket.accept(); sendHandlerMsg("有客户端连接"); // } } //获取输入输出流 btIs = mSocket.getInputStream(); btOs = mSocket.getOutputStream(); //通讯-接收消息 BufferedReader reader = new BufferedReader(new InputStreamReader(btIs, "UTF-8")); String content = null; while (canRecv) { content = reader.readLine(); sendHandlerMsg("收到消息:" + content); } } catch (IOException e) { e.printStackTrace(); } finally { try { if (mSocket != null) { mSocket.close(); } // btIs.close();//两个输出流都依赖socket,关闭socket即可 // btOs.close(); } catch (IOException e) { e.printStackTrace(); sendHandlerMsg("错误:" + e.getMessage()); } } } private void sendHandlerMsg(String content) { Message msg = mHandler.obtainMessage(); msg.what = 1001; msg.obj = content; mHandler.sendMessage(msg); } public void write(String msg) { if (btOs != null) { try { if (writer == null) { writer = new PrintWriter(new OutputStreamWriter(btOs, "UTF-8"), true); } writer.println(msg); } catch (UnsupportedEncodingException e) { e.printStackTrace(); writer.close(); sendHandlerMsg("错误:" + e.getMessage()); } } } }}
然后是两个RecycleView的适配器
消息列表:
package cn.small_qi.bluetoothtest;import android.bluetooth.BluetoothDevice;import android.content.Context;import android.support.v7.widget.RecyclerView;import android.view.LayoutInflater;import android.view.View;import android.view.ViewGroup;import android.widget.TextView;import java.util.ArrayList;import java.util.List;/** * Created by small_qi on 2017/9/13. */public class MsgAdapter extends RecyclerView.Adapter<MsgAdapter.MsgHolder>{ private Context mContext; private List<String> msgList; public MsgAdapter(Context mContext) { this.mContext = mContext; msgList = new ArrayList<>(); } @Override public MsgAdapter.MsgHolder onCreateViewHolder(ViewGroup parent, int viewType) { return new MsgAdapter.MsgHolder(LayoutInflater.from(mContext).inflate(R.layout.item,parent,false)); } @Override public void onBindViewHolder(MsgAdapter.MsgHolder holder, final int position) { holder.nameTv.setText(msgList.get(position)); } @Override public int getItemCount() { return msgList.size(); } public void addMessage(String msg) { msgList.add(msg); notifyItemInserted(msgList.size()-1); } public void clearMsgList(){ msgList.clear(); notifyDataSetChanged(); } public interface OnItemClickListener{ void onClick(BluetoothDevice device); } class MsgHolder extends RecyclerView.ViewHolder{ private TextView nameTv; public MsgHolder(View itemView) { super(itemView); nameTv = itemView.findViewById(R.id.name); } }}
设备列表(有个点击回调):
package cn.small_qi.bluetoothtest;import android.bluetooth.BluetoothDevice;import android.content.Context;import android.support.v7.widget.RecyclerView;import android.view.LayoutInflater;import android.view.View;import android.view.ViewGroup;import android.widget.Button;import android.widget.TextView;import java.util.ArrayList;import java.util.List;/** * Created by small_qi on 2017/9/13. */public class RvAdapter extends RecyclerView.Adapter<RvAdapter.RvHolder>{ private Context mContext; private List<BluetoothDevice> mDevices; private OnItemClickListener onItemClickListener; public void setOnItemClickListener(OnItemClickListener onItemClickListener) { this.onItemClickListener = onItemClickListener; } public RvAdapter(Context mContext) { this.mContext = mContext; mDevices = new ArrayList<>(); } @Override public RvHolder onCreateViewHolder(ViewGroup parent, int viewType) { return new RvHolder(LayoutInflater.from(mContext).inflate(R.layout.item,parent,false)); } @Override public void onBindViewHolder(RvHolder holder, final int position) { holder.nameTv.setText(mDevices.get(position).getName()+":"+mDevices.get(position).getAddress()); //点击事件 点击配对 if (onItemClickListener!=null) { holder.itemView.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { onItemClickListener.onClick(mDevices.get(position)); } }); } } @Override public int getItemCount() { return mDevices.size(); } public void addDevice(BluetoothDevice device) { mDevices.add(device); notifyItemInserted(mDevices.size()-1); } public void clearDevices(){ mDevices.clear(); notifyDataSetChanged(); } public interface OnItemClickListener{ void onClick(BluetoothDevice device); } class RvHolder extends RecyclerView.ViewHolder{ private TextView nameTv; public RvHolder(View itemView) { super(itemView); nameTv = itemView.findViewById(R.id.name); } }}
列表Item的布局,两个用的同一个布局
<?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="wrap_content" android:padding="8dp" > <TextView android:id="@+id/name" android:layout_width="match_parent" android:layout_height="wrap_content" /></LinearLayout>
全部代码就这些了。主要展示的是蓝牙的基本使用流程,要达到标准的使用,还需要做大量优化和修改~这就要根据业务需求来了。就像我这里,用手机实时获取同步并记录万用表的测量数据,如果不用BLE,其实就是万用表充当服务端,我一旦连接,就给我发送约定好的数据格式,我在客户端进行解析就可以了。这样的功能这个例子就可以完全模拟出来了~~
非常感谢您能看到最后~这Demo实现了,两个设备相互聊天。其实获取到socekt后,就不关蓝牙什么事了,主要是考察对socket通讯的使用了。例子中只实现了1V1聊天,至于一对多还有文件传输,可以看看我之前的Socket通讯的博客哦~博客中的WIFI通讯相关中也有类似的功能,大家有兴趣可以看看,虽然不是什么深度优秀文章。
demo就是demo各种处理都不完善,而且我只是个小白白,有问题在所难免,大家见谅。有问题评论中指出~谢谢 have a nice day
- Android开发之BlueTooth--最简单的Andorid传统蓝牙通讯Demo
- Android开发之蓝牙(Bluetooth)
- android Bluetooth蓝牙开发
- android 蓝牙bluetooth的简单使用
- android 传统蓝牙Bluetooth联通性
- android 传统蓝牙开发
- Android开发之蓝牙(Bluetooth)操作(一)--扫描已经配对的蓝牙设备
- Android开发之蓝牙(Bluetooth)操作(一)--扫描已经配对的蓝牙设备(转)
- Android开发之蓝牙(Bluetooth)操作(一)--扫描已经配对的蓝牙设备
- iOS蓝牙开发 Bluetooth蓝牙CoreBluetooth 蓝牙中心设备的实现 蓝牙外设的实现 有Demo
- iOS蓝牙开发 Bluetooth蓝牙CoreBluetooth 蓝牙中心设备的实现 蓝牙外设的实现 有Demo
- Android Bluetooth蓝牙开发:Bluetooth蓝牙设备之间的连接建立(3)
- Android开发之蓝牙(Bluetooth)---源码目录
- Android开发之Bluetooth API 基本使用-蓝牙小程序
- Android开发之蓝牙(Bluetooth)---源码目录
- 超简单的 BlueTooth 蓝牙开发实例,打开蓝牙,关闭蓝牙,配对,解除,功能齐全
- Android Bluetooth蓝牙开发:发现Bluetooth蓝牙设备(1)
- 两个Android端基于蓝牙通讯的demo
- 【模板】最短路径(Dijkstra 4heap)
- linux 定时器的使用
- Java中Filter、Listener,拦截器的学习,listener、 filter、servlet 加载顺序及其详解
- 关于Drupal的数据表查看
- idea新建文件报错的临时解决方法
- Android开发之BlueTooth--最简单的Andorid传统蓝牙通讯Demo
- Python中函数的参数定义和可变参数
- 关于内存加载DLL后修复重定位的问题
- ODOO更多中添加按钮
- 解压.tar.gz出错gzip: stdin: not in gzip format tar: /Child returned status 1 tar: Error is not recoverab
- 第三十四讲项目1-分数的累加
- 莫名被封杀
- ButterKnife Fragment null
- spring boot 整合redis 将代码记录以备以后使用