potblog

技術メモとかガジェットレビューとか

androidとpcとの文字列送受信

androidとpc(teraterm)とで文字列の送受信を行いました。

android側はボタンを押すとteratermにHelloWorld!を送信します。
teraterm側は入力した文字をandroid側に送り、android側でボタンを押すと受信した文字を表示します。

android
f:id:potblog:20181025103814j:plain

teraterm
f:id:potblog:20181025103606p:plain

MainActivity.java
MacAddress にはpcのbluetoothアダプタのMacアドレスを書く

package com.example.t.myapplication;

import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothSocket;
import android.os.Message;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;

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

import android.os.Handler;

public class MainActivity extends AppCompatActivity {

    /** Bluetoothから受信した値. */
    private TextView mInputTextView;
    private static final String TAG = "BluetoothSample";
    /* Threadの状態を表す */
    private boolean isRunning;


    private BluetoothAdapter mBTAdapter = null;
    private BluetoothDevice mBTDevice = null;
    private BluetoothSocket mBTSocket = null;
    private OutputStream mOutputStream = null;//出力ストリーム

    private Button btnSend;//送信用ボタン
    private Button btnFinish;//終了用ボタン
    private TextView textview;//MacAddress表示用
    private String MacAddress = "xx:xx:xx:xx:xx:xx";
    private String MY_UUID = "00001101-0000-1000-8000-00805F9B34FB";
    private InputStream mmInStream = null;

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

        mInputTextView = (TextView)findViewById(R.id.inputValue);

        btnSend = (Button)findViewById(R.id.btnSend);
        btnFinish = (Button)findViewById(R.id.btnFinish);
        textview = (TextView)findViewById(R.id.textView);
        btnSend.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if(mBTSocket != null) {
                    Send();
                }
            }
        });
        btnFinish.setOnClickListener(new View.OnClickListener(){
            @Override
            public void onClick(View v) {
                finish();
            }
        });

        //ソケットを確立する関数
        BTConnect();

        //ソケットが取得出来たら、出力用ストリームを作成する
        if(mBTSocket != null){
            try{
                mOutputStream = mBTSocket.getOutputStream();
            }catch(IOException e){/*ignore*/}
        }else{
            btnSend.setText("mBTSocket == null !!");
        }
    }

    private void BTConnect(){
        Message valueMsg = new Message();
        valueMsg.obj = "connecting...";
        mHandler.sendMessage(valueMsg);

        //BTアダプタのインスタンスを取得
        mBTAdapter = BluetoothAdapter.getDefaultAdapter();

        textview.setText(MacAddress);
        //相手先BTデバイスのインスタンスを取得
        mBTDevice = mBTAdapter.getRemoteDevice(MacAddress);
        //ソケットの設定
        try {
            mBTSocket = mBTDevice.createRfcommSocketToServiceRecord(UUID.fromString(MY_UUID));
        } catch (IOException e) {
            mBTSocket = null;
        }

        if(mBTSocket != null) {
            //接続開始
            mBTAdapter.cancelDiscovery();
            try {
                mBTSocket.connect();
            } catch (IOException connectException) {
                isRunning = false;
                try {
                    mBTSocket.close();
                    mBTSocket = null;
                } catch (IOException closeException) {
                    return;
                }
            }
        }
    }

    private void Send(){
        //文字列を送信する
        isRunning = true;
        byte[] bytes_ = {};
        String str = "Hello World!";
        bytes_ = str.getBytes();
        try {
            //ここで送信
            mOutputStream.write(bytes_);

            mmInStream = mBTSocket.getInputStream();
            // InputStreamのバッファを格納
            byte[] buffer = new byte[1024];
            // 取得したバッファのサイズを格納
            int bytes;
            // InputStreamの読み込み
            bytes = mmInStream.read(buffer);
            Log.i(TAG,"bytes="+bytes);
            // String型に変換
            String readMsg = new String(buffer, 0, bytes);
            // null以外なら表示
            if(readMsg.trim() != null && !readMsg.trim().equals("")){
                Log.i(TAG,"value="+readMsg.trim());
                Message valueMsg = new Message();
                valueMsg.obj = readMsg;
                mHandler.sendMessage(valueMsg);
            }
        } catch (IOException e) {
            try{
                mBTSocket.close();
            }catch(IOException e1){/*ignore*/}
        }
    }

    @Override
    protected void onDestroy(){
        super.onDestroy();
        if(mBTSocket != null){
            try {
                mBTSocket.connect();
            } catch (IOException connectException) {/*ignore*/}
            mBTSocket = null;
        }
    }
    /**
     * 描画処理はHandlerでおこなう
     */
    Handler mHandler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            int action = msg.what;
            String msgStr = (String)msg.obj;
            mInputTextView.setText(msgStr);
        }
    };
}

activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout 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"
    tools:context=".MainActivity">

    <TextView
        android:id="@+id/textView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Hello"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintVertical_bias="0.4" />

    <Button
        android:id="@+id/btnSend"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Button"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintVertical_bias="0.6" />

    <Button
        android:id="@+id/btnFinish"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="終了" />

    <TextView
        android:id="@+id/inputValue"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:layout_marginBottom="8dp"
        app:layout_constraintBottom_toBottomOf="parent" />

</android.support.constraint.ConstraintLayout>

AndroidManifest.xmlに以下を追記

    <uses-permission android:name="android.permission.BLUETOOTH_ADMIN"/>
    <uses-permission android:name="android.permission.BLUETOOTH"/>

参考
Android開発日記 AndroidのBluetooth通信(SPP)【初心者向け】