Подтвердить что ты не робот

Инициализация Android-соединения Bluetooth (клиент) на python (сервер) на ПК

Я пытаюсь отправить "helloWorld" (просто строку) с моего телефона Android (samsung galaxy s2) на python script на моем компьютере, работающем под Linux. Но я не могу заставить его работать. Ниже приведен код для приложения android (клиент) и python script (сервер). Bluetooth работает нормально на ПК и телефоне (например, я могу отправлять фотографии с телефона через BT). Когда я вызываю btSocket.connect(); в java-коде ниже он просто не соединяется. Должен ли я указывать порт для подключения, поскольку я указал порт для serverSocket? Любая помощь будет очень оценена.

public class BlueTooth_testActivity extends Activity {
    TextView header;
    Button discoverDevicesBtn;
    Button sendMsgBtn;
    Button closeBtn;
    EditText sendTxt;
    BluetoothAdapter btAdapter;
    BluetoothSocket btSocket;
    private static String btAdress = "00:10:60:D1:95:CD";
    private static final UUID MY_UUID = UUID.fromString("00001101-0000-1000-8000-00805F9B34FB");
    private OutputStream out;
    public BluetoothDevice device;
    private Boolean CONNECTED = false;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        //init layout parameters        
        header = (TextView) findViewById(R.id.text1);
        discoverDevicesBtn = (Button) findViewById(R.id.discBtn);
        sendMsgBtn = (Button) findViewById(R.id.sendButton);
        closeBtn = (Button) findViewById(R.id.closeButton);
        sendTxt = (EditText) findViewById(R.id.editText1);
        discoverDevicesBtn.setOnClickListener(discoverDeviceListener);
        sendMsgBtn.setOnClickListener(sendMsgListener);
        closeBtn.setOnClickListener(closeBtnListener);
        //init bluetooth
        btAdapter = BluetoothAdapter.getDefaultAdapter();
        if (btAdapter.isEnabled()) {
            Toast.makeText(this, "Bluetooth state:" + btAdapter.getState() + " Ok!", Toast.LENGTH_LONG).show();
        } else {
            Toast.makeText(this, "Bluetooth state:" + btAdapter.getState() + " Not ok!", Toast.LENGTH_LONG).show();
        }

    }

    private Button.OnClickListener discoverDeviceListener = new Button.OnClickListener() {@Override
        public void onClick(View v) {
            if (!CONNECTED) {
                device = btAdapter.getRemoteDevice(btAdress);
                header.append("\nRemote device: " + device.getName());
                try {
                    btSocket = device.createRfcommSocketToServiceRecord(MY_UUID);
                } catch (Exception e) {
                                    }
                header.append("\n createRfcommsockettoservice! ");
                btAdapter.cancelDiscovery();
                try {
                    btSocket.connect();
                    CONNECTED = true;
                    header.append("\n btSocket Created!");
                } catch (IOException e) {
                    Toast.makeText(getApplicationContext(), "Could not connect to socket", Toast.LENGTH_LONG);
                    try {
                        btSocket.close();
                    } catch (Exception b) {}
                }
            }

        }
    };


    private Button.OnClickListener sendMsgListener = new Button.OnClickListener() {@Override
        public void onClick(View v) {
            if (CONNECTED) {
                try {
                    out = btSocket.getOutputStream();
                    String msg = sendTxt.getText().toString();
                    byte[] msgBffr = msg.getBytes();
                    out.write(msgBffr);
                    Toast.makeText(getApplicationContext(), "Message sent", Toast.LENGTH_LONG).show();
                } catch (Exception a) {
                    Toast.makeText(getApplicationContext(), "Could not send msg", Toast.LENGTH_LONG).show();
                }
            } else {
                Toast.makeText(getApplicationContext(), "cant send msg, not connected", Toast.LENGTH_LONG).show();
            }

        }
    };


}  

(Я havnt потрудился включить остальную часть java-кода, поскольку проблема находится где-то в настройке соединения)

import bluetooth

name="bt_server"
target_name="siggen"
uuid="00001101-0000-1000-8000-00805F9B34FB"

def runServer():
serverSocket=bluetooth.BluetoothSocket(bluetooth.RFCOMM )
    port=bluetooth.PORT_ANY
    serverSocket.bind(("",port))
    print "Listening for connections on port: ", port   
    serverSocket.listen(1)
    port=serverSocket.getsockname()[1]
    inputSocket, address=serverSocket.accept()
    print "Got connection with" , address
    data=inputSocket.recv("1024")
    print "received [%s] \n " % data    
    inputSocket.close()
    serverSocket.close()  

runServer()  

.

4b9b3361

Ответ 1

Вам не нужно указывать порт, он должен просто подключить вас к первому открытому каналу RFComm. Одна вещь, которую я нашел для приложения Bluetooth, которое я сделал, заключается в том, что для того, чтобы он работал на моем телефоне, мне нужно вручную подключиться к компьютеру, на котором работает сервер, перед тем, как пытаться подключиться в приложении. То есть, я прохожу через Settings -> Wireless/Networks -> Bluetooth Settings -> <Find/Pair to Computer> и делаю все это до тех пор, пока уведомление не появится в моем системном трее. Затем, когда я пытаюсь подключиться к сокету через мое приложение, он работает. Я нахожу это странным, потому что мне нужно только прыгать через эти обручи на моем телефоне, а не на планшет, так что, возможно, это зависит от устройства.

Кроме того, вы захотите сделать материал соединения в отдельном Thread.

Ответ 2

Серверная часть

Я не понимаю, когда дело доходит до python, но похоже, что ваш фрагмент python не использует uuid где угодно. Например, pybluez repo имеет примерный сервер, где они используют uuid при вызове advertise_service, который, как вам кажется, отсутствует в вашем сниппет. Если бы вы сделали что-то подобное, ваш снипп мог бы выглядеть так:

import bluetooth

name="bt_server"
target_name="siggen"
uuid="00001101-0000-1000-8000-00805F9B34FB"

def runServer():
serverSocket=bluetooth.BluetoothSocket(bluetooth.RFCOMM )
    port=bluetooth.PORT_ANY
    serverSocket.bind(("",port))
    print "Listening for connections on port: ", port   
    serverSocket.listen(1)
    port=serverSocket.getsockname()[1]

    #the missing piece
    advertise_service( server_sock, "SampleServer",
                       service_id = uuid,
                       service_classes = [ uuid, bluetooth.SERIAL_PORT_CLASS ],
                       profiles = [ bluetooth.SERIAL_PORT_PROFILE ] 
                        )

    inputSocket, address=serverSocket.accept()
    print "Got connection with" , address
    data=inputSocket.recv("1024")
    print "received [%s] \n " % data    
    inputSocket.close()
    serverSocket.close()  

runServer()  

Клиент

BluetoothDevice.createRfcommSocketToServiceRecord() предназначен для создания "защищенных сокетов связи". Это то, что делает ваш сервер? Если нет, возможно, BluetoothDevice.createInsecureRfcommSocketToServiceRecord() - соответствующий вызов?

Ответ 3

Следуя рекомендациям, уже опубликованным, вот как я смог заставить ваш код работать, поскольку я ожидаю, что вы захотите его:

import bluetooth
    
    name="bt_server"
    target_name="test"
    # some random uuid, generated by https://www.famkruithof.net/uuid/uuidgen
    uuid="0fee0450-e95f-11e5-a837-0800200c9a66"
    
    def runServer():
        # you had indentation problems on this line:
        serverSocket=bluetooth.BluetoothSocket(bluetooth.RFCOMM )
        port=bluetooth.PORT_ANY
        serverSocket.bind(("",port))
        print "Listening for connections on port: ", port   

        # wait for a message to be sent to this socket only once
        serverSocket.listen(1)
        port=serverSocket.getsockname()[1]
    
        # you were 90% there, just needed to use the pyBluez command:
        bluetooth.advertise_service( serverSocket, "SampleServer",
                           service_id = uuid,
                           service_classes = [ uuid, bluetooth.SERIAL_PORT_CLASS ],
                           profiles = [ bluetooth.SERIAL_PORT_PROFILE ] 
                            )
    
        inputSocket, address=serverSocket.accept()
        print "Got connection with" , address
        data=inputSocket.recv(1024)
        print "received [%s] \n " % data    
        inputSocket.close()
        serverSocket.close()  
    
    runServer()  

Выполнить из командной строки, этот код будет ждать до тех пор, пока сообщение не будет отправлено через Bluetooth. Таким образом, при запуске этого кода все, что вам нужно сделать, - это подключить ваше устройство Android через Bluetooth, а затем отправить данные устройства (со ссылкой на тот же uuid, что и выше), с помощью любого метода Android-приложения, который вы разрабатывали, или что-то вроде этого gist (что я использовал): https://gist.github.com/tito/7432757