RFCOMM соединение между двумя устройствами Android? - PullRequest
1 голос
/ 26 июня 2011

У меня есть два устройства Android, к которым я хочу подключиться, используя Bluetooth, и передавать данные по каналу RFCOMM. У меня только одно устройство для приема данных, а другое устройство отправляет его ...

Используя этот код, я могу подключиться к другому устройству и начать прослушивание канала 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);

Они оба подключаются по каналу 2 RFCOMM, и оба видят друг друга, однако, второе устройство всегда остается заблокированным на BluetoothSocket sock = socket.accept();

.

Любая помощь?

1 Ответ

3 голосов
/ 30 мая 2012

ОК, я новичок, но я могу попытаться помочь.Итак, вот мой опыт, мне удалось соединить два устройства с помощью отражения.Мой телефон Android получает данные, используя метод 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, который я считаю, был занят, потому что когда я отправляю на него некоторые данные, я получаю 5 символов, начиная с ERR:).

Хотя, с другой стороны, мой поток все еще ждет ?!:) Это приводит нас к другому, что я заметил, порты (или каналы) не всегда отображаются на желаемое количество.Например, со мной часто случалось, что я хочу что-то отправить на 15-й порт, но на Android поток, ожидающий на 9-м порту, получил данные :) Поэтому я предлагаю проверить, какой порт действительно выделен!Вы можете достичь этого, используя код, который я разместил.И еще, здесь есть функция link to channelPicker, которая выбирает канал при использовании обычного API, если я не ошибаюсь, внутри некоторых констант должны представлять зарезервированные каналы.

Iтолько что заметил, мой код для регистрации порта немного отличается, вот как я это делаю:

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

В любом случае, я знаю, что это, вероятно, слишком поздно, но, возможно, у кого-то в будущем возникнет подобный вопрос.

...