質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

88.64%

UnityでBluetooth機能を持つAndroidプラグインを動かすと重い。通信できない。

解決済

回答 1

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 2,096

GG_4454

score 15

ボタンを押すとAndroidのBluetooth機能を通じてBluetoothモジュールRN42に通信がなされ、その値をArduinoで読み取りLEDを光らせる。

こういったものを作っています。

このアプリ作成にあたってUnityからBluetoothを扱う方法を調べるうち、Unityにネイティブプラグインというものを加えAndroidの機能(ここではBluetooth)を使用する方法があると知りました。
さらに調べた結果、Android Studioを用いてJava Libraryを作成。ここにUnityから呼び出せる関数として機能をまとめておくことでBluetoothも使えると考えました。
そこで参考にしたのがこのページです。これはAndroid Studioで作成するアプリでBluetoothを使用するためのものですが、これをLibraryに関数としてまとめてしまえば、Unityから呼び出しても使用できる!
そう思っていたのですが・・・

次に、実際に作成したAndroid Libraryのソースを記します。

package com.hoge.bluetooth_plugin_library;

import android.app.AlertDialog;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothSocket;
import android.content.Context;

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


public class BluetoothPlugin {

    static private BluetoothAdapter mBTAdapter = null;// Bluetooth通信を行うために必要な情報を格納する
    static private BluetoothDevice mBTDevice   = null;// 実際に通信を行うデバイスの情報を格納する
    static private BluetoothSocket mBTSocket   = null;// ソケット情報を格納する
    static private OutputStream mOutputStream  = null;// 出力ストリーム

    static private boolean connectFlg = false;// Connect確認用フラグ
    static private String DEVICE_NAME = "RNBT-HOGE";// デバイス名
    static private UUID   MY_UUID     = UUID.fromString("00001101-0000-1000-8000-00805F9B34FB");// 通信規格がSPPであることを示す数字

    // Bluetoothを使用するにあたっての初期設定
    static public boolean BluetoothSetup(){

        // Bluetoothのデバイス名を取得
        mBTAdapter = BluetoothAdapter.getDefaultAdapter();
        Set< BluetoothDevice > devices = mBTAdapter.getBondedDevices();
        for ( BluetoothDevice device : devices){
            if(device.getName().equals(DEVICE_NAME)){
                mBTDevice = device;
                return true;
            }
        }
        // 取得できなかった
        return false;
    }

    // Bluetoothを使用して通信する
    static public void BluetoothRun(){

        try{
            // 取得したデバイス名を使ってBluetoothでSocket接続
            mBTSocket = mBTDevice.createRfcommSocketToServiceRecord(MY_UUID);
            mBTSocket.connect();
            mOutputStream = mBTSocket.getOutputStream();
            connectFlg = true;
        }catch(Exception e){
            try{
                mBTSocket.close();
            }catch(Exception ee){}

            connectFlg = false;
        }
    }

    // Bluetoothを使用して出力する
    static public void BluetoothSend(){

        // もしモジュールと接続できていれば
        if(connectFlg) {
            try {
                mOutputStream.write("1".getBytes());
            } catch (IOException e) {}
        }
    }
}


InputStreamはおそらく通信で送られてきた情報を扱う部分ですので、今回のような一方的な送信には使用しないと思い省いています。
次に、実際にUnityでこれらの関数を使用している部分を記します。

using UnityEngine;

public class BluetoothPluginTest : MonoBehaviour
{
    private AndroidJavaClass bluetoothPlugin;

    private void Awake()
    {
        bluetoothPlugin = new AndroidJavaClass("com.hoge.bluetooth_plugin_library.BluetoothPlugin");

        // Bluetoothのセットアップを実行
        if(bluetoothPlugin.CallStatic<bool>("BluetoothSetup"))
        {
            // Bluetoothの初期設定が完了
            Debug.Log("Bluetoothの初期設定が完了しました。");
        }
        else
        {
            // Bluetoothの初期設定が失敗
            Debug.Log("Bluetoothの初期設定に失敗しました。");
        }
    }

    private void Update()
    {
        // Bluetoothの通信を更新
        bluetoothPlugin.CallStatic("BluetoothRun");
    }

    public void OnClick()
    {
        bluetoothPlugin.CallStatic("BluetoothSend");
    }

}

また、Arduino Unoに書いたプログラムです。

#include <SoftwareSerial.h>

SoftwareSerial android(2,3);

const int LED_PIN = 13; // デバッグ用LED
byte data = 0;  // Androidからのテキスト取得用
bool flag = false;

void setup(){
  // Bluetooth用のシリアルのポートを設定
  android.begin(115200);
  // arduinoのシリアルモニタ用
  Serial.begin(19200); 
  // LEDピンの出力設定
  pinMode(LED_PIN, OUTPUT);

  Serial.write("init");
}

void loop(){

  if(android.available()){
    data = android.read();
    Serial.println(data);

    flag = true;
  }

  if(flag)
  {
    digitalWrite(LED_PIN, HIGH);
  }
}


何か情報が送られてきた時点でフラグを立て、13番のLEDを点灯させる、というプログラムにしたつもりです。

Unityから実機(Nexus7)でBuild And Runしてみると、「Made with Unity」が消えてから黒い画面のまま十数秒経ってゲーム画面が表示されます(おそらくこの間に接続されているのでしょうが、遅すぎですか?)。
ゲーム画面が表示されると同時にBluetoothモジュールの「Conect」ランプが光るので、一応接続はできているみたいです。画面からLogが見れるようにしているのですが、そこに
Blutoohの初期設定が完了しました。
と2回出ます(AwakeやStartは複数回呼ばれるらしい?)。やはり接続は成功しているみたいです。
しかしボタンを押してOnClick関数からデータを送信するBluetoothSend関数を呼び出しても、LEDには何の変化も見られません。シリアルモニタも確認しようとしたのですが、そもそもどのbpsの画面を見ていいかわからず、19200bpsの画面には「init」と書いてあるのを確認しました。しかし画面のボタンを押しても何の変化もなかったのでやはり送信はできていないと思います。
なお、この実行中非常にアプリが重いです。画面を横に傾けるのに6秒ほどかかり、ボタンを押しても反応が5秒ほど遅れます。

質問内容は次の通りです。
・全体としてこの方法での通信は可能でしょうか?
・データが送信できていない(あるいは、送信できていないと勘違いしているだけ?)理由を知りたいです。
・アプリが非常に重くなる理由を教えてください。素人の考えですが、データの送信にかかる時間が1/60秒より大きく、Unityの実行速度が早すぎて重くなっているということはないでしょうか?

以上です。少しでも手掛かりが欲しいので、一つだけでもお答えいただけると嬉しいです。ご不明な点があればお聞きください。

よろしくお願いします。

バージョン情報
Android Studio 3.2
Unity 2018.2.11f1
Arduino 1.8.5

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 1

check解決した方法

0

なぜか解決していました....何が悪かったのかわかりません。というか最後まで回答がいただけなかったですね。やはりマイナーすぎますか(笑)

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 88.64%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る