蓝牙小试牛刀之模拟蓝牙客户端向服务端传数据

今天我们来实现一下客户端和服务端通过蓝牙传数据
效果图如下:
这里写图片描述
这个布局太简单了,我就不给出了,直接上逻辑.

MainActivity:

public class MainActivity extends Activity implements View.OnClickListener {

    private Button btn1;
    private Button btn2;
    private Button btn3;
    private Button btn4;
    private Button btn5;
    private Button btn6;
    private Button btn7;
    private BluetoothAdapter mBlueToothAdapter;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        initView();
        setListener();
    }

    private void setListener() {
        btn1.setOnClickListener(this);
        btn2.setOnClickListener(this);
        btn3.setOnClickListener(this);
        btn4.setOnClickListener(this);
        btn5.setOnClickListener(this);
        btn6.setOnClickListener(this);
        btn7.setOnClickListener(this);
    }

    private void initView() {
        btn1 = ((Button) findViewById(R.id.btn1));
        btn2 = ((Button) findViewById(R.id.btn2));
        btn3 = ((Button) findViewById(R.id.btn3));
        btn4 = ((Button) findViewById(R.id.btn4));
        btn5 = ((Button) findViewById(R.id.btn5));
        btn6 = ((Button) findViewById(R.id.btn6));
        btn7 = ((Button) findViewById(R.id.btn7));
    }

    @Override
    public void onClick(View v) {
        switch (v.getId()){
            case R.id.btn1://打开蓝牙
                onOpen();
                break;
            case R.id.btn2://关闭蓝牙
                onClose();
                break;
            case R.id.btn3://允许搜索
                onAbleFound();
                break;
            case R.id.btn4://开始搜索
                onFound();
                break;
            case R.id.btn5://客户端
                Intent intent=new Intent(this,ClientSocketActivity.class);
                startActivity(intent);
                break;
            case R.id.btn6://服务器端
                Intent intent1=new Intent(this,ServerSocketActivity.class);
                startActivity(intent1);

                break;
            case R.id.btn7://OBEX服务器端

                break;
        }
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if (requestCode==300){
            //蓝牙已开启
            Toast.makeText(MainActivity.this,"蓝牙已打开",Toast.LENGTH_SHORT).show();
        }
    }
    /*
    * 打开蓝牙
    * */
    public void onOpen(){
        mBlueToothAdapter= BluetoothAdapter.getDefaultAdapter();
        if (mBlueToothAdapter==null){
            Toast.makeText(MainActivity.this,"手机不支持蓝牙",Toast.LENGTH_SHORT).show();
            return;
        }
        if (!mBlueToothAdapter.isEnabled()){//蓝牙未开启 则开启蓝牙
            Intent enableIntent=new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
            startActivityForResult(enableIntent,300);
        }
    }
    /*
    * 关闭蓝牙
    * */
    public void onClose(){
        if (mBlueToothAdapter.enable())
        mBlueToothAdapter.disable();
        Toast.makeText(MainActivity.this,"蓝牙已关闭",Toast.LENGTH_SHORT).show();
    }
    /*
    * 允许被搜索到 时长300
    * */
    public void onAbleFound(){
        if (mBlueToothAdapter!=null&&mBlueToothAdapter.isEnabled()){
            if (mBlueToothAdapter.getScanMode()==BluetoothAdapter.SCAN_MODE_CONNECTABLE_DISCOVERABLE){
                Intent discoverableIntent=new Intent(BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE);
                //使本机在300秒内可被搜索
                discoverableIntent.putExtra(BluetoothAdapter.EXTRA_DISCOVERABLE_DURATION,300);
                startActivity(discoverableIntent);
                Toast.makeText(MainActivity.this,"蓝牙已允许被检测",Toast.LENGTH_SHORT).show();
            }

        }
    }
    public void onFound(){
        Intent intent=new Intent(MainActivity.this,BlueListActivity.class);
        startActivity(intent);
    }

    @Override
    protected void onStart() {
        super.onStart();
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
    }

    @Override
    protected void onResume() {
        super.onResume();
    }

    @Override
    protected void onRestart() {
        super.onRestart();
    }
}

客户端逻辑:

/*
* 客户端
*
* */
public class ClientSocketActivity extends AppCompatActivity implements View.OnClickListener {
    private BluetoothAdapter mBluetoothAdapter;
    private  static final int REQUEST_BLUELIST=200;
    BluetoothDevice device;
    private Button btn;
    BluetoothSocket socket=null;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_client);
        initView();
        setListener();
        Log.i("onCreate----","onCreate");
        // 获取到蓝牙默认的适配器
        mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
        if (!mBluetoothAdapter.isEnabled()){
            finish();
            return;
        }
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if (requestCode!=REQUEST_BLUELIST){
            return;
        }
        if (resultCode!=RESULT_OK){
            return;
        }
         device=data.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);

         new Thread(new Runnable() {
             @Override
             public void run() {
                //开始连接
                 connect();
             }
         }).start();
    }

    private void connect() {
        try {
           socket=device.createRfcommSocketToServiceRecord(UUID.fromString("db764ac8-4b08-7f25-aafe-59d03c27bae3"));
            if (socket!=null){
                socket.connect();
                OutputStream outputStream=socket.getOutputStream();
                if (outputStream != null) {
                    // 需要发送的信息
                    String text ="向服务端"+device.getName()+"发送的信息";
                    // 以utf-8的格式发送出去
                    outputStream.write(text.getBytes("UTF-8"));
//                    Toast.makeText(ClientSocketActivity.this,"消息已发出,等待服务端接收",Toast.LENGTH_SHORT).show();
                }
            }
        } catch (IOException e) {
            e.printStackTrace();
//            Toast.makeText(ClientSocketActivity.this,"socket未连接",Toast.LENGTH_SHORT).show();
        }finally {
        }
    }
    private void setListener() {
        btn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                //跳转到搜索蓝牙列表 选择一个要连接的服务器 回到客户端 开始连接
                Intent intent=new Intent(ClientSocketActivity.this,BlueListActivity.class);
                startActivityForResult(intent,REQUEST_BLUELIST);
            }
        });
    }
    private void initView() {
        // 获取到ListView组件
        btn=(Button)findViewById(R.id.btn);
    }
    @Override
    public void onClick(View v) {
    }
    @Override
    protected void onDestroy() {
        super.onDestroy();
        if (socket!=null){
            socket=null;
        }
    }

}

activity_client布局

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context="com.example.lzq.bluetoothmanager.MainActivity">

    <TextView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="客户端"

        />
        <Button
            android:id="@+id/btn"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="搜索蓝牙设备"
            />

</LinearLayout>

服务端逻辑:

/*
* 服务端
*
* */
public class ServerSocketActivity extends Activity implements View.OnClickListener {
    private BluetoothAdapter mBluetoothAdapter;
    private Thread serverWorker=new Thread(){
        @Override
        public void run() {
            listen();
        }
    };
    private Handler handler=new Handler(){
        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            // 通过msg传递过来的信息,吐司一下收到的信息
            Toast.makeText(ServerSocketActivity.this, (String) msg.obj, Toast.LENGTH_SHORT).show();
        }
    };
    private BluetoothServerSocket serverSocket;
    private BluetoothSocket clientSocket;
    private ListView lv;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_server);
        initView();
        setListener();
        // 获取到蓝牙默认的适配器
        mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
        if (!mBluetoothAdapter.isEnabled()){
            finish();
            return;
        }
        //开启服务器
        serverWorker.start();

    }

   /*
   * 监听是否有客户端连接
   * */
    private void listen() {
        try {
            serverSocket=mBluetoothAdapter.listenUsingRfcommWithServiceRecord("服务端",UUID.fromString("db764ac8-4b08-7f25-aafe-59d03c27bae3"));
            /*
            * 客户连线列表
            * */
            final List<String> lines=new ArrayList<>();
            handler.post(new Runnable() {
                @Override
                public void run() {
                    lines.add("Rfcomm server started...");
                    ArrayAdapter<String> arrayAdapter=new ArrayAdapter<String>(ServerSocketActivity.this,android.R.layout.simple_list_item_1,lines);
                    lv.setAdapter(arrayAdapter);
                }
            });
            clientSocket=serverSocket.accept();
            //处理请求内容
            if (clientSocket!=null){
                Log.i("clientSocket---","已经连接上客户端");
//                Toast.makeText(ServerSocketActivity.this,"已经连接上客户端",Toast.LENGTH_SHORT).show();
                InputStream inputStream = clientSocket.getInputStream();
                // 无线循环来接收数据
                while (true) {
                    // 创建一个128字节的缓冲
                    byte[] buffer = new byte[128];
                    // 每次读取128字节,并保存其读取的角标
                    int count = inputStream.read(buffer);
                    // 创建Message类,向handler发送数据
                    Message msg = new Message();
                    // 发送一个String的数据,让他向上转型为obj类型
                    msg.obj = new String(buffer, 0, count, "utf-8");
                    // 发送数据
                    handler.sendMessage(msg);
                }
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    private void setListener() {
    }
    private void shutDownServer() {
        new Thread(new Runnable() {
            @Override
            public void run() {
                serverWorker.interrupt();
                if (serverSocket!=null){
                    try {
                        serverSocket.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                    serverSocket=null;
                }
            }
        }).start();
    }
    private void initView() {
        lv = (ListView) findViewById(R.id.lv);
    }
    @Override
    public void onClick(View v) {
    }
    @Override
    protected void onDestroy() {
        super.onDestroy();
        shutDownServer();
    }
}

activity_server布局

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context="com.example.lzq.bluetoothmanager.MainActivity">

    <TextView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="服务端"

        />
        <ListView
            android:id="@+id/lv"
            android:layout_width="match_parent"
            android:layout_height="match_parent"></ListView>
</LinearLayout>

BlueListActivity

/*
* 搜索蓝牙列表
*
* */
public class BlueListActivity extends AppCompatActivity implements View.OnClickListener, AdapterView.OnItemClickListener {


    private ListView lvDevices;
    private ArrayAdapter<String> arrayAdapter;
    //蓝牙设备信息集合包括 name address
    private List<String> bluetoothDevicesStr = new ArrayList<String>();

    //蓝牙设备对象集合
    private List<BluetoothDevice> bluetoothDevices = new ArrayList<BluetoothDevice>();
    private BluetoothAdapter mBluetoothAdapter;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_blue_list);
        initView();
        setListener();


        // 为listview设置字符换数组适配器
        arrayAdapter = new ArrayAdapter<String>(this,android.R.layout.simple_list_item_1, android.R.id.text1,bluetoothDevicesStr);
        // 为listView绑定适配器
        lvDevices.setAdapter(arrayAdapter);
        // 为listView设置item点击事件侦听
        lvDevices.setOnItemClickListener(this);

        // 获取到蓝牙默认的适配器
        mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
        if (mBluetoothAdapter==null){
            Toast.makeText(BlueListActivity.this,"手机不支持蓝牙",Toast.LENGTH_SHORT).show();
            return;
        }
        if (!mBluetoothAdapter.isEnabled()){//蓝牙未开启 则开启蓝牙
            Intent enableIntent=new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
            startActivityForResult(enableIntent,200);
        }

        // 获取曾经匹配的蓝牙设备  用Set集合保持已匹配的蓝牙设备
        Set<BluetoothDevice> devices = mBluetoothAdapter.getBondedDevices();
        if (devices.size() > 0) {
            for (BluetoothDevice bluetoothDevice : devices) {
                // 保存到arrayList集合中
                bluetoothDevicesStr.add("曾经匹配过的蓝牙--"+bluetoothDevice.getName() + ":"
                        + bluetoothDevice.getAddress() + "\n");
                bluetoothDevices.add(bluetoothDevice);
            }
        }

        // 因为蓝牙搜索到设备和完成搜索都是通过广播来告诉其他应用的
        // 这里注册找到设备和完成搜索广播
        IntentFilter filter=new IntentFilter(BluetoothDevice.ACTION_FOUND);
        filter.addAction(BluetoothAdapter.ACTION_DISCOVERY_FINISHED);
        filter.addAction(BluetoothDevice.ACTION_ACL_CONNECTED);   //设备已经连接广播
        filter.addAction(BluetoothDevice.ACTION_ACL_DISCONNECTED); //设备断开连接广播
        registerReceiver(receiver, filter);
        //开始搜索
        Search();

    }

    private void setListener() {
    }

    private void initView() {
        // 获取到ListView组件
        lvDevices = (ListView) findViewById(R.id.lv);
    }
    public void Search() {
        setTitle("正在扫描...");
        // 点击搜索周边设备,如果正在搜索,则暂停搜索
        if (mBluetoothAdapter.isDiscovering()) {
            mBluetoothAdapter.cancelDiscovery();
        }
        mBluetoothAdapter.startDiscovery();
    }

    // 注册广播接收者
    private BroadcastReceiver receiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context arg0, Intent intent) {
            // 获取到广播的action
            String action = intent.getAction();
            // 判断广播是搜索到设备还是搜索完成
            if (action.equals(BluetoothDevice.ACTION_FOUND)) {
                // 找到设备后获取其设备
                BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
                // 判断这个设备是否是之前已经绑定过了,如果是则不需要添加,在程序初始化的时候已经添加了
                if (device.getBondState() != BluetoothDevice.BOND_BONDED) {
                    // 设备没有绑定过,则将其保持到arrayList集合中
                    bluetoothDevicesStr.add(device.getName() + ":"
                            + device.getAddress() + "\n");
                    // 更新字符串数组适配器,将内容显示在listView中
                    arrayAdapter.notifyDataSetChanged();
                    bluetoothDevices.add(device);
                }
            } else if (action.equals(BluetoothAdapter.ACTION_DISCOVERY_FINISHED)) {
                setTitle("搜索完成");
            }
        }
    };
    @Override
    public void onClick(View v) {
        switch (v.getId()){
            case R.id.btn1://打开蓝牙
                break;
        }
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        unregisterReceiver(receiver);
        if (bluetoothDevicesStr!=null){
            bluetoothDevicesStr=null;
        }
        if (bluetoothDevices!=null){
            bluetoothDevices=null;
        }
    }

    @Override
    public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
            mBluetoothAdapter.cancelDiscovery();
            Intent intent=new Intent();
            intent.putExtra(BluetoothDevice.EXTRA_DEVICE,bluetoothDevices.get(position));
            setResult(RESULT_OK,intent);
            finish();
    }
}

注意:测试时要在两个手机同时安装app,且一个打开服务器,作为服务端,另一个打开客户端,模拟向服务端发送数据。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值