Connect Android phone to paired bluetooth device like in settings

时间:2017-07-17 15:28:25

标签: android bluetooth

Looking at the various examples and questions regarding this, I simply want to make a connection programmatically to a previously paired bluetooth device. In all of the examples, it seems that you have to choose a profile. What I want to do is just like what happens when you go into settings>bluetooth and click on a paired device and it just connects. So far I can find the bonded device:

    BluetoothDevice result;

    BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter();
    Set<BluetoothDevice> devices = adapter.getBondedDevices();
    if (devices != null) {
        for (BluetoothDevice device : devices) {
            Log.i("TAG", "Device name:" + device.getName());
            if (deviceName.equals(device.getName())) {
                result = device;
                Log.i("TAG", "Found:" + result.getName() + " attempting to connect");
                break;
            }
        }
    }

Now I just want to attempt to connect to the device in the same manner as occurs from bluetooth settings page.

Jackabe, seems to be doing "something" here is what I get:

07-17 10:50:55.346 11494-11494/com.daford.autowificonnect I/BT: Attempting to connect to Protocol: 00001101-0000-1000-8000-00805f9b34fb
07-17 10:50:55.348 11494-11494/com.daford.autowificonnect W/BluetoothAdapter: getBluetoothService() called with no BluetoothManagerCallback
07-17 10:50:56.263 11494-11494/com.daford.autowificonnect W/BluetoothAdapter: getBluetoothService() called with no BluetoothManagerCallback
07-17 10:50:56.357 11494-11494/com.daford.autowificonnect I/messageFromSensor: AT+VGS=14

(here it hangs for a while then)

07-20 14:43:04.314 18793-28387/com.daford.bluetoothdetection I/BT: Attempting to connect to Protocol: 00001101-0000-1000-8000-00805f9b34fb
07-20 14:43:04.321 18793-28387/com.daford.bluetoothdetection W/BluetoothAdapter: getBluetoothService() called with no BluetoothManagerCallback
07-20 14:43:05.172 18793-28387/com.daford.bluetoothdetection W/BluetoothAdapter: getBluetoothService() called with no BluetoothManagerCallback
07-20 14:43:05.187 18793-28387/com.daford.bluetoothdetection W/BT: Fallback failed. Cancelling.
java.io.IOException: read failed, socket might closed or timeout, read ret: -1
at android.bluetooth.BluetoothSocket.readAll(BluetoothSocket.java:738)
at android.bluetooth.BluetoothSocket.waitSocketSignal(BluetoothSocket.java:697)
at android.bluetooth.BluetoothSocket.connect(BluetoothSocket.java:379)
at com.daford.bluetoothdetection.ConnectThread$FallbackBluetoothSocket.connect(ConnectThread.java:199)
at com.daford.bluetoothdetection.ConnectThread.connect(ConnectThread.java:66)
at com.daford.bluetoothdetection.MainActivity.connectToDevice(MainActivity.java:53)
at com.daford.bluetoothdetection.MainActivity$1.run(MainActivity.java:37)
at java.lang.Thread.run(Thread.java:761)
07-20 14:43:05.188 18793-28387/com.daford.bluetoothdetection W/System.err: java.io.IOException: Could not connect to device: 44:5E:F3:9F:35:1D
07-20 14:43:05.188 18793-28387/com.daford.bluetoothdetection W/System.err:     at com.daford.bluetoothdetection.ConnectThread.connect(ConnectThread.java:80)
07-20 14:43:05.194 18793-28387/com.daford.bluetoothdetection W/System.err:     at com.daford.bluetoothdetection.MainActivity.connectToDevice(MainActivity.java:53)
07-20 14:43:05.196 18793-28387/com.daford.bluetoothdetection W/System.err:     at com.daford.bluetoothdetection.MainActivity$1.run(MainActivity.java:37)
07-20 14:43:05.196 18793-28387/com.daford.bluetoothdetection W/System.err:     at java.lang.Thread.run(Thread.java:761)

1 个答案:

答案 0 :(得分:0)

此时此处:

BluetoothDevice device : devices

您现在已将配对设备作为设备对象。

我假设您现在将这些显示在某种列表中。如果这样做,则需要获取要连接的特定设备对象。通过使用int位置将onClickListener附加到列表视图来执行此操作。

要实际创建连接,还有很多工作要做。您现在必须使用套接字打开手机设备和蓝牙设备之间的通道。

有很多方法可以做到这一点,很多都是在这个网站上展示的。根据过去的经验,我创建了一个单独的类来处理这些连接。

import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothSocket;
import android.util.Log;

import com.smart.app.smartremote.Messages.DeviceMessageListener;

import org.json.JSONObject;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;

public class ConnectThread {

    private BluetoothSocketWrapper bluetoothSocket;
    private BluetoothDevice device;
    private boolean secure;
    private BluetoothAdapter adapter;
    private List<UUID> uuidCandidates;
    private int candidate;
    private DeviceMessageListener messageListener;

    /**
     * @param device the device
     * @param secure if connection should be done via a secure socket
     * @param adapter the Android BT adapter
     * @param uuidCandidates a list of UUIDs. if null or empty, the Serial PP id is used
     */

    /**
     * This class runs on a new thread and handles communication between the phone and bluetooth device.
     * We attempt to open a socket, and if that fails, open a backup socket.
     * The methods to send and recieve data are also handled here.
     * */
    public ConnectThread(BluetoothDevice device, boolean secure, BluetoothAdapter adapter,
                         List<UUID> uuidCandidates) {
        this.device = device;
        this.secure = secure;
        this.adapter = adapter;
        this.uuidCandidates = uuidCandidates;
        this.messageListener = new DeviceMessageListener();

        if (this.uuidCandidates == null || this.uuidCandidates.isEmpty()) {
            this.uuidCandidates = new ArrayList<UUID>();
            this.uuidCandidates.add(UUID.fromString("00001101-0000-1000-8000-00805F9B34FB"));
        }
    }

    public BluetoothSocketWrapper connect() throws IOException {
        boolean success = false;
        while (selectSocket()) {
            adapter.cancelDiscovery();
            try {
                bluetoothSocket.connect();
                success = true;
                break;
            } catch (IOException e) {
                //try the fallback
                try {
                    bluetoothSocket = new FallbackBluetoothSocket(bluetoothSocket.getUnderlyingSocket());
                    Thread.sleep(500);
                    bluetoothSocket.connect();
                    success = true;
                    break;
                } catch (FallbackException e1) {
                    Log.w("BT", "Could not initialize FallbackBluetoothSocket classes.", e);
                } catch (InterruptedException e1) {
                    Log.w("BT", e1.getMessage(), e1);
                } catch (IOException e1) {
                    Log.w("BT", "Fallback failed. Cancelling.", e1);
                }
            }
        }

        if (!success) {
            throw new IOException("Could not connect to device: "+ device.getAddress());
        }

        receiveData(bluetoothSocket);
        return bluetoothSocket;
    }

    private boolean selectSocket() throws IOException {
        if (candidate >= uuidCandidates.size()) {
            return false;
        }

        BluetoothSocket tmp;
        UUID uuid = uuidCandidates.get(candidate++);

        Log.i("BT", "Attempting to connect to Protocol: "+ uuid);
        if (secure) {
            tmp = device.createRfcommSocketToServiceRecord(uuid);
        } else {
            tmp = device.createInsecureRfcommSocketToServiceRecord(uuid);
        }
        bluetoothSocket = new NativeBluetoothSocket(tmp);

        return true;
    }

    public static interface BluetoothSocketWrapper {

        InputStream getInputStream() throws IOException;

        OutputStream getOutputStream() throws IOException;

        String getRemoteDeviceName();

        void connect() throws IOException;

        String getRemoteDeviceAddress();

        void close() throws IOException;

        BluetoothSocket getUnderlyingSocket();

    }

    public static class NativeBluetoothSocket implements BluetoothSocketWrapper {

        private BluetoothSocket socket;

        public NativeBluetoothSocket(BluetoothSocket tmp) {
            this.socket = tmp;
        }

        @Override
        public InputStream getInputStream() throws IOException {
            return socket.getInputStream();
        }

        @Override
        public OutputStream getOutputStream() throws IOException {
            return socket.getOutputStream();
        }

        @Override
        public String getRemoteDeviceName() {
            return socket.getRemoteDevice().getName();
        }

        @Override
        public void connect() throws IOException {
            socket.connect();
        }

        @Override
        public String getRemoteDeviceAddress() {
            return socket.getRemoteDevice().getAddress();
        }

        @Override
        public void close() throws IOException {
            socket.close();
        }

        @Override
        public BluetoothSocket getUnderlyingSocket() {
            return socket;
        }

    }

    public class FallbackBluetoothSocket extends NativeBluetoothSocket {

        private BluetoothSocket fallbackSocket;

        public FallbackBluetoothSocket(BluetoothSocket tmp) throws FallbackException {
            super(tmp);
            try
            {
                Class<?> clazz = tmp.getRemoteDevice().getClass();
                Class<?>[] paramTypes = new Class<?>[] {Integer.TYPE};
                Method m = clazz.getMethod("createRfcommSocket", paramTypes);
                Object[] params = new Object[] {Integer.valueOf(1)};
                fallbackSocket = (BluetoothSocket) m.invoke(tmp.getRemoteDevice(), params);
            }
            catch (Exception e)
            {
                throw new FallbackException(e);
            }
        }

        @Override
        public InputStream getInputStream() throws IOException {
            return fallbackSocket.getInputStream();
        }

        @Override
        public OutputStream getOutputStream() throws IOException {
            return fallbackSocket.getOutputStream();
        }


        @Override
        public void connect() throws IOException {
            fallbackSocket.connect();
        }


        @Override
        public void close() throws IOException {
            fallbackSocket.close();
        }

    }

    public static class FallbackException extends Exception {

        /**
         *
         */
        private static final long serialVersionUID = 1L;

        public FallbackException(Exception e) {
            super(e);
        }

    }

    /**
     * This method sends InfraRed command as JsonObjects
     * */
    public void sendData(JSONObject object) throws IOException{
        String jsonStr = object.toString();
        OutputStream socketOutputStream =  bluetoothSocket.getOutputStream();
        socketOutputStream.write(jsonStr.toString().getBytes("utf-8"));
        Log.i("sending", jsonStr);
    }

    /**
     * This method sends RF commands as Hex strings.
     * */
    public void sendRadio(String string) throws IOException{
        OutputStream socketOutputStream =  bluetoothSocket.getOutputStream();
        socketOutputStream.write(string.getBytes("utf-8"));
        Log.i("sending", string);
    }

    /**
     * This method handles messages being sent from the bluetooth device.
     * We log the messages and also send them to a message receiver so we can evaluate them.
     * The checkMessages() methods do this.
     * */
    public boolean receiveData(BluetoothSocketWrapper socket) throws IOException{
        InputStream socketInputStream =  socket.getInputStream();
        byte[] buffer = new byte[1024];
        int bytes;

        // Keep looping to listen for received messages
        while (true) {
            try {
                bytes = socketInputStream.read(buffer);            //read bytes from input buffer
                String readMessage = new String(buffer, 0, bytes);
                messageListener.checkMessages(readMessage);
                Log.i("messageFromSensor", readMessage);

            } catch (IOException e) {
                break;
            }
        }
        return false;
    }

    /**
     * This method should be called when we no longer need the connection.
     * */
    public void close() throws IOException {
        bluetoothSocket.close();
    }

您可以像我一样实例化此类,并调用.connect()和.sendData()等方法与设备进行通信。

public void connectToDevice(final BluetoothDevice device) {
        mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
        uuidCandidates = new ArrayList<>();
        uuidCandidates.add(UUID.fromString("00001101-0000-1000-8000-00805F9B34FB"));
        connectThread = new ConnectThread(device, true, mBluetoothAdapter, uuidCandidates);
        connectThread.connect();

    }