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

org.fz.nettyx.util.BtFinder Maven / Gradle / Ivy

There is a newer version: 2.3.17-RELEASE
Show newest version
package org.fz.nettyx.util;

import cn.hutool.core.text.CharSequenceUtil;
import io.netty.util.internal.logging.InternalLogger;
import io.netty.util.internal.logging.InternalLoggerFactory;
import lombok.NoArgsConstructor;
import lombok.RequiredArgsConstructor;
import lombok.SneakyThrows;
import lombok.experimental.UtilityClass;

import javax.bluetooth.*;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.function.Predicate;

/**
 * @author fengbinbin
 * @version 1.0
 * @since 2024/5/30 11:04
 */

@UtilityClass
public final class BtFinder {

    private static final InternalLogger log = InternalLoggerFactory.getInstance(BtFinder.class);

    @NoArgsConstructor
    public static class DeviceFinder {

        private final Object             completedTag = new Object();
        private final List devices      = new ArrayList<>(64);
        private       DiscoveryListener  listener     = new DiscoveryListenerAdapter() {
            @Override
            public void deviceDiscovered(RemoteDevice btDevice, DeviceClass cod) {
                devices.add(btDevice);
            }

            @Override
            public void inquiryCompleted(int discType) {
                synchronized (completedTag) {
                    completedTag.notifyAll();
                }
            }
        };

        public DeviceFinder(DiscoveryListener listener) {
            this.listener = listener;
        }

        public List getDevices() {
            return getDevices(device -> true);
        }

        @SneakyThrows({ InterruptedException.class })
        public List getDevices(Predicate condition) {
            try {
                devices.clear();

                synchronized (completedTag) {
                    DiscoveryAgent discoveryAgent = LocalDevice.getLocalDevice().getDiscoveryAgent();
                    boolean        started        = discoveryAgent.startInquiry(DiscoveryAgent.GIAC, listener);

                    if (started) {
                        completedTag.wait();
                        discoveryAgent.cancelInquiry(listener);
                    }
                }
                devices.removeIf(condition.negate());
            } catch (BluetoothStateException stateException) {
                log.error("bluetooth state is illegal, please check");
                return Collections.emptyList();
            }

            return devices;
        }
    }

    @RequiredArgsConstructor
    public static class ServiceFinder {

        private static final int               DEFAULT_ATTR_ID = 0x0100;
        private final        Object            completedTag    = new Object();
        private final        List      services        = new ArrayList<>(32);
        private              DiscoveryListener listener        = new DiscoveryListenerAdapter() {
            @Override
            public void servicesDiscovered(int transID, ServiceRecord[] servRecord) {
                for (ServiceRecord serviceRecord : servRecord) {
                    String url = serviceRecord.getConnectionURL(ServiceRecord.NOAUTHENTICATE_NOENCRYPT, false);
                    if (CharSequenceUtil.isEmpty(url)) {
                        continue;
                    }
                    services.add(url);
                }
            }

            @Override
            public void serviceSearchCompleted(int transID, int respCode) {
                synchronized (completedTag) {
                    completedTag.notifyAll();
                }
            }
        };

        public ServiceFinder(DiscoveryListener listener) {
            this.listener = listener;
        }

        public List getServices(RemoteDevice btDevice, String serviceUUID) throws IOException, InterruptedException {
            return getServices(btDevice, serviceUUID, s -> true);
        }

        public List getServices(RemoteDevice btDevice, String serviceUUID, Predicate condition) throws IOException, InterruptedException {
            UUID[] searchUuidSet = new UUID[]{ new UUID(serviceUUID, false) };

            synchronized (completedTag) {
                LocalDevice.getLocalDevice().getDiscoveryAgent().searchServices(new int[]{ DEFAULT_ATTR_ID }, searchUuidSet, btDevice, listener);
                completedTag.wait();
            }

            services.removeIf(condition.negate());

            return services;
        }
    }

    abstract static class DiscoveryListenerAdapter implements DiscoveryListener {
        @Override
        public void deviceDiscovered(RemoteDevice btDevice, DeviceClass cod) {
        }

        @Override
        public void servicesDiscovered(int transID, ServiceRecord[] servRecord) {
        }

        @Override
        public void serviceSearchCompleted(int transID, int respCode) {
        }

        @Override
        public void inquiryCompleted(int discType) {
        }
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy