Android蓝牙连接两个或更多设备并发送数据 [英] Android bluetooth connect two or more devices and send data

查看:147
本文介绍了Android蓝牙连接两个或更多设备并发送数据的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我需要将3个不同的设备(客户端)连接到第四个设备(服务器). 这是我的服务器代码:

Hi I need to connect 3 different devices (Clients) to a fourth device (Server). Here is my server code:

public class MainServerActivity extends Activity {

    ArrayAdapter<String> listAdapter;
    ListView listView;
    TextView textViewTextoRecibido;
    BluetoothAdapter btADapter;
    Set<BluetoothDevice> devicesArray;
    ArrayList<String> pairedDevices;
    ArrayList<BluetoothDevice> devices;
    IntentFilter filter;
    BroadcastReceiver receiver;
    public AcceptThread acceptThread;
    protected static final int SUCCESS_CONNECT = 0;
    protected static final int MESSAGE_READ = 1;
    public static final UUID MY_UUID = UUID.fromString("00001101-0000-1000-8000-00805F9B34FB");
    public static final String NAME = "Tablet_Madre";
    //public static final UUID MY_UUID = UUID.fromString("00001105-0000-1000-8000-00805F9B34FB");
    ConnectedThread connectedThread;
    Handler mHandler = new Handler() {

        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            switch (msg.what) {
            case SUCCESS_CONNECT:

                connectedThread = new ConnectedThread((BluetoothSocket) msg.obj);
                Toast.makeText(getApplicationContext(), "Dispositivo conectado!", Toast.LENGTH_LONG).show();
                //String s = "successfully connected";
                //connectedThread.write(s.getBytes());
                break;

            case MESSAGE_READ:
                byte[] readBuf = (byte[]) msg.obj;
                String string = new String(readBuf);
                textViewTextoRecibido.setText(string);
                Toast.makeText(getApplicationContext(), "Llego el mensaje!!!!", Toast.LENGTH_LONG).show();
                break;

            }
        }
    };


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main_server);
        init();

        if (btADapter == null) {
            Toast.makeText(getApplicationContext(), "No bluetooth detectado", Toast.LENGTH_LONG).show();
            finish();
        } else {
            if (!btADapter.isEnabled()) {
                turnOnBT();
            }

            //getPairedDevices();
            //startDiscovery();
            aceptarConexiones();

        }
    }

    private void aceptarConexiones() {
        try {
             acceptThread = new AcceptThread();
            //acceptThread.run();

        } catch (Exception e) {
            System.out.print(e);
        }

    }

    @Override
    protected void onResume() {
        // TODO Auto-generated method stub
        super.onResume();
        try {
            acceptThread.run();
            //start();
        } catch (Exception e) {
            System.out.print(e);
        }
    }


    private void startDiscovery() {
        // TODO Auto-generated method stub
        btADapter.cancelDiscovery();
        btADapter.startDiscovery();
    }

    private void turnOnBT() {
        Intent intent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
        startActivityForResult(intent, 1);
    }


    /*Inicializa todos los componentes*/
    private void init() {
        listView = (ListView) findViewById(R.id.listView);
        //listView.setOnItemClickListener(this);
        textViewTextoRecibido = (TextView) findViewById(R.id.textViewTextoRecibido);
        listAdapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, 0);
        listView.setAdapter(listAdapter);
        btADapter = BluetoothAdapter.getDefaultAdapter();
        pairedDevices = new ArrayList<String>();
        filter = new IntentFilter(BluetoothDevice.ACTION_FOUND);
        devices = new ArrayList<BluetoothDevice>();
    }

    @Override
    protected void onPause() {
        // TODO Auto-generated method stub
        super.onPause();
        unregisterReceiver(receiver);
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        // TODO Auto-generated method stub
        super.onActivityResult(requestCode, resultCode, data);

        if (resultCode == RESULT_CANCELED) {
            Toast.makeText(getApplicationContext(), "Bluetooth debe estar encendido", Toast.LENGTH_SHORT).show();
            finish();
        }
    }

    public void enviarMensaje(View view){
        String s = "Campeon del Siglo";
        connectedThread.write(s.getBytes());
    }

    private class AcceptThread extends Thread{
        public final BluetoothServerSocket mmServerSocket;
        private int cantClientes;

        public AcceptThread() {
            BluetoothServerSocket tmp = null;

            // Create a new listening server socket
            try {
                tmp = btADapter.listenUsingRfcommWithServiceRecord(NAME, MY_UUID);
            } catch (IOException e) {
                //Log.e(TAG, "listen() failed", e);
            }
            mmServerSocket = tmp;
        }

        public void run(){
            BluetoothSocket socket = null;

            while(true){
                try{
                    socket = mmServerSocket.accept();
                    //No se llama al socket.connect() porque esto ya los conecta.
                } catch (IOException e){
                    break;
                }
                if(socket != null){
                    cantClientes = cantClientes + 1;
                }

                mHandler.obtainMessage(SUCCESS_CONNECT, socket).sendToTarget();

                if (socket != null){

                    //manageConnectedSocket(socket);
                    try {
                        mmServerSocket.close();
                    } catch (IOException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                    break;
                }
            }

        }

        public void cancel(){
            try{
                mmServerSocket.close();
            } catch(IOException e) {}
        }

    }

    private class ConnectedThread extends Thread {
        private final BluetoothSocket mmSocket;
        private final InputStream mmInStream;
        private final OutputStream mmOutStream;

        public ConnectedThread(BluetoothSocket socket) {
            mmSocket = socket;
            InputStream tmpIn = null;
            OutputStream tmpOut = null;

            // Get the input and output streams, using temp objects because
            // member streams are final
            try {
                tmpIn = socket.getInputStream();
                tmpOut = socket.getOutputStream();
            } catch (IOException e) { }

            mmInStream = tmpIn;
            mmOutStream = tmpOut;
        }

        public void run() {
            byte[] buffer = new byte[1024];  // buffer store for the stream
            int bytes; // bytes returned from read()

            // Keep listening to the InputStream until an exception occurs
            while (true) {
                try {
                    // Read from the InputStream
                    bytes = mmInStream.read(buffer);
                    // Send the obtained bytes to the UI activity
                    mHandler.obtainMessage(MESSAGE_READ, bytes, -1, buffer).sendToTarget();
                } catch (IOException e) {
                    break;
                }
            }
        }

        /* Call this from the main activity to send data to the remote device */
        public void write(byte[] bytes) {
            try {
                mmOutStream.write(bytes);
            } catch (IOException e) { }
        }

        /* Call this from the main activity to shutdown the connection */
        public void cancel() {
            try {
                mmSocket.close();
            } catch (IOException e) { }
        }
    }

}

这是我的客户代码:

public class MainClientActivity extends ActionBarActivity implements OnItemClickListener {


    ArrayAdapter<String> listAdapter;
    ListView listView;
    TextView textViewTextoRecibido;
    BluetoothAdapter btADapter;
    Set<BluetoothDevice> devicesArray;
    ArrayList<String> pairedDevices;
    ArrayList<BluetoothDevice> devices;
    IntentFilter filter;
    BroadcastReceiver receiver;
    protected static final int SUCCESS_CONNECT = 0;
    protected static final int MESSAGE_READ = 1;
    public static final UUID MY_UUID = UUID.fromString("00001101-0000-1000-8000-00805F9B34FB");
    public static final String NAME = "Tablet_Madre";
    //public static final UUID MY_UUID = UUID.fromString("00001105-0000-1000-8000-00805F9B34FB");
    ConnectedThread connectedThread;
    Handler mHandler = new Handler() {

        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            switch (msg.what) {
            case SUCCESS_CONNECT:

                connectedThread = new ConnectedThread((BluetoothSocket) msg.obj);
                Toast.makeText(getApplicationContext(), "Dispositivo conectado!", Toast.LENGTH_LONG).show();
                //String s = "successfully connected";
                //connectedThread.write(s.getBytes());
                break;

            case MESSAGE_READ:
                byte[] readBuf = (byte[]) msg.obj;
                String string = new String(readBuf);
                textViewTextoRecibido.setText(string);
                Toast.makeText(getApplicationContext(), "Llego el mensaje!!!!", Toast.LENGTH_LONG).show();
                break;

            }
        }
    };


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main_client);
        init();

        if (btADapter == null) {
            Toast.makeText(getApplicationContext(), "No bluetooth detectado", Toast.LENGTH_LONG).show();
            finish();
        } else {
            if (!btADapter.isEnabled()) {
                turnOnBT();
            }

            getPairedDevices();
            startDiscovery();
        }
    }

    /*Inicializa todos los componentes*/
    private void init() {
        listView = (ListView) findViewById(R.id.listView);
        listView.setOnItemClickListener(this);
        textViewTextoRecibido = (TextView) findViewById(R.id.textViewTextoRecibido);
        listAdapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, 0);
        listView.setAdapter(listAdapter);
        btADapter = BluetoothAdapter.getDefaultAdapter();
        pairedDevices = new ArrayList<String>();
        filter = new IntentFilter(BluetoothDevice.ACTION_FOUND);
        devices = new ArrayList<BluetoothDevice>();
        receiver = new BroadcastReceiver() {
            public void onReceive(Context context, Intent intent) {
                String action = intent.getAction();

                if (BluetoothDevice.ACTION_FOUND.equals(action)) {
                    BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
                    boolean yaEstaListado = false;
                    //Si encuentro uno, me fijo is ya esta en la lista de paireds
                    for (int j = 0; j < pairedDevices.size(); j++) {
                        if (device.getName().equals(pairedDevices.get(j))) {
                            yaEstaListado = true;
                            break;
                        }
                    }

                    if(!yaEstaListado){
                        listAdapter.add(device.getName() + "\n" + device.getAddress());
                        devices.add(device);
                    }

                } else if (BluetoothAdapter.ACTION_DISCOVERY_STARTED.equals(action)) {

                } else if (BluetoothAdapter.ACTION_DISCOVERY_FINISHED.equals(action)) {

                } else if (BluetoothAdapter.ACTION_STATE_CHANGED.equals(action)) {
                    if (btADapter.getState() == btADapter.STATE_OFF) {
                        turnOnBT();
                    }
                }
            }
        };

        registerReceiver(receiver, filter);
        filter = new IntentFilter(BluetoothAdapter.ACTION_DISCOVERY_STARTED);
        registerReceiver(receiver, filter);
        filter = new IntentFilter(BluetoothAdapter.ACTION_DISCOVERY_FINISHED);
        registerReceiver(receiver, filter);
        filter = new IntentFilter(BluetoothAdapter.ACTION_STATE_CHANGED);
        registerReceiver(receiver, filter);
    }

    private void startDiscovery() {

        btADapter.cancelDiscovery();
        btADapter.startDiscovery();
    }

    public void buscarDispositivo(View view){
        startDiscovery();
    }

    private void turnOnBT() {
        Intent intent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
        startActivityForResult(intent, 1);
    }

    private void getPairedDevices() {
        devicesArray = btADapter.getBondedDevices();
        if (devicesArray.size() > 0) {
            for (BluetoothDevice device : devicesArray) {
                pairedDevices.add(device.getName());
                listAdapter.add(device.getName() + " (Paired) " + "\n" + device.getAddress());
                devices.add(device);
            }
        }

    }


    @Override
    protected void onPause() {
        super.onPause();
        unregisterReceiver(receiver);
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);

        if (resultCode == RESULT_CANCELED) {
            Toast.makeText(getApplicationContext(), "Bluetooth debe estar encendido", Toast.LENGTH_SHORT).show();
            finish();
        }
    }

    @Override
    public void onItemClick(AdapterView<?> parent, View view, int position, long id) {

        try {
            if(btADapter.isDiscovering()){
                btADapter.cancelDiscovery();
            }
                BluetoothDevice selectedDevice = devices.get(position);
                ConnectThread connect = new ConnectThread(selectedDevice);
                connect.start();

        } catch (Exception e) {
            System.out.println(e);
        }
    }

    public void enviarMensaje(View view){
        String s = "Carbonero querido";
        connectedThread.write(s.getBytes());
    }

    private class ConnectThread extends Thread {

        private BluetoothSocket mmSocket = null;
        private final BluetoothDevice mmDevice;

        public ConnectThread(BluetoothDevice device) throws NoSuchMethodException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
            // Use a temporary object that is later assigned to mmSocket,
            // because mmSocket is final
            // BluetoothSocket tmp = null;
            mmDevice = device;

            // Get a BluetoothSocket to connect with the given BluetoothDevice
            try {
                // MY_UUID is the app's UUID string, also used by the server code
                mmSocket = mmDevice.createRfcommSocketToServiceRecord(MY_UUID);
                //Method m = mmDevice.getClass().getMethod("createInsecureRfcommSocket", new Class[] {int.class});
                //mmSocket = (BluetoothSocket) m.invoke(mmDevice, 1);
            } catch (IOException e) { }
        }

        public void run() {
            // Cancel discovery because it will slow down the connection
            btADapter.cancelDiscovery();

            try {
                // Connect the device through the socket. This will block
                // until it succeeds or throws an exception
                Thread.sleep(2000);
                mmSocket.connect();
                mHandler.obtainMessage(SUCCESS_CONNECT, mmSocket).sendToTarget();
            } catch (IOException connectException) {
                System.out.println(connectException);
                // Unable to connect; close the socket and get out
                try {
                    mmSocket.close();
                } catch (IOException closeException) {
                }
                return;
            } catch (InterruptedException e) {
                e.printStackTrace();
            }  catch (Exception e) {
                System.out.println(e);
            }
        }

        /** Will cancel an in-progress connection, and close the socket */
        public void cancel() {
            try {
                mmSocket.close();
            } catch (IOException e) {
            }
        }
    }

    private class ConnectedThread extends Thread {
        private final BluetoothSocket mmSocket;
        private final InputStream mmInStream;
        private final OutputStream mmOutStream;

        public ConnectedThread(BluetoothSocket socket) {
            mmSocket = socket;
            InputStream tmpIn = null;
            OutputStream tmpOut = null;

            // Get the input and output streams, using temp objects because
            // member streams are final
            try {
                tmpIn = socket.getInputStream();
                tmpOut = socket.getOutputStream();
            } catch (IOException e) { }

            mmInStream = tmpIn;
            mmOutStream = tmpOut;
        }

        public void run() {
            byte[] buffer = new byte[1024];  // buffer store for the stream
            int bytes; // bytes returned from read()

            // Keep listening to the InputStream until an exception occurs
            while (true) {
                try {
                    // Read from the InputStream
                    bytes = mmInStream.read(buffer);
                    // Send the obtained bytes to the UI activity
                    mHandler.obtainMessage(MESSAGE_READ, bytes, -1, buffer).sendToTarget();
                } catch (IOException e) {
                    break;
                }
            }
        }

        /* Call this from the main activity to send data to the remote device */
        public void write(byte[] bytes) {
            try {
                mmOutStream.write(bytes);
            } catch (IOException e) { }
        }

        /* Call this from the main activity to shutdown the connection */
        public void cancel() {
            try {
                mmSocket.close();
            } catch (IOException e) { }
        }
    }



}

我看到了一些答案,我认为我不清楚.现在,使用此代码,我无法连接两个设备,无法将数据从客户端发送到服务器并向后发送.问题的第二部分是我不知道如何从服务器端管理3个连接.给我一些想法,例子...

I saw some answers and i think i was not clear. Now with this code i cant connect two devices and send data from client to server and backwards. The second part of the problem is that i dont have any idea how can i manage 3 connections from server side. Give me some ideas, examples...

我有4个问题:

1)我需要创建一个线程,以便可以接受多个设备,因为现在正在接受一个设备,并且当我执行socket.accept()时,主线程处于冻结状态.

1) I need to create a thread so I can accept more than one device because now is accepting one and the main thread is freeze when I do socket.accept();

2)有时,de connection可以正常工作,但有时则不能.如果看到代码,则在连接时我会在两个设备上显示一条消息,有时会显示在一个设备中,有时会出现在另一个设备中.

2) Sometimes de connections works fine but sometimes no. If you see the code, I show a message in both devices when connect, sometimes appears in one and sometimes appears in the other.

3)当我建立连接时,当我尝试发送消息时,这是行不通的.我不知道是否必须在客户端和服务器中都创建一个ConnectionThread,但我都在两者中创建了,但是当我要在客户端编写时,connectionThread为null.

3) When I have a connection, when I try to send a message, this is not working. I don’t know if I have to create a ConnectionThread in the client and in the server, I create in both but when im going to write in client side, connectionThread is null.

4)如何管理服务器中的3个线程,每个客户端一个?

4) How can I manage 3 threads from server, one for each client?

我希望我很清楚……有些名字是西班牙语的.

I hope I was clear… Some names are in Spanish.

问候.

推荐答案

您一次只能在两个设备之间进行通信.

You can only communicate between two devices at one time.

如果您尝试使用此代码与第三台设备通信,它将无法正常工作.

If you try to communicate with a third device with this code, it will not work.

要在两个以上的设备之间进行通信,您需要在开始与客户端2的通信之前结束与客户端1的通信.这将需要更多的代码来以任何希望的方式管理您的连接,无论您是否希望将它们放置在其中.某种队列.

To communicate between more than two devices, you would need to end the communication with client 1 before commencing communication with client 2. This would require more code to manage your connections in whatever way you wish, whether you wanted to put them in some sort of queue.

这取决于您是要自动进行通信还是要手动启动和停止设备之间的通信,以了解如何进行管理.

It depends on if you want to automate your communication, or manually start and stop the communication between devices as to how you would manage this.

您可以遍历可发现的设备并启动和停止连接.这将涉及为蓝牙服务器调用和管理线程,以便关闭套接字,并为每个新连接进行新的初始化,以等待新连接.

You could loop through your discoverable devices and start and stop connections. This would involve calling and managing your threads for your bluetooth server, so that the sockets were closed and a new inialisation of waiting for a new connection occurs for each new connection.

这意味着您需要跟踪已连接的设备以​​及队列中的下一个设备,并进行错误处理以在服务器准备好接受来自该设备的连接时检查该设备是否可用.由于要确保设备的可用性,它相当复杂并且容易出错,您将需要仔细地遍历代码,并确保在服务器就绪时为不可用的设备做好准备,以便让服务器随后循环至下一个可用的设备.

It would mean that you would need to keep track of which device has been connected and which would be next in the queue, with error handling to check that the device is available when the server is ready to accept connection from this device. It is reasonably complicate and prone to error, due to ensuring the availability of devices and you would need to carefully step through your code and ensure you make provisions for devices not being available when the server is ready, so allowing the server to then loop to the next available device.

因此,对于服务器代码,基本连接和线程管理与到一个客户端的连接相同,但是由您的代码调用和管理,以遍历客户端设备或手动停止与一个客户端的通信设备并尝试与其他设备连接.

So in the case of the server code, the basic connection and thread management is the same as for connection to one client, but this is called and managed by your code to loop through client devices, or to manually stop communicating with one device and attempt connection with another device.

无论您是试图遍历一台以上的客户端设备还是仅处理一个客户端,客户端代码都不必更改.处理此类代码需要在您的服务器代码中进行管理.

The client code would not not have to change whether you are attempting to loop through more than one client device or just deal with one client. Handling this type of code would need to be managed within your server code.

首先,您需要清楚地了解如何仅在两个设备之间进行通信,并且不清楚您是否知道如何执行此操作.

Firstly you need to understand clearly how to just communicate between two devices and I am unclear if you know how to do this.

这篇关于Android蓝牙连接两个或更多设备并发送数据的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆