java - 如何在Ubuntu中运行TinyB库?

标签 java intellij-idea bluetooth bluetooth-lowenergy ubuntu-16.04

我尝试从存储库安装tinyb:https://github.com/intel-iot-devkit/tinyb

我已经构建了tinyb.jar 并将其作为库添加到IntellJ 项目中。

我运行了tinyb示例中提供的示例代码,并进行了一些小修改(在蓝牙管理器初始化之前注释掉了主方法中的一些代码):

import tinyb.*;
import java.util.*;
import java.util.concurrent.locks.*;
import java.util.concurrent.TimeUnit;

public class HelloTinyB {
private static final float SCALE_LSB = 0.03125f;
static boolean running = true;

static void printDevice(BluetoothDevice device) {
    System.out.print("Address = " + device.getAddress());
    System.out.print(" Name = " + device.getName());
    System.out.print(" Connected = " + device.getConnected());
    System.out.println();
}

static float convertCelsius(int raw) {
    return raw / 128f;
}

/*
 * After discovery is started, new devices will be detected. We can get a list of all devices through the manager's
 * getDevices method. We can the look through the list of devices to find the device with the MAC which we provided
 * as a parameter. We continue looking until we find it, or we try 15 times (1 minutes).
 */
static BluetoothDevice getDevice(String address) throws InterruptedException {
    BluetoothManager manager = BluetoothManager.getBluetoothManager();
    BluetoothDevice sensor = null;
    for (int i = 0; (i < 15) && running; ++i) {
        List<BluetoothDevice> list = manager.getDevices();
        if (list == null)
            return null;

        for (BluetoothDevice device : list) {
            printDevice(device);
            /*
             * Here we check if the address matches.
             */
            if (device.getAddress().equals(address))
                sensor = device;
        }

        if (sensor != null) {
            return sensor;
        }
        Thread.sleep(4000);
    }
    return null;
}

/*
 * Our device should expose a temperature service, which has a UUID we can find out from the data sheet. The service
 * description of the SensorTag can be found here:
 * http://processors.wiki.ti.com/images/a/a8/BLE_SensorTag_GATT_Server.pdf. The service we are looking for has the
 * short UUID AA00 which we insert into the TI Base UUID: f000XXXX-0451-4000-b000-000000000000
 */
static BluetoothGattService getService(BluetoothDevice device, String UUID) throws InterruptedException {
    System.out.println("Services exposed by device:");
    BluetoothGattService tempService = null;
    List<BluetoothGattService> bluetoothServices = null;
    do {
        bluetoothServices = device.getServices();
        if (bluetoothServices == null)
            return null;

        for (BluetoothGattService service : bluetoothServices) {
            System.out.println("UUID: " + service.getUUID());
            if (service.getUUID().equals(UUID))
                tempService = service;
        }
        Thread.sleep(4000);
    } while (bluetoothServices.isEmpty() && running);
    return tempService;
}

static BluetoothGattCharacteristic getCharacteristic(BluetoothGattService service, String UUID) {
    List<BluetoothGattCharacteristic> characteristics = service.getCharacteristics();
    if (characteristics == null)
        return null;

    for (BluetoothGattCharacteristic characteristic : characteristics) {
        if (characteristic.getUUID().equals(UUID))
            return characteristic;
    }
    return null;
}

/*
 * This program connects to a TI SensorTag 2.0 and reads the temperature characteristic exposed by the device over
 * Bluetooth Low Energy. The parameter provided to the program should be the MAC address of the device.
 *
 * A wiki describing the sensor is found here: http://processors.wiki.ti.com/index.php/CC2650_SensorTag_User's_Guide
 *
 * The API used in this example is based on TinyB v0.3, which only supports polling, but v0.4 will introduce a
 * simplied API for discovering devices and services.
 */
public static void main(String[] args) throws InterruptedException {

//        if (args.length < 1) {
//            System.err.println("Run with <device_address> argument");
//            System.exit(-1);
//        }

    /*
     * To start looking of the device, we first must initialize the TinyB library. The way of interacting with the
     * library is through the BluetoothManager. There can be only one BluetoothManager at one time, and the
     * reference to it is obtained through the getBluetoothManager method.
     */
    BluetoothManager manager = BluetoothManager.getBluetoothManager();

    /*
     * The manager will try to initialize a BluetoothAdapter if any adapter is present in the system. To initialize
     * discovery we can call startDiscovery, which will put the default adapter in discovery mode.
     */
    boolean discoveryStarted = manager.startDiscovery();

    System.out.println("The discovery started: " + (discoveryStarted ? "true" : "false"));
    BluetoothDevice sensor = getDevice(args[0]);

    /*
     * After we find the device we can stop looking for other devices.
     */
    try {
        manager.stopDiscovery();
    } catch (BluetoothException e) {
        System.err.println("Discovery could not be stopped.");
    }

    if (sensor == null) {
        System.err.println("No sensor found with the provided address.");
        System.exit(-1);
    }

    System.out.print("Found device: ");
    printDevice(sensor);

    if (sensor.connect())
        System.out.println("Sensor with the provided address connected");
    else {
        System.out.println("Could not connect device.");
        System.exit(-1);
    }

    Lock lock = new ReentrantLock();
    Condition cv = lock.newCondition();

    Runtime.getRuntime().addShutdownHook(new Thread() {
        public void run() {
            running = false;
            lock.lock();
            try {
                cv.signalAll();
            } finally {
                lock.unlock();
            }

        }
    });


    BluetoothGattService tempService = getService(sensor, "f000aa00-0451-4000-b000-000000000000");

    if (tempService == null) {
        System.err.println("This device does not have the temperature service we are looking for.");
        sensor.disconnect();
        System.exit(-1);
    }
    System.out.println("Found service " + tempService.getUUID());

    BluetoothGattCharacteristic tempValue = getCharacteristic(tempService, "f000aa01-0451-4000-b000-000000000000");
    BluetoothGattCharacteristic tempConfig = getCharacteristic(tempService, "f000aa02-0451-4000-b000-000000000000");
    BluetoothGattCharacteristic tempPeriod = getCharacteristic(tempService, "f000aa03-0451-4000-b000-000000000000");

    if (tempValue == null || tempConfig == null || tempPeriod == null) {
        System.err.println("Could not find the correct characteristics.");
        sensor.disconnect();
        System.exit(-1);
    }

    System.out.println("Found the temperature characteristics");

    /*
     * Turn on the Temperature Service by writing 1 in the configuration characteristic, as mentioned in the PDF
     * mentioned above. We could also modify the update interval, by writing in the period characteristic, but the
     * default 1s is good enough for our purposes.
     */
    byte[] config = { 0x01 };
    tempConfig.writeValue(config);

    /*
     * Each second read the value characteristic and display it in a human readable format.
     */
    while (running) {
        byte[] tempRaw = tempValue.readValue();
        System.out.print("Temp raw = {");
        for (byte b : tempRaw) {
            System.out.print(String.format("%02x,", b));
        }
        System.out.print("}");

        /*
         * The temperature service returns the data in an encoded format which can be found in the wiki. Convert the
         * raw temperature format to celsius and print it. Conversion for object temperature depends on ambient
         * according to wiki, but assume result is good enough for our purposes without conversion.
         */
        int objectTempRaw = (tempRaw[0] & 0xff) | (tempRaw[1] << 8);
        int ambientTempRaw = (tempRaw[2] & 0xff) | (tempRaw[3] << 8);

        float objectTempCelsius = convertCelsius(objectTempRaw);
        float ambientTempCelsius = convertCelsius(ambientTempRaw);

        System.out.println(
                String.format(" Temp: Object = %fC, Ambient = %fC", objectTempCelsius, ambientTempCelsius));

        lock.lock();
        try {
            cv.await(1, TimeUnit.SECONDS);
        } finally {
            lock.unlock();
        }
    }
    sensor.disconnect();

}
}

运行时出现以下堆栈错误(下图):

enter image description here

我尝试了很多解决方案,例如此修复: https://github.com/intel-iot-devkit/tinyb/issues/75

但给了我同样的错误。

感谢任何提示和技巧。

最佳答案

我发现,为了让tinyb正常工作,它需要从构建中生成的库文件。对我来说,它位于/home/user/Desktop/tinyb-master/src 中,这些文件位于文件夹 (libtinyb.so, libtinyb.so.0, libtinyb.so.0.5 .0) 以及 :/home/user/Desktop/tinyb-master/java/jni 中,这些文件位于文件夹 (libjavatiny.so, libjavatinyb.so .0、libjavatinyb.so.0.5.0)。这两个路径必须添加到VM选项中,如下所示:
-Djava.library.path=/home/user/Desktop/tinyb-master/java/jni:/home/user/Desktop/tinyb-master/src 并且也不要忘记 tinyb.jar (../tinyb-master/java/tinyb.jar) 需要在java项目中添加。

关于java - 如何在Ubuntu中运行TinyB库?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49963411/

相关文章:

java - 如何打印数组直到有值。而不是完整数组?

java - 数据库中的编码问题

java - 当屏幕锁定时,Selenium 执行停止

java - 有没有办法在 IntelliJ IDEA 中编译所有的 JSP 文件?

intellij-idea - IntelliJ : “java connot find symbol class” when class is in same package

java - 如何将用户时区添加到 utc 日期

android - 从IntelliJ/Android Studio运行Gradle时$ PATH设置不正确

ios - 如果我的 iOS 设备获得 MFI 许可证,我是否可以将其与自定义蓝牙设备配对?

android - AGAIN : read failed, 套接字可能关闭或超时

android - 在 Android 中以编程方式连接到支持蓝牙的条码扫描仪