如何获取有关Java中连接/配对蓝牙设备的信息?

时间:2016-12-18 00:22:39

标签: java macos bluetooth bluecove

我是蓝牙初学者。我正在尝试使用Bluecove和Java。我想与已经连接/配对到我的计算机的设备进行通信(例如检索设备电池电量)。问题是我找不到连接的设备。

我知道我可以拥有本地设备,检索设备等,但我无法连接设备。我正在使用代码found here

如果需要,我准备尝试另一个图书馆。

在BluetoothDevices.java中:

import javax.swing.*;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class BluetoothDevices extends javax.swing.JFrame {

    /* DefaultListModel to attach it with JList */
    private DefaultListModel defaultModel;
    /* Map to get device details list */
    private Map<String, List<String>> mapReturnResult = new HashMap<String, List<String>>();
    /* Map to identify device on user click of JList */
    private Map<Integer, List<String>> mapDevicePosition = new HashMap<Integer, List<String>>();

    public BluetoothDevices() {
        initComponents();
        defaultModel = new DefaultListModel();
    }

    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {

        jScrollPane1 = new javax.swing.JScrollPane();
        JListBluetoothDevices = new javax.swing.JList();
        lblDeviceName = new javax.swing.JLabel();
        lblRuntimeDeviceName = new javax.swing.JLabel();
        lblDeviceAddress = new javax.swing.JLabel();
        lblRuntimeDeviceAddress = new javax.swing.JLabel();
        lblServiceDetails = new javax.swing.JLabel();
        jScrollPane2 = new javax.swing.JScrollPane();
        JTextAreaServiceDetails = new javax.swing.JTextArea();

        setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
        setTitle("Bluecove Bluetooth Discovery");
        setResizable(false);
        addWindowListener(new java.awt.event.WindowAdapter() {
            public void windowOpened(java.awt.event.WindowEvent evt) {
                formWindowOpened(evt);
            }
        });

        JListBluetoothDevices.addMouseListener(new java.awt.event.MouseAdapter() {
            public void mouseClicked(java.awt.event.MouseEvent evt) {
                JListBluetoothDevicesMouseClicked(evt);
            }
        });
        jScrollPane1.setViewportView(JListBluetoothDevices);

        lblDeviceName.setText("Bluetooth Device Name");

        lblDeviceAddress.setText("Bluetooth Device Address");

        lblServiceDetails.setText("Service Details");

        JTextAreaServiceDetails.setColumns(20);
        JTextAreaServiceDetails.setRows(5);
        jScrollPane2.setViewportView(JTextAreaServiceDetails);

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
        getContentPane().setLayout(layout);
        layout.setHorizontalGroup(
                layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                        .addGroup(layout.createSequentialGroup()
                                .addContainerGap()
                                .addComponent(jScrollPane1, javax.swing.GroupLayout.PREFERRED_SIZE, 158, javax.swing.GroupLayout.PREFERRED_SIZE)
                                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                                        .addGroup(layout.createSequentialGroup()
                                                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                                                        .addComponent(lblDeviceName)
                                                        .addComponent(lblDeviceAddress))
                                                .addGap(73, 73, 73)
                                                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                                                        .addComponent(lblRuntimeDeviceAddress)
                                                        .addComponent(lblRuntimeDeviceName, javax.swing.GroupLayout.PREFERRED_SIZE, 144, javax.swing.GroupLayout.PREFERRED_SIZE)))
                                        .addComponent(lblServiceDetails)
                                        .addComponent(jScrollPane2, javax.swing.GroupLayout.DEFAULT_SIZE, 475, Short.MAX_VALUE))
                                .addContainerGap())
        );
        layout.setVerticalGroup(
                layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                        .addGroup(layout.createSequentialGroup()
                                .addContainerGap()
                                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                                        .addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 185, Short.MAX_VALUE)
                                        .addGroup(layout.createSequentialGroup()
                                                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                                                        .addComponent(lblDeviceName)
                                                        .addComponent(lblRuntimeDeviceName))
                                                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                                                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                                                        .addComponent(lblDeviceAddress)
                                                        .addComponent(lblRuntimeDeviceAddress))
                                                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                                                .addComponent(lblServiceDetails)
                                                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                                                .addComponent(jScrollPane2, 0, 0, Short.MAX_VALUE)))
                                .addContainerGap())
        );

        pack();
    }// </editor-fold>//GEN-END:initComponents

    /* Search for bluetooth device when window opened */
    private void formWindowOpened(java.awt.event.WindowEvent evt) {//GEN-FIRST:event_formWindowOpened
        int intDevicePosition = 0;
        JListBluetoothDevices.setModel(defaultModel);

        /* Create an object of ServicesSearch */
        ServicesSearch ss = new ServicesSearch();
        /* Get bluetooth device details */
        mapReturnResult = ss.getBluetoothDevices();

        /* Add devices in JList */
        for (Map.Entry<String, List<String>> entry : mapReturnResult.entrySet()) {
            defaultModel.addElement(entry.getValue().get(0));
            mapDevicePosition.put(intDevicePosition, entry.getValue());
            intDevicePosition++;
        }
    }//GEN-LAST:event_formWindowOpened

    /* On click of any item in List Box */
    private void JListBluetoothDevicesMouseClicked(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_JListBluetoothDevicesMouseClicked
  /* Get bluetooth device details from temporary list */
        List<String> tmpDeviceDetails = mapDevicePosition.get(JListBluetoothDevices.getSelectedIndex());
  /* Set bluetooth device name */
        lblRuntimeDeviceName.setText(tmpDeviceDetails.get(0));
  /* Set bluetooth device Address */
        lblRuntimeDeviceAddress.setText(tmpDeviceDetails.get(1));

        if (tmpDeviceDetails.size() > 2 && tmpDeviceDetails.get(2) != null) {
   /* Set bluetooth device service name and URL */
            JTextAreaServiceDetails.setText(tmpDeviceDetails.get(2));
        } else {
            JTextAreaServiceDetails.setText("Service not found");
        }
    }//GEN-LAST:event_JListBluetoothDevicesMouseClicked

    /**
     * @param args the command line arguments
     */
    public static void main(String args[]) {
        java.awt.EventQueue.invokeLater(new Runnable() {

            public void run() {
                 /* To set new look and feel */
                JFrame.setDefaultLookAndFeelDecorated(true);
                try {
                    /**
                     * Change look and feel of JFrame to Nimbus
                     * For other look and feel check
                     * http://www.javaquery.com/2013/06/how-to-applyset-up-swing-look-and-feel.html
                     */
                    UIManager.setLookAndFeel("com.sun.java.swing.plaf.nimbus.NimbusLookAndFeel");
                } catch (Exception ex) {
                    ex.printStackTrace();
                }
                /* Create an object of BluetoothDevices */
                BluetoothDevices bluetoothDevicesFrame = new BluetoothDevices();
                /* make BluetoothDevices visible */
                bluetoothDevicesFrame.setVisible(true);
            }
        });
    }

    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JList JListBluetoothDevices;
    private javax.swing.JTextArea JTextAreaServiceDetails;
    private javax.swing.JScrollPane jScrollPane1;
    private javax.swing.JScrollPane jScrollPane2;
    private javax.swing.JLabel lblDeviceAddress;
    private javax.swing.JLabel lblDeviceName;
    private javax.swing.JLabel lblRuntimeDeviceAddress;
    private javax.swing.JLabel lblRuntimeDeviceName;
    private javax.swing.JLabel lblServiceDetails;
    // End of variables declaration//GEN-END:variables
}

在ServicesSearch.java中:

import javax.bluetooth.*;
import javax.bluetooth.UUID;
import java.util.*;

public class ServicesSearch {

    /**
     * UUID used to find specific service supported by bluetooth device
     * https://www.bluetooth.org/en-us/specification/assigned-numbers/service-discovery
     * Find UUIDs for all types of bluetooth services.
     */
    /* To find push object service */
    private UUID OBEX_OBJECT_PUSH_PROFILE = new UUID(0x1105);
    /* To find file transfer service */
    private UUID OBEX_FILE_TRANSFER_PROFILE = new UUID(0x1106);
    /* To find hands free service */
    private UUID HANDS_FREE = new UUID(0x111E);
    /* Get URL attribute from bluetooth service */
    private int URL_ATTRIBUTE = 0X0100;

    public Map<String, List<String>> getBluetoothDevices() {
        /**
         * Find service on bluetooth device
         * Note: In following line you can use one service at a time. I'm new to bluetooth programming it might me wrong perception.
         * UUID[] searchUuidSet = new UUID[]{OBEX_FILE_TRANSGER_PROFILE};
         *
         * CORRECT: UUID[] searchUuidSet = new UUID[]{OBEX_FILE_TRANSGER_PROFILE};
         * WRONG: UUID[] searchUuidSet = new UUID[]{OBEX_FILE_TRANSGER_PROFILE, OBEX_OBJECT_PUSH_PROFILE};
         */
        /* Initialize UUID Array */
        UUID[] searchUuidSet = new UUID[]{HANDS_FREE};
        final Object serviceSearchCompletedEvent = new Object();
        int[] attrIDs = new int[]{URL_ATTRIBUTE};

        /* Create an object to get list of devices in range or paired */
        RemoteDeviceDiscovery remoteDeviceDiscovery = new RemoteDeviceDiscovery();
        /* Create map to return Bluetooth device address, name and URL */
        final Map<String, List<String>> mapReturnResult = new HashMap<String, List<String>>();

        try {
            /* Create an object of DiscoveryListener */
            DiscoveryListener listener = new DiscoveryListener() {

                /* To find bluetooth devices */
                public void deviceDiscovered(RemoteDevice btDevice, DeviceClass cod) {
                }

                /* To find bluetooth devices */
                public void inquiryCompleted(int discType) {
                }

                /* Find service URL of bluetooth device */
                public void servicesDiscovered(int transID, ServiceRecord[] servRecord) {
                    for (int i = 0; i < servRecord.length; i++) {
                        /* Find URL of bluetooth device */
                        String url = servRecord[i].getConnectionURL(ServiceRecord.NOAUTHENTICATE_NOENCRYPT, false);
                        if (url == null) {
                            continue;
                        }
                        String temporaryString = "";
                        /* Get object of bluetooth device */
                        RemoteDevice rd = servRecord[i].getHostDevice();
                        /* Get attribute from ServiceRecord */
                        DataElement serviceName = servRecord[i].getAttributeValue(URL_ATTRIBUTE);
                        if (serviceName != null) {
                            temporaryString = serviceName.getValue() + "\n" + url;
                            /* Put it in map */
                            mapReturnResult.get(rd.getBluetoothAddress()).add(temporaryString);
                        } else {
                            temporaryString = "Uknown service \n" + url;
                            /* Put it in map */
                            mapReturnResult.get(rd.getBluetoothAddress()).add(temporaryString);
                        }
                    }
                }

                public void serviceSearchCompleted(int transID, int respCode) {
                    /* Notify thread when search completed */
                    synchronized (serviceSearchCompletedEvent) {
                        serviceSearchCompletedEvent.notifyAll();
                    }
                }
            };

            /* Get list of bluetooth device from class RemoteDeviceDiscovery */
            for (Enumeration en = remoteDeviceDiscovery.getDevices().elements(); en.hasMoreElements();) {
                /* Get RemoteDevice object */
                RemoteDevice btDevice = (RemoteDevice) en.nextElement();
                /* Create list to return details */
                List<String> listDeviceDetails = new ArrayList<String>();

                try {
                    /* Add bluetooth device name and address in list */
                    listDeviceDetails.add(btDevice.getFriendlyName(false));
                    listDeviceDetails.add(btDevice.getBluetoothAddress());
                } catch (Exception e) {
                }

                /* Put bluetooth device details in map */
                mapReturnResult.put(btDevice.getBluetoothAddress(), listDeviceDetails);
                synchronized (serviceSearchCompletedEvent) {
                    LocalDevice.getLocalDevice().getDiscoveryAgent().searchServices(attrIDs, searchUuidSet, btDevice, listener);
                    serviceSearchCompletedEvent.wait();
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        /* Return bluetooth devices detail */
        return mapReturnResult;
    }
}

在RemoteDeviceDiscovery.java中:

import javax.bluetooth.*;
import java.io.IOException;
import java.util.Vector;

public class RemoteDeviceDiscovery {

    public Vector getDevices() {
        /* Create Vector variable */
        final Vector devicesDiscovered = new Vector();
        try {
            final Object inquiryCompletedEvent = new Object();
            /* Clear Vector variable */
            devicesDiscovered.clear();

            LocalDevice device = LocalDevice.getLocalDevice();

            System.out.println("Address : " + device.getBluetoothAddress());
            System.out.println("Name : " + device.getFriendlyName());
            System.out.println("Powered : " + device.isPowerOn());

            RemoteDevice[] devices = device.getDiscoveryAgent().retrieveDevices(DiscoveryAgent.PREKNOWN);

            for (RemoteDevice d : devices) {
                System.out.println("Adress : " + d.getBluetoothAddress());
                System.out.println("Name : " + d.getFriendlyName(false));
                System.out.println("Authenticated : " + d.isAuthenticated());
                System.out.println("Trusted : " + d.isTrustedDevice());
                System.out.println();
            }

            /* Create an object of DiscoveryListener */
            DiscoveryListener listener = new DiscoveryListener() {

                public void deviceDiscovered(RemoteDevice btDevice, DeviceClass cod) {
                    /* Get devices paired with system or in range(Without Pair) */
                    System.out.println("Address : " + btDevice.getBluetoothAddress());
                    try {
                        System.out.println("Name : " + btDevice.getFriendlyName(false));
                    } catch (IOException e) {
                    }
                    devicesDiscovered.addElement(btDevice);
                }

                public void inquiryCompleted(int discType) {
                    /* Notify thread when inquiry completed */
                    synchronized (inquiryCompletedEvent) {
                        inquiryCompletedEvent.notifyAll();
                    }
                }

                /* To find service on bluetooth */
                public void serviceSearchCompleted(int transID, int respCode) {
                }

                /* To find service on bluetooth */
                public void servicesDiscovered(int transID, ServiceRecord[] servRecord) {
                }
            };

            synchronized (inquiryCompletedEvent) {
                /* Start device discovery */
                boolean started = LocalDevice.getLocalDevice().getDiscoveryAgent().startInquiry(DiscoveryAgent.GIAC, listener);
                if (started) {
                    System.out.println("wait for device inquiry to complete...");
                    inquiryCompletedEvent.wait();
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        /* Return list of devices */
        return devicesDiscovered;
    }
}

如您所见,我尝试为LocalDevice获取所有PREKNOWN设备。在这里,我可以找到我已连接到计算机的所有蓝牙设备,但我不知道它是否已连接。

这是输出:

Address : 000000000003
Name : M
Powered : true

Adress : ACD1B8925628
Name : BLU-RAY HOME THEATRE SYSTEM
Authenticated : false
Trusted : false

Adress : A0143D6B170A
Name : Parrot ZIK 2.0 V2.05
Authenticated : false
Trusted : false

Adress : DC415F7780BB
Name : iPhone de Benjamin
Authenticated : false
Trusted : false

Adress : B0B28FD3668D
Name : LaBox6687
Authenticated : false
Trusted : false

wait for device inquiry to complete...
Address : 4D08B6DE2FDE
Name : LaBox6687
Address : A5362CC20702

我想使用的设备是 Parrot ZIK 2.0 V2.05

1 个答案:

答案 0 :(得分:3)

在链接库文档中,他们声称如下:

  

SmartGattLib是一个简化蓝牙工作的Java库   SMART设备(例如蓝牙4.0中的蓝牙低功耗)。它   提供所采用的GATT规范的所有UUID并且方便   解释特征的方法(例如Heart Rate,BatteryLevel)。

     

Implemented and tested characteristics

     
      
  • BatteryLevel
  •   
  • BodySensorLocation
  •   
  • HeartRateMeasurement
  •   
  • ManufacturerNameString
  •   

希望测试类中的这两个例子也会有所帮助。