All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.github.hypfvieh.bluetooth.wrapper.BluetoothDevice Maven / Gradle / Ivy

Go to download

Java native bluetooth library which uses bluez via dbus (linux only). This is the OSGi compliant bundle of all required libraries in one bundle.

The newest version!
package com.github.hypfvieh.bluetooth.wrapper;

import com.github.hypfvieh.DbusHelper;
import org.bluez.Device1;
import org.bluez.GattService1;
import org.bluez.exceptions.*;
import org.freedesktop.dbus.connections.impl.DBusConnection;
import org.freedesktop.dbus.exceptions.DBusExecutionException;
import org.freedesktop.dbus.interfaces.DBusInterface;
import org.freedesktop.dbus.types.UInt16;
import org.freedesktop.dbus.types.UInt32;

import java.util.*;
import java.util.Map.Entry;
import java.util.concurrent.atomic.AtomicBoolean;

/**
 * Wrapper class which represents a remote bluetooth device.
 * @author hypfvieh
 *
 */
public class BluetoothDevice extends AbstractBluetoothObject {

    private final Device1 rawdevice;
    private final BluetoothAdapter adapter;

    private final AtomicBoolean servicesDiscovered = new AtomicBoolean();
    private final Map servicesByUuid = new LinkedHashMap<>();

    public BluetoothDevice(Device1 _device, BluetoothAdapter _adapter, String _dbusPath, DBusConnection _dbusConnection) {
        super(BluetoothDeviceType.DEVICE, _dbusConnection, _dbusPath);
        rawdevice = _device;
        adapter = _adapter;
    }

    /**
     * {@inheritDoc}
     */
    @Override
    protected Class getInterfaceClass() {
        return Device1.class;
    }

    /**
     * Return the list of available {@link BluetoothGattService}s.
* Will start a query if no list was gathered before.
* To re-scan for services use {@link #refreshGattServices()}. * @return List, maybe empty but never null */ public List getGattServices() { if (!servicesDiscovered.get()) { refreshGattServices(); } return new ArrayList<>(servicesByUuid.values()); } /** * Re-queries the list of available {@link BluetoothGattService}'s on this device. */ public void refreshGattServices() { servicesDiscovered.set(true); servicesByUuid.clear(); Set findNodes = DbusHelper.findNodes(getDbusConnection(), getDbusPath()); Map remoteObjects = getRemoteObjects(findNodes, getDbusPath(), GattService1.class); for (Entry entry : remoteObjects.entrySet()) { BluetoothGattService bluetoothGattService = new BluetoothGattService(entry.getValue(), this, entry.getKey(), getDbusConnection()); servicesByUuid.put(bluetoothGattService.getUuid(), bluetoothGattService); } } /** * Get the given {@link BluetoothGattService} instance by UUID. * @param _uuid uuid * @return {@link BluetoothGattService}, maybe null if not found */ public BluetoothGattService getGattServiceByUuid(String _uuid) { if (!servicesDiscovered.get()) { refreshGattServices(); } return servicesByUuid.get(_uuid); } /** * Get {@link BluetoothAdapter} object where this {@link BluetoothDevice} object belongs to. * @return adapter */ public BluetoothAdapter getAdapter() { return adapter; } /** * Get the raw {@link Device1} object wrapped by this {@link BluetoothDevice} object. * @return device */ public Device1 getRawDevice() { return rawdevice; } /** * True if incoming connections are rejected, false otherwise. * @return maybe null if feature is not supported */ public Boolean isBlocked() { return getTyped("Blocked", Boolean.class); } /** * From bluez Documentation: *

* If set to true any incoming connections from the
* device will be immediately rejected. Any device
* drivers will also be removed and no new ones will
* be probed as long as the device is blocked *

* @param _blocked set blocked status */ public void setBlocked(Boolean _blocked) { setTyped("Blocked", _blocked); } /** * True if the remote device is trusted, false otherwise. * @return maybe null if feature is not supported */ public Boolean isTrusted() { return getTyped("Trusted", Boolean.class); } /** * Set to true to trust the connected device, or to false if you don't.
* Default is false. * @param _trusted set trusted */ public void setTrusted(boolean _trusted) { setTyped("Trusted", _trusted); } /** * The current name alias for the remote device. * @return alias name */ public String getAlias() { return getTyped("Alias", String.class); } /** * From bluez Documentation: *

* The name alias for the remote device. The alias can
* be used to have a different friendly name for the
* remote device.
* In case no alias is set, it will return the remote
* device name. Setting an empty string as alias will
* convert it back to the remote device name. *

* @param _alias alias name to set */ public void setAlias(String _alias) { setTyped("Alias", _alias); } /** * The Advertising Data Flags of the remote device.
* EXPERIMENTAL * * @return byte array maybe null */ public byte[] getAdvertisingFlags() { List typed = getTyped("AdvertisingFlags", ArrayList.class); if (typed != null) { return byteListToByteArray(typed); } return null; } /** * From bluez Documentation: *

* List of 128-bit UUIDs that represents the available * remote services. *

* @return string array of UUIDs, maybe null */ public String[] getUuids() { List typed = getTyped("UUIDs", ArrayList.class); if (typed != null) { return typed.toArray(new String[]{}); } return null; } /** * True if device is connected, false otherwise. * @return maybe null if feature is not supported */ public Boolean isConnected() { return getTyped("Connected", Boolean.class); } /** * From bluez Documentation: *

* Set to true if the device only supports the pre-2.1
* pairing mechanism. This property is useful during
* device discovery to anticipate whether legacy or
* simple pairing will occur if pairing is initiated.
* Note that this property can exhibit false-positives
* in the case of Bluetooth 2.1 (or newer) devices that
* have disabled Extended Inquiry Response support. *

* @return maybe null if feature is not supported */ public Boolean isLegacyPairing() { return getTyped("LegacyPairing", Boolean.class); } /** * True if the device is currently paired with another device. False otherwise. * @return boolean, maybe null */ public Boolean isPaired() { return getTyped("Paired", Boolean.class); } /** * From bluez Documentation: *

* Indicate whether or not service discovery has been * resolved. *

* @return maybe null if feature is not supported */ public Boolean isServicesResolved() { return getTyped("ServicesResolved", Boolean.class); } /** * From bluez Documentation: *

* Service advertisement data. Keys are the UUIDs in * string format followed by its byte array value. *

* @return map of string/bytearray, maybe null */ @SuppressWarnings("unchecked") public Map getServiceData() { return getTyped("ServiceData", LinkedHashMap.class); } /** * From bluez Documentation: *

* Manufacturer specific advertisement data. Keys are * 16 bits Manufacturer ID followed by its byte array * value. *

* @return map of uint16/bytearray, maybe null */ @SuppressWarnings("unchecked") public Map getManufacturerData() { return getTyped("ManufacturerData", LinkedHashMap.class); } /** * From bluez Documentation: *

* Received Signal Strength Indicator of the remote * device (inquiry or advertising). *

* @return short, maybe null */ public Short getRssi() { return getTyped("RSSI", Short.class); } /** * From bluez Documentation: *

* Advertised transmitted power level (inquiry or * advertising). *

* @return short, maybe null */ public Short getTxPower() { return getTyped("TxPower", Short.class); } /** * Returns the remote devices bluetooth (MAC) address. * @return mac address, maybe null */ public String getAddress() { return getTyped("Address", String.class); } /** * From bluez Documentation: *

* Proposed icon name according to the freedesktop.org * icon naming specification. *

* @return icon name, maybe null */ public String getIcon() { return getTyped("Icon", String.class); } /** * From bluez Documentation: *

* Remote Device ID information in modalias format * used by the kernel and udev. *

* @return modalias string, maybe null */ public String getModAlias() { return getTyped("Modalias", String.class); } /** * Get the bluetooth device name.
* This may fail if you not connected to the device, or if the device does not support this operation.
* If no name could be retrieved, the alias will be used.

* * From bluez Documentation: *

* The Bluetooth remote name. This value can not be
* changed. Use the Alias property instead.
* This value is only present for completeness. It is
* better to always use the Alias property when
* displaying the devices name.
* If the Alias property is unset, it will reflect
* this value which makes it more convenient. *

* @return name, maybe null */ public String getName() { String name = null; try { name = getTyped("Name", String.class); } catch (DBusExecutionException _ex) { } if (name == null) { name = getAlias(); } return name; } /** * From bluez Documentation: *

* External appearance of device, as found on GAP service. *

* @return integer, maybe null */ public Integer getAppearance() { UInt16 typed = getTyped("Appearance", UInt16.class); return typed != null ? typed.intValue() : null; } /** * From bluez Documentation: *

* The Bluetooth class of device of the remote device. *

* @return integer, maybe null */ public Integer getBluetoothClass() { UInt32 typed = getTyped("Class", UInt32.class); return typed != null ? typed.intValue() : null; } /** * From bluez Documentation: *

* This is a generic method to connect any profiles
* the remote device supports that can be connected
* to and have been flagged as auto-connectable on
* our side. If only subset of profiles is already
* connected it will try to connect currently disconnected * ones. *

* @return true if connected, false otherwise */ public boolean connect() { try { rawdevice.Connect(); } catch (BluezNotReadyException _ex) { } catch (BluezFailedException _ex) { } catch (BluezAlreadyConnectedException _ex) { return true; } catch (BluezInProgressException _ex) { return false; } return isConnected(); } /** * From bluez Documentation: *

* This method gracefully disconnects all connected
* profiles and then terminates low-level ACL connection.
* ACL connection will be terminated even if some profiles
* were not disconnected properly e.g. due to misbehaving
* device.

* This method can be also used to cancel a preceding
* Connect call before a reply to it has been received. *

* @return true if disconnected false otherwise */ public boolean disconnect() { try { rawdevice.Disconnect(); return true; } catch (BluezNotConnectedException _ex) { } return !isConnected(); } /** * From bluez Documentation: *

* This method connects a specific profile of this
* device. The UUID provided is the remote service
* UUID for the profile. *

* * @param _uuid profile uuid * @return true if connected to given profile, false otherwise */ public boolean connectProfile(String _uuid) { try { rawdevice.ConnectProfile(_uuid); return true; } catch (BluezFailedException | BluezInProgressException | BluezInvalidArgumentsException | BluezNotAvailableException | BluezNotReadyException _ex) { return false; } } /** * From bluez Documentation: *

* This method disconnects a specific profile of
* this device. The profile needs to be registered
* client profile.

* There is no connection tracking for a profile, so
* as long as the profile is registered this will always
* succeed. *

* * @param _uuid profile uuid * @return true if profile disconnected, false otherwise */ public boolean disconnectProfile(String _uuid) { try { rawdevice.DisconnectProfile(_uuid); } catch (BluezFailedException | BluezInProgressException | BluezInvalidArgumentsException | BluezNotSupportedException _ex) { return false; } return true; } /** * From bluez Documentation: *

* This method will connect to the remote device,
* initiate pairing and then retrieve all SDP records
* (or GATT primary services).

* If the application has registered its own agent,
* then that specific agent will be used. Otherwise
* it will use the default agent.

* Only for applications like a pairing wizard it
* would make sense to have its own agent. In almost
* all other cases the default agent will handle
* this just fine.

* In case there is no application agent and also
* no default agent present, this method will fail. *

* @return true on successful pair, false otherwise */ public boolean pair() { try { rawdevice.Pair(); return true; } catch (BluezInvalidArgumentsException | BluezFailedException | BluezAuthenticationFailedException | BluezAlreadyExistsException | BluezAuthenticationCanceledException | BluezAuthenticationRejectedException | BluezAuthenticationTimeoutException | BluezConnectionAttemptFailedException _ex) { return false; } } /** * From bluez Documentation: *

* This method can be used to cancel a pairing
* operation initiated by the Pair method. *

* @return true if cancel succeeds, false otherwise */ public boolean cancelPairing() { try { rawdevice.CancelPairing(); return true; } catch (BluezDoesNotExistException | BluezFailedException _ex) { return false; } } @Override public String toString() { return getClass().getSimpleName() + " [device=" + rawdevice + ", adapter=" + adapter.getDbusPath() + ", getBluetoothType()=" + getBluetoothType().name() + ", getDbusPath()=" + getDbusPath() + "]"; } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy