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


阅读全文
1 0
原创粉丝点击