web-dev-qa-db-ja.com

クライアントとしてのPCからサーバーとしてのモバイルにBluetooth経由で文字列を送信する

文字列をPCからAndroid Bluetooth経由のモバイルデバイスに転送することでサポートが必要です。Androidモバイルデバイスはサーバーとして機能し、文字列メッセージを表示しますクライアントのPCは、モバイルデバイスに文字列を送信する必要があります。

サーバーが抽出された文字列に反応するようにします(Bluetooth経由で転送されます)。つまり、サーバーは常に新しい文字列を受信する必要がありますが、他方ではこれらのメッセージに対応する必要があります(たとえば、あるメニューから別のメニューに移動する)。

BlueStack(2.1.1)をBluetoothStack(BlueCoveのライブラリを両方のプロジェクトにライブラリとして追加)として使用し、サーバーとクライアント間の通信の例を組み合わせて試してみました こちら =。

アップデート:

サーバーのRFComm接続を使用するuser_CCのおかげで、サーバーからのコードを更新しました。

_public class RFCommServer extends Thread{

//based on Java.util.UUID
private static UUID MY_UUID = UUID.fromString("446118f0-8b1e-11e2-9e96-0800200c9a66");

// The local server socket
private BluetoothServerSocket mmServerSocket;

// based on Android.bluetooth.BluetoothAdapter
private BluetoothAdapter mAdapter;
private BluetoothDevice remoteDevice;

private Activity activity;

public RFCommServer(Activity activity) {
    this.activity = activity;
}

public void run() {
    BluetoothSocket socket = null;
    mAdapter = BluetoothAdapter.getDefaultAdapter();        

    // Listen to the server socket if we're not connected
    while (true) {

        try {
            // Create a new listening server socket
            Log.d(this.getName(), ".....Initializing RFCOMM SERVER....");

            // MY_UUID is the UUID you want to use for communication
            mmServerSocket = mAdapter.listenUsingRfcommWithServiceRecord("MyService", MY_UUID);
            //mmServerSocket = mAdapter.listenUsingInsecureRfcommWithServiceRecord(NAME, MY_UUID); // you can also try using In Secure connection...

            // This is a blocking call and will only return on a
            // successful connection or an exception
            socket = mmServerSocket.accept();

        } catch (Exception e) {

        }

        try {
            Log.d(this.getName(), "Closing Server Socket.....");
            mmServerSocket.close();

            InputStream tmpIn = null;
            OutputStream tmpOut = null;

            // Get the BluetoothSocket input and output streams

            tmpIn = socket.getInputStream();
            tmpOut = socket.getOutputStream();

            DataInputStream mmInStream = new DataInputStream(tmpIn);
            DataOutputStream mmOutStream = new DataOutputStream(tmpOut);

            // here you can use the Input Stream to take the string from the client whoever is connecting
            //similarly use the output stream to send the data to the client

            RelativeLayout layout = (RelativeLayout) activity.findViewById(R.id.relativeLayout_Layout);
            TextView text = (TextView) layout.findViewById(R.id.textView_Text);

            text.setText(mmInStream.toString());
        } catch (Exception e) {
            //catch your exception here
        }
    }
}
_

here のSPPクライアントのコード:

_/**
* A simple SPP client that connects with an SPP server
*/
public class SampleSPPClient implements DiscoveryListener{

//object used for waiting
private static Object lock=new Object();

//vector containing the devices discovered
private static Vector vecDevices=new Vector();

private static String connectionURL=null;

public static void main(String[] args) throws IOException {

    SampleSPPClient client=new SampleSPPClient();

    //display local device address and name
    LocalDevice localDevice = LocalDevice.getLocalDevice();
    System.out.println("Address: "+localDevice.getBluetoothAddress());
    System.out.println("Name: "+localDevice.getFriendlyName());

    //find devices
    DiscoveryAgent agent = localDevice.getDiscoveryAgent();

    System.out.println("Starting device inquiry...");
    agent.startInquiry(DiscoveryAgent.GIAC, client);

    try {
        synchronized(lock){
            lock.wait();
        }
    }
    catch (InterruptedException e) {
        e.printStackTrace();
    }


    System.out.println("Device Inquiry Completed. ");

    //print all devices in vecDevices
    int deviceCount=vecDevices.size();

    if(deviceCount <= 0){
        System.out.println("No Devices Found .");
        System.exit(0);
    }
    else{
        //print bluetooth device addresses and names in the format [ No. address (name) ]
        System.out.println("Bluetooth Devices: ");
        for (int i = 0; i <deviceCount; i++) {
            RemoteDevice remoteDevice=(RemoteDevice)vecDevices.elementAt(i);
            System.out.println((i+1)+". "+remoteDevice.getBluetoothAddress()+" ("+remoteDevice.getFriendlyName(true)+")");
        }
    }

    System.out.print("Choose Device index: ");
    BufferedReader bReader=new BufferedReader(new InputStreamReader(System.in));

    String chosenIndex=bReader.readLine();
    int index=Integer.parseInt(chosenIndex.trim());

    //check for spp service
    RemoteDevice remoteDevice=(RemoteDevice)vecDevices.elementAt(index-1);
    UUID[] uuidSet = new UUID[1];
    uuidSet[0]=new UUID("446118f08b1e11e29e960800200c9a66", false);

    System.out.println("\nSearching for service...");
    agent.searchServices(null,uuidSet,remoteDevice,client);

    try {
        synchronized(lock){
            lock.wait();
        }
    }
    catch (InterruptedException e) {
        e.printStackTrace();
    }

    if(connectionURL==null){
        System.out.println("Device does not support Simple SPP Service.");
        System.exit(0);
    }

    //connect to the server and send a line of text
    StreamConnection streamConnection=(StreamConnection)Connector.open(connectionURL);

    //send string
    OutputStream outStream=streamConnection.openOutputStream();
    PrintWriter pWriter=new PrintWriter(new OutputStreamWriter(outStream));
    pWriter.write("Test String from SPP Client\r\n");
    pWriter.flush();


    //read response
    InputStream inStream=streamConnection.openInputStream();
    BufferedReader bReader2=new BufferedReader(new InputStreamReader(inStream));
    String lineRead=bReader2.readLine();
    System.out.println(lineRead);


}//main

//methods of DiscoveryListener
public void deviceDiscovered(RemoteDevice btDevice, DeviceClass cod) {
    //add the device to the vector
    if(!vecDevices.contains(btDevice)){
        vecDevices.addElement(btDevice);
    }
}

//implement this method since services are not being discovered
public void servicesDiscovered(int transID, ServiceRecord[] servRecord) {
    if(servRecord!=null && servRecord.length>0){
        connectionURL=servRecord[0].getConnectionURL(0,false);
    }
    synchronized(lock){
        lock.notify();
    }
}

//implement this method since services are not being discovered
public void serviceSearchCompleted(int transID, int respCode) {
    synchronized(lock){
        lock.notify();
    }
}


public void inquiryCompleted(int discType) {
    synchronized(lock){
        lock.notify();
    }

}//end method

}
_

テストには、最新のAndroid APIを使用したGalaxy Nexus(GT-I9250)を使用します。

user_CCのおかげで、クライアントとサーバーは例外なく実行されるようになりました。しかし、残念ながらクライアントはサーバーに接続できません(下のスクリーンショットを参照)。これは、connectionURLが設定されていないためです(したがって、デフォルトでここにジャンプしますif(connectionURL==null)

実際にサーバーに接続できるように、クライアントコードを変更するにはどうすればよいですか?次の行に適切なconnectionURLが必要です。

_StreamConnection streamConnection=(StreamConnection)Connector.open(connectionURL)
_

これまでのところ、私はどういうわけかServiceRecordを取得する必要があることを知りましたが、悲しいことに、これは here のコード例にも記載されていません。

enter image description here

22
Elementary

RFComm APISを使用して、スレッドであり、サーバーとして機能し、クライアント接続をリッスンするクラスを定義するために管理している通信を機能させる必要があります。また、あなたが理解できるようにコメントを付けました。

    private class AcceptThread extends Thread {
    // The local server socket
    private BluetoothServerSocket mmServerSocket;

    public AcceptThread() {
    }

    public void run() {         
        BluetoothSocket socket = null;

                    BluetoothAdapter mAdapter = BluetoothAdapter.getDefaultAdapter();

        // Listen to the server socket if we're not connected
        while (true) {

            try {
                // Create a new listening server socket
                Log.d(TAG, ".....Initializing RFCOMM SERVER....");

                // MY_UUID is the UUID you want to use for communication
                mmServerSocket = mAdapter.listenUsingRfcommWithServiceRecord(NAME, MY_UUID);                    
                //mmServerSocket = mAdapter.listenUsingInsecureRfcommWithServiceRecord(NAME, MY_UUID);  you can also try using In Secure connection...

                // This is a blocking call and will only return on a
                // successful connection or an exception                    
                socket = mmServerSocket.accept();                   

            } catch (Exception e) {

            }

            try {
                Log.d(TAG, "Closing Server Socket.....";                    
                mmServerSocket.close();



                InputStream tmpIn = null;
                OutputStream tmpOut = null;

                // Get the BluetoothSocket input and output streams

                tmpIn = socket.getInputStream();
                tmpOut = socket.getOutputStream();


                mmInStream = new DataInputStream(tmpIn);
                mmOutStream = new DataOutputStream(tmpOut); 

                // here you can use the Input Stream to take the string from the client whoever is connecting
                //similarly use the output stream to send the data to the client
            } catch (Exception e) {
                //catch your exception here
            }

        }
    }

}

これが役立つことを願っています

別の質問:

クライアント側(PC)UUIDクラスでjavax.bluetooth.UUIDを宣言するには、javax.bluetooth.UUIDを使用する必要があります

   uuidSet2[0] = new UUID("446118f08b1e11e29e960800200c9a66", false);

サーバー側でのJava.util.UUIDの宣言(Android)

    UUID MY_UUID = UUID.fromString("446118f0-8b1e-11e2-9e96-0800200c9a66");
7
user_CC

私はJava開発者ではありませんが、Android(c#)のMonoで同様の問題が発生しました

SPPのUUIDは"00001101-0000-1000-8000-00805F9B34FB"
これは、Bluetooth SPPアダプターを識別するためのよく知られたUIDです。

私のC#コードでは

private static UUID MY_UUID = UUID.FromString("00001101-0000-1000-8000-00805F9B34FB");

Javaコードを次のように更新できると思います。

new UUID("00001101-0000-1000-8000-00805F9B34FB", true);

関数がどのパラメータを受け入れるかはわかりませんが、確認する必要があるかもしれません。

Androidデバイスをクライアントとして使用していましたが、この情報は役に立つかもしれませんが、
だから私は元々Javaサンプルから翻訳したc#コードをここに含めます、
したがって、翻訳して戻すことができるはずです:

btAdapter = BluetoothAdapter.DefaultAdapter;

btAdapter.CancelDiscovery(); //Always call CancelDiscovery before doing anything
remoteDevice = btAdapter.GetRemoteDevice(Settings["deviceaddress"].ToString());

socket = remoteDevice.CreateRfcommSocketToServiceRecord(MY_UUID);
socket.Connect();

基本的に、デフォルトのアダプターを取得し、実行中のディスカバリー操作をキャンセルしてから、他のデバイスへのソケットを作成します。あなたの場合、あなたは接続するのではなく、あなたの情報のためだけに聞きたいでしょう。

これがお役に立てば幸いです。申し訳ありませんが、より多くのJava特定の情報を提供できません。

'更新:' Java多かれ少なかれ私が使用しているのと同じ方法に従っているという小さなサンプルを見つけました: Androidでbluetooth SPPを接続する際の問題?

2
TimothyP