蓝牙技术——数据传输

蓝牙编程常用到的几个类

\接口

功能描述

BluetoothAdapter 1

本地的蓝牙适配器设备

BluetoothDevice  2

代表一个远程的蓝牙设备

BluetoothServerSocket  3

监听蓝牙服务的端口

BluetoothSocket  4

一个双向连接的蓝牙端口socket

BluetoothClass   5

描述了设备通用特性和功能的蓝牙类

BluetoothClass.Device

定义了所有设备类的常量

BluetoothClass.Device.Major

定义了所有主要设备类的常量

BluetoothClass.Service

定义了所有服务类的常量


各个类的文档网络上有不少,可以自己去360 的好搜上去搜索,在此不对其进行进一步的说明

UUID的说明

UUID(全局唯一标识符,Universally Unique Identifier)格式如下:

XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX

UUID的格式被分成5段,其中中间3段的字符数都是4,第一段是8个字符,最后一段是12个字符,所有UUID实际上是一个8-4-4-4-12的字符串。

UUID相当于Socket的端口而蓝牙的地址相当于SocketIP

实现如何在2个蓝牙之间传递信息




创建一个新工程LearnBluetoothSocket实现功能:
n        本程既是蓝牙通信的客户端,也是蓝牙通信的服务端。
n        在两部手机上运行本程序,一部当做服务器,另外一部当作客户端
一个的Activity,上面放几个控件。
控件
属性
功能描述
EditText
layout_width="match_parent"    layout_height="wrap_content"    id="@+id/etSendInfo"    hint="请输入要发送到服务器的信息.然后点击要发送到的蓝牙设备"
在此输入要发送的消息
ListView
id="@+id/lvDevices"
 
用于存放扫描到的蓝牙设备信息(名称和地址),点击时会连接选定的蓝牙,并发送消息。
Button
android:text="搜索蓝牙设备"    android:id="@+id/btnSearchBlueTooth"
android:onClick="onClick_Search"
 
 
用于刷新搜索周围蓝牙设备(蓝牙的配对请在手机上手动匹配/绑定)
 

 

在AndroidManifest.xml 文件中添加蓝牙的2个权限
<uses-permission android:name="android.permission.BLUETOOTH"/>
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN"/>

 

MainActivity.java代码

public class MainActivity extends AppCompatActivity implements AdapterView.OnItemClickListener {
    ListView lvDevices//用于显示蓝牙设备的空间
    EditText etSendInfo//要发送的消息在此输入
    BluetoothAdapter bluetoothAdapter//蓝牙适配器
    private List<String> bluetoothDevices = new ArrayList<String>(); //String数组 用于存储所有搜索到的蓝牙名称和地址
    private ArrayAdapter<String> arrayAdapter//数组适配器用于显示列表
  
    private final UUID MY_UUID = UUID.fromString("1234abcd-12ab-7f25-aafe-59d03c27bae3");
    private final String NAME = "Bluetooth_Socket"//蓝牙服务端的名字,可以自己随便定义一个
  
    private BluetoothSocket clientSocket//客户端的BluetoothSocket
    private BluetoothDevice device// 远程的蓝牙设备
    private OutputStream os//输出流(用于客户端向服务端输出)
  
    private AcceptThread acceptThread;   //服务端线程类对象
  
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
  //        requestWindowFeature(Window.FEATURE_INDETERMINATE_PROGRESS);
        setContentView(R.layout.activity_main);
        init();
    }
  
    private void init() {
  
        bluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
  
        lvDevices = (ListView) findViewById(R.id.lvDevices);
        etSendInfo= (EditText) findViewById(R.id.etSendInfo);
  
  
        //已经配对的蓝牙设备显示出来(根据方法名称就可以知道,其实也叫做绑定好的蓝牙设备)
        Set<BluetoothDevice> pairedDevices = bluetoothAdapter.getBondedDevices();
  
        if (pairedDevices.size() > 0) {
            //把扫描到的蓝牙设备添加到 bluetoothDevices(String数组),后面可以用其绑定到Listview视图上
            for (BluetoothDevice device : pairedDevices) {
                bluetoothDevices.add(device.getName() + ":"
                        + device.getAddress() + "\n");
  
            }
        }
  
        //arrayAdapter将所有 arrayList内的数据显示在指定的视图上(使用的是系统内部的View资源)
        arrayAdapter = new ArrayAdapter<String>(this,
                android.R.layout.simple_list_item_1, android.R.id.text1,
                bluetoothDevices);
        lvDevices.setAdapter(arrayAdapter);
  
        lvDevices.setOnItemClickListener(this);  //实现客户端代码,响应客户的单击事件
  
        IntentFilter filter = new IntentFilter(BluetoothDevice.ACTION_FOUND);
        this.registerReceiver(receiver, filter);
  
        filter = new IntentFilter(BluetoothAdapter.ACTION_DISCOVERY_FINISHED);
        this.registerReceiver(receiver, filter);
        acceptThread = new AcceptThread();    //创建一个线程用于接收客户端发来的信息
        acceptThread.start();  //启动服务
  
    }
  
    //实现客户端代码,响应客户的单击事件
    @Override
    public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
        //获取选择的蓝牙设备名(中间用“:”分开的)
        String s = arrayAdapter.getItem(position);
        //由于设备名用“:”分开的,所有要解析出蓝牙地址address
        String address = s.substring(s.indexOf(":") + 1).trim();
  
        try {
            //如果蓝牙适配器还在扫描,则停止扫描  需要BLUETOOTH_ADMIN权限
            if (bluetoothAdapter.isDiscovering()) {
                bluetoothAdapter.cancelDiscovery();
            }
            try {
                if (device == null) {
                    //参数是地址,类似PC中的IP
                    device = bluetoothAdapter.getRemoteDevice(address);
  
                }
                if (clientSocket == null) {
                    clientSocket = device
                            .createRfcommSocketToServiceRecord(MY_UUID);  //相当于Socket的端口
                    //目前还没有配对,直接连接。(正常需要配对,我们把蓝牙配对的工作交给系统手工完成****)
                    clientSocket.connect();
  
                    os = clientSocket.getOutputStream();  //获得输出流(由于客户端只向服务点输出文本,所有只要输出流即可)
  
                }
            } catch (Exception e) {
                // TODO: handle exception
            }
            //如果获得服务端的输出流,那么就向服务端写文本信息
            if (os != null) {
  
                String strInfo=etSendInfo.getText().toString();
  
                if (strInfo.length()<=0){
                    os.write("发送默认信息---》其他蓝牙设备".getBytes("utf-8"));
                }else {
                    byte[] midbytes=strInfo.getBytes("utf-8");  //string转换为Byte
                    os.write(midbytes);
                    //return ByteBuffer.wrap(str.getBytes());
                }
  
  
            }
        } catch (Exception e) {
            // TODO: handle exception
        }
  
    }
  
    //服务端线程收到客户端发来的消息会通过本handle进行处理消息。为了监听客户端发来的信息,我们需要创建一个线程
    private Handler handler = new Handler(){
        public void handleMessage(Message msg) {
            Toast.makeText(MainActivity.this, "收到其他蓝牙设备发来的消息:"+String.valueOf(msg.obj),
                    Toast.LENGTH_LONG).show();
            super.handleMessage(msg);
        }
  
    };
  
    //定义线程服务类
    private class AcceptThread extends Thread {
        private BluetoothServerSocket serverSocket;
        private BluetoothSocket socket;
        private InputStream is//输入流
        private OutputStream os;
  
        public AcceptThread() {
            try {
                serverSocket = bluetoothAdapter
                        .listenUsingRfcommWithServiceRecord(NAME, MY_UUID);
            } catch (Exception e) {
                // TODO: handle exception
            }
        }
  
        //服务线程run中 截取客户端蓝牙发来的消息
        public void run() {
            try
            {
  
                socket = serverSocket.accept();  //如果客户端没有发来请求,程序会一直停留再次等待客户端发来的请求消息,收到客户端请求后才会继续后续代码
                is = socket.getInputStream();
                os = socket.getOutputStream();
  
                while(true)
                {
                    byte[] buffer =new byte[128];  //每次只发128个字节
                    int count = is.read(buffer);   //从蓝牙读取数据,客户端没有发生数据过来,则会堵塞在此
  
                    //让Hander处理消息
                    Message msg = new Message();
                    msg.obj = new String(buffer, 0, count, "utf-8");
                    handler.sendMessage(msg);
                }
            }
            catch (Exception e) {
                // TODO: handle exception
            }
  
        }
    }
    public void onClick_Search(View view) {
        setProgressBarIndeterminateVisibility(true);
        setTitle("正在扫描...");
  
        if (bluetoothAdapter.isDiscovering()) {
            bluetoothAdapter.cancelDiscovery();
        }
        bluetoothAdapter.startDiscovery();
    }
  
  
    //广播接受器,用于搜索系统发来的蓝牙设备扫描信息情况
    //定义广播接受器 处理BluetoothDevice的ACTION_FOUND(发现蓝牙设备)、ACTION_DISCOVERY_FINISHED(搜索结束)消息
    private final BroadcastReceiver receiver = new 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);
                //判断设备是否已经被绑定
                if (device.getBondState() != BluetoothDevice.BOND_BONDED) {
                    bluetoothDevices.add(device.getName() + ":"
                            + device.getAddress() + "\n");
                    arrayAdapter.notifyDataSetChanged();
                }
  
            } else if (BluetoothAdapter.ACTION_DISCOVERY_FINISHED
                    .equals(action)) {
                setProgressBarIndeterminateVisibility(false);
                setTitle("连接蓝牙设备");
  
            }
        }
    };
}

 


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

牵手生活

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值