スマホでのBluetooth通信(接続)5

■PCで受信できた。
少し間を開けたので再度スマホでのBluetooth通信に挑戦。今回はスマホから送信した内容をWindows PCのTeratermで受信できた。結局コードの問題でなくWindowsの設定の問題だった。

Androidのアプリをインストールして、スマホとPCとのBluetoothのペアリングなどは手動で済ませておく。アプリ起動時が下の画面。接続先のPC名・Bluetoothの物理アドレスのテキストビューをクリックすることで接続が確立するようにしておく。


接続が確立した後、PC側で「パーソナルエリアネットワークへ参加」、デバイスのプロパティを開くとサービスのタブに今回のアプリ名が表示される。


下の「com20240707」はコードの中で指定した名称。ここにチェックを入れる。


すると、COMポートのCOM3が割り当てられる。Bluetoothの設定画面から確認すると発信という形でCOM3が追加されている。


この状態でTeratermを起動し、COM3で受信するように設定する。アプリ内のテキストボックスに適当な文字列を入れて「SEND」ボタンを押すと、Teratermで受信される。


PC側のTeraterm。ボタンを押しても表示されない場合は、「com20240707」のチェックをもう一度外して付け直した。


Bluetoothの接続が確立した時点で、PC本体にも働きかけているよう。受信として使うReadメソッドもスマホ上のプログラムのはずだけど、PC側で読み取りが行われるというのは変な感じ。接続が確立した時点で、スマホとPCのBluetoothが連動して同じプログラムに従っているようなイメージかなー。

接続部分のコードは下の通り。Android developerのサイトのBluetooth Chat サンプルアプリから必要な部分を持ってきて修正したもの。

package com.example.sampleproject014_bluetooth;

import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothServerSocket;
import android.bluetooth.BluetoothSocket;
import android.util.Log;

import java.io.InputStream;
import java.io.OutputStream;
import java.util.UUID;
import java.io.IOException;

public class BluetoothService {
    private BluetoothAdapter bta_;
    private AcceptThread at_;
    private ConnectThread ct_;
    private ConnectedThread cdt_;

    public BluetoothService() {
        bta_ = BluetoothAdapter.getDefaultAdapter();
    }

    public synchronized void start() {
        if (at_ == null) {
            at_ = new AcceptThread();
            at_.start();
        }
    }

    public synchronized void connect(BluetoothDevice device) {
        if (ct_ == null) {
            ct_ = new ConnectThread(device);
            ct_.start();
        }
    }

    public synchronized void connected(BluetoothSocket socket) {
        if (at_ != null) {
            at_ = null;
        }
        if (ct_ != null) {
            ct_.cancel();
            ct_ = null;
        }
        if (cdt_ != null) {
            cdt_.cancel();
            cdt_ = null;
        }
        if (cdt_ == null) {
            cdt_ = new ConnectedThread(socket);
            cdt_.start();
        }
    }


    public void write(byte[] out) {
        ConnectedThread r;
        synchronized (this) {
            r = cdt_;
        }
        r.write(out);
    }


    private class AcceptThread extends Thread {
        private final BluetoothServerSocket bss_;
        private final UUID UUID_SAMPLE =
                UUID.fromString("00000000-0000-0000-0000-000000000000");
        public AcceptThread() {
            BluetoothServerSocket tmp = null;
            try {
                Log.i("listen_before", "aaa");
                tmp = bta_.listenUsingRfcommWithServiceRecord("com20240707", UUID_SAMPLE);
                Log.i("listen_after", "bbb");
            } catch (IOException e) {
                Log.e("error_a", "IOException", e);
            } catch (SecurityException se) {
                Log.e("error_b", "securityexception");
            }
            bss_ = tmp;
        }

        public void run() {
            BluetoothSocket socket;
            while (true) {
                try {
                    Log.d("accept_before", "log before accept method");
                    socket = bss_.accept();
                    Log.d("accept_after", "log after accept method");
                } catch (IOException e) {
                    Log.e("aaa", "IOException", e);
                    break;
                }
                if (socket != null) {
                    synchronized (BluetoothService.this) {
                        try {
                            Log.d("before connected", "111");
                            connected(socket);
                            bss_.close();
                        } catch (IOException e) {
                            break;
                        }
                    }
                }
            }
        }
    }


    private class ConnectThread extends Thread {
        private BluetoothSocket bs_;
        private final BluetoothDevice bd_;
        private final UUID UUID_SAMPLE =
                UUID.fromString("00000000-0000-0000-0000-000000000000");
        public ConnectThread(BluetoothDevice device) {
            BluetoothSocket tmp = null;
            try {
                tmp = device.createRfcommSocketToServiceRecord(UUID_SAMPLE);
            } catch (IOException e) {
                Log.e("error_ccc", "IOException", e);
            } catch (SecurityException se) {

            }
            bs_ = tmp;
            bd_ = device;
        }

        public void run() {
            Log.i("ccc", "start connectThread");
            try {
                bta_.cancelDiscovery();
            } catch (SecurityException se) {

            }
            Log.i("ddd", "after cancelDiscovery");
            BluetoothSocket fallbackSocket = null;
            try {
                Log.d("connect_before", "log before connect method");
                bs_.connect();
                Log.d("connect_after", "cccqqq");
            } catch (IOException e) {
                try {
                    Log.d("connect2_before", "qqq");
                    try {
                        bs_ = (BluetoothSocket) bd_.getClass().getMethod("createRfcommSocket", new Class[]{int.class}).invoke(bd_, 1);
                    } catch (Exception e3) {
                        Log.e("www", "aa", e3);
                    }
                    bs_.connect();
                    Log.d("connect_after", "qqq");
                } catch (IOException e2) {
                    Log.e("www", "unable to close() " + " socket during connection failure", e2);
                }
            } catch (SecurityException se) {

            }
            Log.d("connect_end_before", "123qqq");
            synchronized (BluetoothService.this) {
                ct_ = null;
            }
            Log.d("connectThread_before_connected", "123q4436qq");
            connected(bs_);
        }

        public void cancel() {
            try {
                bs_.close();
            } catch (IOException e) {
                Log.e("qqqq", "close() of connect failed", e);
            }
        }
    }

    private class ConnectedThread extends Thread {
        private final BluetoothSocket bs_;
        private final InputStream is_;
        private final OutputStream os_;
        private byte[] buffer_;

        public ConnectedThread(BluetoothSocket bs) {
            bs_ = bs;
            InputStream tempIn = null;
            OutputStream tempOut = null;

            try {
                tempIn = bs_.getInputStream();
                tempOut = bs_.getOutputStream();
            } catch (IOException e) {
                Log.e("ddd", "Error occurred when creating stream", e);
            }
            is_ = tempIn;
            os_ = tempOut;
        }

        public void run() {
            buffer_ = new byte[1024];
            int numBytes;
            while (true) {
                try {
                    Log.d("start?readfffsss", "aa");
                    numBytes = is_.read(buffer_);
                    Log.d("readfff", new Integer(numBytes).toString() + "log");
                } catch (IOException e) {
                    e.printStackTrace();
                    Log.d("fff", "Input stream was disconnected", e);
                    break;
                }
            }
        }

        public void write(byte[] bytes) {
            try {
                os_.write('a');
                os_.write(bytes);

                Log.i("qqq", "test");
            } catch (IOException e) {
                Log.e("ggg", "Error occurred when sending data", e);
            }
        }

        public void cancel() {
            try {
                Log.i("close_log", "close() socket");
                bs_.close();
            } catch (IOException e) {
                Log.e("aaaa", "close() of connect socket failed", e);
            }
        }
    }
}