1

Bluetoothを使用して接続し、RFCOMMチャネルを介してデータを転送する2つのAndroidデバイスがあります。データを受信するデバイスは1つだけですが、他のデバイスはデータを送信します...

このコードを使用して、他のデバイスに接続し、RFCOMMチャネルのリッスンを開始できます。

Method m = device.getClass().getMethod("createRfcommSocket", new Class[] { int.class });
socket = (BluetoothSocket) m.invoke(device, 2);
socket.connect();

class BasicThread implements Runnable{    

        public void run() {
            try {
                InputStream stream = socket.getInputStream();
                BufferedReader r = new BufferedReader(new InputStreamReader(stream));
                while (true){
                    Log.d("myapp", "now listening...");
                    latestLine = r.readLine();
                    Log.d("myapp", latestLine);
                }
            } catch (IOException e) {

            }
        } 
    }

    new Thread(new BasicThread()).run();

他のデバイスを使用して、次のようなリスニングソケットを実装しました。

Method m = blue.getClass().getMethod("listenUsingRfcommOn", new Class[] { int.class });
BluetoothServerSocket socket = (BluetoothServerSocket) m.invoke(blue, 2);

BluetoothSocket sock = socket.accept();

Log.d("myapp", "Connected...\n\n\n\n\n\n\n\n");

OutputStream s = sock.getOutputStream();
final PrintWriter out = new PrintWriter(s);

これらは両方ともRFCOMMチャネル2で接続し、両方とも相互にSEEしますが、2番目のデバイスは常にBluetoothSocket sock = socket.accept();

何か助けはありますか?

4

1 に答える 1

3

わかりました、私は初心者ですが、助けようとすることができます. これが私の経験です。リフレクションを使用して2つのデバイスを接続することができました。私の Android フォンは method を使用してデータを受信してlistenUsingInsecureRfcommOn​​いますが、他のデバイスは通信のマスターであり、BT SPP 経由でデータを送信しています。この方法では、目に見える SDP レコードが作成されないため、他のデバイスでは検出できませんでした。そのため、Bluecove と Java SE を使用して、特定の範囲内のすべてのポートに接続しようとする小さなスニファーを作成しました。コードは次のとおりです。

package application.test;

import static java.lang.System.out;

import java.io.InputStream;
import java.io.PrintStream;
import java.text.SimpleDateFormat;

import javax.microedition.io.Connector;
import javax.microedition.io.StreamConnection;

public class RfCommClient {

    public static void main(String args[]) {
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e1) {
            e1.printStackTrace();
        }

        String add = "btspp://8C71F894A36D:";
        String par = ";authenticate=false;encrypt=false;master=true";
        String url = null;
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd;HH-mm-ss-SSS");
        for (int i = 1; i < 15; ++i) {
            try {
                url = add + i + par;
                out.format("Time: %s, port = %d\n", sdf.format(System.currentTimeMillis()), i);
                StreamConnection conn = (StreamConnection) Connector.open(url);
                PrintStream ops = new PrintStream(conn.openOutputStream());
                ops.println("Hi there...");

                // response
                Thread.sleep(1000);

                InputStream is = conn.openInputStream();
                byte[] resp = new byte[5];
                int r = is.read(resp);

                out.println("r = " + r + ", response = " + new String(resp, "US-ASCII"));

                Thread.sleep(10 * 1000);
                conn.close();
            } catch (Exception e) {
                out.println("Exception occured, time = " + sdf.format(System.currentTimeMillis()) + ", i = " + i);
                //e.printStackTrace();
            }
        }

    }
}

私が学んだことは、一部のポートが使用され、一部のポートが使用できないことです (ドキュメントに記載されているように、ポート 0 など)。たとえば、ポート2にデータを送信すると、ERRで始まる5文字が返されるため、ポート2が使用されたと思います:)。

一方、私のスレッドはまだ待機中ですか?! :) これにより、ポート (またはチャネル) が常に目的の番号にマップされているとは限らないことに気付きました。たとえば、ポート15で何かを送信したいことがよくありましたが、Androidではポート9で待機しているスレッドがデータを受信しました:)したがって、どのポートが実際に割り当てられているかを確認することをお勧めします! 私が投稿したコードを使用してそれを達成できます。そしてもう1つ、これは通常のAPIが使用されているときにチャネルを選択する関数へのリンクchannelPickerです。私が間違っていなければ、いくつかの定数は予約されたチャネルを表す必要があります。

ポートを登録するための私のコードは少し異なります。これが私のやり方です:

        Method m = cba.getDeclaredMethod("listenUsingInsecureRfcommOn", int.class);
        ss = (BluetoothServerSocket) m.invoke(BluetoothAdapter.getDefaultAdapter(), port);

とにかく、これはおそらく手遅れであることはわかっていますが、将来誰かが同様の質問をするかもしれません.

于 2012-05-30T12:18:54.567 に答える