蓝牙,是一种支持设备短距离通信(一般10m内)的无线电技术,能在包括移动电话、PDA、无线耳机、笔记本电脑、相关外设等众多设备之间,通过蓝牙设备之间的无线通信实现数据传输,实现数据传输,音频传输,文件传输,图片传输等多种应用的无线信息交换。利用“蓝牙”技术,能够有效地简化移动通信终端设备之间的通信,也能够成功地简化设备与因特网Internet之间的通信,从而数据传输变得更加迅速高效,为无线通信拓宽道路。蓝牙技术是一种无线数据和语音通信开放的全球规范,它是基于低成本的近距离无线连接,为固定和移动设备建立通信环境的一种特殊的近距离无线技术连接。目前,越来越多的企业采用蓝牙交互技术来实现自己的产品。
Java是世界上最流行的编程语言之一。Java具有平台无关性、对象化编程、简单易用、可扩展性等特点,因此目前已广泛应用于企业和互联网领域。Java还提供了很好的蓝牙接口,可以帮助企业快速开发蓝牙交互应用。Java的蓝牙接口是基于JSR-82标准实现的,这个标准允许JAVA应用程序访问蓝牙网络的API。与其他大多数蓝牙接口不同,JSR-82可以在任意实现了JSR-82标准的蓝牙设备间进行通讯,这就保证了兼容性和灵活性。
蓝牙技术规定每一对设备之间进行蓝牙通讯时,必须一个为主角色,另一为从角色,才能进行通信,通信时,必须由主端进行查找,发起配对,建链成功后,双方即可收发数据。
蓝牙主端设备发起呼叫,首先是查找,找出周围处于可被查找的蓝牙设备。主端设备找到从端蓝牙设备后,与从端蓝牙设备进行配对,此时需要输入从端设备的PIN码,也有设备不需要输入PIN码。
配对完成后,从端蓝牙设备会记录主端设备的信任信息,此时主端即可向从端设备发起呼叫,已配对的设备在下次呼叫时,不再需要重新配对。
net.sf.bluecove
bluecove
2.1.0
public class BluetoothServer implements Runnable {
//本机蓝牙设备
private LocalDevice local = null;
// 流连接
private StreamConnection streamConnection = null;
// 输入流
private InputStream inputStream;
private OutputStream outputStream;
//接入通知
private StreamConnectionNotifier notifier;
//线程池
private final static ExecutorService service = Executors.newCachedThreadPool();
public String serverName;
public String serverUUID;
private OnServerListener mServerListener;
public interface OnServerListener {
void onConnected(InputStream inputStream, OutputStream outputStream);
void onDisconnected();
void onClose();
}
public BluetoothServer(String serverUUID, String serverName) {
this.serverUUID = serverUUID;
this.serverName = serverName;
}
public void start() {
try {
local = LocalDevice.getLocalDevice();
if (!local.setDiscoverable(DiscoveryAgent.GIAC)) {
System.out.println("请将蓝牙设置为可被发现");
}
/**
* 作为服务端,被请求 ";name="+serverName;
*/
String url = "btspp://localhost:" + serverUUID;
notifier = (StreamConnectionNotifier) Connector.open(url);
service.submit(this);
} catch (IOException e) {
System.out.println(e.getMessage());;
}
}
public OnServerListener getServerListener() {
return mServerListener;
}
public void setServerListener(OnServerListener mServerListener) {
this.mServerListener = mServerListener;
}
@Override
public void run() {
try {
//阻塞的,等待设备连接
streamConnection = notifier.acceptAndOpen();
inputStream = streamConnection.openInputStream();
outputStream = streamConnection.openOutputStream();
if (mServerListener != null) {
mServerListener.onConnected(inputStream, outputStream);
}
} catch (IOException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
} finally {
}
}
}
public class BluetoothClient {
private StreamConnection streamConnection;
private OnDiscoverListener onDiscoverListener = null;
private OnClientListener onClientListener = null;
public interface OnClientListener {
void onConnected(InputStream inputStream, OutputStream outputStream);
void onConnectionFailed();
void onDisconnected();
void onClose();
}
public interface OnDiscoverListener {
void onDiscover(RemoteDevice remoteDevice);
}
public BluetoothClient() {
}
public OnDiscoverListener getOnDiscoverListener() {
return onDiscoverListener;
}
public void setOnDiscoverListener(OnDiscoverListener onDiscoverListener) {
this.onDiscoverListener = onDiscoverListener;
}
public OnClientListener getClientListener() {
return onClientListener;
}
public void setClientListener(OnClientListener onClientListener) {
this.onClientListener = onClientListener;
}
public void find() throws IOException, InterruptedException {
//附近所有的蓝牙设备,必须先执行 runDiscovery
Set devicesDiscovered = RemoteDeviceDiscovery.getDevices();
Iterator itr = devicesDiscovered.iterator();
//连接
while (itr.hasNext()) {
RemoteDevice remoteDevice = itr.next();
onDiscoverListener.onDiscover(remoteDevice);
}
}
public void startClient(RemoteDevice remoteDevice, String serviceUUID) throws IOException, InterruptedException {
String url = RemoteDeviceDiscovery.searchService(remoteDevice, serviceUUID);
streamConnection = (StreamConnection) Connector.open(url);
if (this.onClientListener != null) {
this.onClientListener.onConnected(streamConnection.openInputStream(), streamConnection.openOutputStream());
}
}
}
public class RemoteDeviceDiscovery {
public final static Set devicesDiscovered = new HashSet();
public final static Vector serviceFound = new Vector();
final static Object serviceSearchCompletedEvent = new Object();
final static Object inquiryCompletedEvent = new Object();
private static DiscoveryListener listener = new DiscoveryListener() {
public void inquiryCompleted(int discType) {
System.out.println("#" + "搜索完成");
synchronized (inquiryCompletedEvent) {
inquiryCompletedEvent.notifyAll();
}
}
@Override
public void deviceDiscovered(RemoteDevice remoteDevice, DeviceClass deviceClass) {
devicesDiscovered.add(remoteDevice);
try {
System.out.println("#发现设备" + remoteDevice.getFriendlyName(false));
} catch (IOException e) {
e.printStackTrace();
}
}
@Override
public void servicesDiscovered(int transID, ServiceRecord[] servRecord) {
for (int i = 0; i < servRecord.length; i++) {
String url = servRecord[i].getConnectionURL(ServiceRecord.NOAUTHENTICATE_NOENCRYPT, false);
if (url == null) {
continue;
}
serviceFound.add(url);
DataElement serviceName = servRecord[i].getAttributeValue(0x0100);
if (serviceName != null) {
System.out.println("service " + serviceName.getValue() + " found " + url);
} else {
System.out.println("service found " + url);
}
}
System.out.println("#" + "servicesDiscovered");
}
@Override
public void serviceSearchCompleted(int arg0, int arg1) {
System.out.println("#" + "serviceSearchCompleted");
synchronized(serviceSearchCompletedEvent){
serviceSearchCompletedEvent.notifyAll();
}
}
};
private static void findDevices() throws IOException, InterruptedException {
devicesDiscovered.clear();
synchronized (inquiryCompletedEvent) {
LocalDevice ld = LocalDevice.getLocalDevice();
System.out.println("#本机蓝牙名称:" + ld.getFriendlyName());
boolean started = LocalDevice.getLocalDevice().getDiscoveryAgent().startInquiry(DiscoveryAgent.GIAC,listener);
if (started) {
System.out.println("#" + "等待搜索完成...");
inquiryCompletedEvent.wait();
LocalDevice.getLocalDevice().getDiscoveryAgent().cancelInquiry(listener);
System.out.println("#发现设备数量:" + devicesDiscovered.size());
}
}
}
public static Set getDevices() throws IOException, InterruptedException {
findDevices();
return devicesDiscovered;
}
public static String searchService(RemoteDevice btDevice, String serviceUUID) throws IOException, InterruptedException {
UUID[] searchUuidSet = new UUID[] { new UUID(serviceUUID, false) };
int[] attrIDs = new int[] {
// Service name
0x0100
};
synchronized(serviceSearchCompletedEvent) {
System.out.println("search services on " + btDevice.getBluetoothAddress() + " " + btDevice.getFriendlyName(false));
LocalDevice.getLocalDevice().getDiscoveryAgent().searchServices(attrIDs, searchUuidSet, btDevice, listener);
serviceSearchCompletedEvent.wait();
}
if (serviceFound.size() > 0) {
return serviceFound.elementAt(0);
} else {
return "";
}
}
}
@Test
public void test(){
final String serverName = "Bluetooth Server Test";
final String serverUUID = "1000110100001000800000805F9B34FB"; //根据需要自定义
BluetoothServer server = new BluetoothServer(serverUUID, serverName);
server.setServerListener(new BluetoothServer.OnServerListener() {
@Override
public void onConnected(InputStream inputStream, OutputStream outputStream) {
System.out.printf("Connected");
//添加通信代码
}
@Override
public void onDisconnected() {
}
@Override
public void onClose() {
}
});
server.start();
}
Connected to the target VM, address: '127.0.0.1:8442', transport: 'socket'
Native Library intelbth_x64 not available
Native Library bluecove_x64 not available
BlueCove libraries not available
Disconnected from the target VM, address: '127.0.0.1:8442', transport: 'socket'
没有找到_64的包。
看看导包的版本
官网:BlueCove - BlueCove JSR-82 project
下载地址:https://sourceforge.net/projects/bluecove/files/
ps:下面自己测试吧。
JNI,Java Native Interface,主要是通过读取其他底层语言的文件,转换成Java的类,操作设备。
另外还有连接打印机、pos机等,也是使用Java的JNI调用其他底层语言的文件,如打印机使用jacob读取dll文件、可实现无接触操作语音智能打印等。