注意:代码仅供参考,需要根据具体的设备做调整
同系列文章:
注意:仅适用于带主动上传功能的人脸通设备
演示程序源代码下载:
FaceIdDemo-Java-20161118.zip
注意:需要引入FaceId.jar
演示程序界面
源代码
TcpServerDemo.java
/* * To change this license header, choose License Headers in Project Properties. * To change this template file, choose Tools | Templates * and open the template in the editor. */ package Splash; import java.io.IOException; import java.util.Locale; import javafx.application.Application; import javafx.fxml.FXMLLoader; import javafx.scene.Parent; import javafx.scene.Scene; import javafx.scene.image.Image; import javafx.stage.Stage; import javafx.stage.WindowEvent; /** * * @author Splash */ public class TcpServerDemo extends Application { @Override public void start(Stage stage) throws Exception { Locale.setDefault(Locale.CHINESE);// 让Dialogs按钮显示中文 FXMLLoader loader = new FXMLLoader(getClass().getResource("FXMLDocument.fxml")); Parent root = loader.load(); Scene scene = new Scene(root); stage.setScene(scene); // 设置窗体标题 stage.setTitle("接收卡点数据"); // 设置窗体图标 stage.getIcons().add(new Image(getClass().getResourceAsStream("FireEyes.png"))); // 设置到屏幕中心 stage.centerOnScreen(); // 设置窗口关闭处理函数 stage.setOnCloseRequest((WindowEvent e) -> { try { FXMLDocumentController controller = loader.getController(); if(controller.TcpServer != null) { controller.TcpServer.close(); controller.TcpServer = null; } } catch (IOException ex) { // 错误处理 } }); // 显示窗体 stage.show(); } /** * @param args the command line arguments */ public static void main(String[] args) { launch(args); } }
FXMLDocumentController.java
/* ---------------------------------------------------------- * 文件名称:FXMLDocumentController.java * * 作者:秦建辉 * * QQ:36748897 * * 博客:http://www.firstsolver.com/wordpress/ * * 开发环境: * NetBeans 8.0 * JDK 8u20 * ControlsFX-8.0.6_20 * * 版本历史: * V1.0 2014年09月04日 * 接收卡点数据 ------------------------------------------------------------ */ package Splash; import com.hanvon.faceid.sdk.*; import java.io.IOException; import java.net.Inet4Address; import java.net.Inet6Address; import java.net.InetAddress; import java.net.NetworkInterface; import java.net.SocketException; import java.net.URL; import java.util.Enumeration; import java.util.LinkedList; import java.util.List; import java.util.ResourceBundle; import javafx.application.Platform; import javafx.collections.FXCollections; import javafx.event.ActionEvent; import javafx.fxml.FXML; import javafx.fxml.Initializable; import javafx.scene.control.Button; import javafx.scene.control.ComboBox; import javafx.scene.control.TextArea; import javafx.scene.control.TextField; import javafx.stage.Stage; import org.controlsfx.dialog.DialogStyle; import org.controlsfx.dialog.Dialogs; /** * * @author Splash */ public class FXMLDocumentController implements Initializable, ISocketServerThreadTask { private final String DeviceCharset = "GBK"; private boolean IsServerRunning = false; public TcpListenerPlus TcpServer = null; @FXML private TextField textFieldDeviceIP; @FXML private TextField textFieldDevicePort; @FXML private ComboBox comboBoxServerIP; @FXML private TextField textFieldServerPort; @FXML private TextArea textAreaRecords; @FXML private Button buttonStartListener; @FXML private void handleButtonSetServerHostAction(ActionEvent event) { // 获取当前应用窗体 Stage stage = (Stage)((Button)event.getSource()).getScene().getWindow(); try(FaceId tcpClient = new FaceId(textFieldDeviceIP.getText(), Integer.parseInt(textFieldDevicePort.getText()))) { // 设置服务器地址 FaceIdAnswer output = new FaceIdAnswer(); FaceId_ErrorCode ErrorCode = tcpClient.Execute("SetServerHost(ip=\"" + comboBoxServerIP.getValue().toString() + "\" port=\"" + textFieldServerPort.getText() + "\")", output, DeviceCharset); if (ErrorCode.equals(FaceId_ErrorCode.Success)) { Dialogs.create().style(DialogStyle.NATIVE).owner(stage).title("成功").message("设置服务器成功!").showInformation(); } else { Dialogs.create().style(DialogStyle.NATIVE).owner(stage).title("错误").message("设置服务器失败!").showError(); } } catch (RuntimeException | IOException e) { Dialogs.create().style(DialogStyle.NATIVE).owner(stage).title("错误").message("连接设备失败!").showError(); } } @FXML private void handleButtonClearAction(ActionEvent event) { textAreaRecords.clear(); } @FXML private void handleButtonStartListenerAction(ActionEvent event) throws IOException, Exception { if(IsServerRunning) { if(TcpServer != null) { TcpServer.close(); TcpServer = null; } IsServerRunning = false; buttonStartListener.setText("开始侦听"); } else { // 创建侦听服务器 TcpServer = new TcpListenerPlus(Integer.parseInt(textFieldServerPort.getText()), 0, InetAddress.getByName(comboBoxServerIP.getValue().toString())); // 设置通信线程任务委托 TcpServer.ThreadTaskDelegate = this; // 设置通信密码 TcpServer.setSecretKey(null); // 开启侦听服务 List<String> TrustedIPAddresses = new LinkedList<>(); TrustedIPAddresses.add(textFieldDeviceIP.getText()); TcpServer.StartListenThread(TrustedIPAddresses, 0, 0); IsServerRunning = true; buttonStartListener.setText("停止侦听"); } } @Override public void OnServerTaskRequest(NetworkStreamPlus stream){ // TODO while(true) { try { // 读取数据 String Answer = stream.Read(DeviceCharset); // 显示读取信息 Platform.runLater(new Runnable() { @Override public void run() { textAreaRecords.appendText(Answer + "\r\n"); } }); if(Answer.startsWith("PostRecord")) { // 准备上传考勤记录 // 服务器回应,不上传照片 stream.Write("Return(result=\"success\" postphoto=\"false\")", DeviceCharset); } else if(Answer.startsWith("PostEmployee")) { // 准备上传人员信息 // 服务器回应 stream.Write("Return(result=\"success\")", DeviceCharset); } else if(Answer.startsWith("Record")) { // 读取考勤记录 // 服务器回应 stream.Write("Return(result=\"success\")", DeviceCharset); } else if(Answer.startsWith("Employee")) { // 读取人员信息 // 服务器回应 stream.Write("Return(result=\"success\")", DeviceCharset); } else if(Answer.startsWith("Quit")) { // 结束会话 break; } } catch (Exception ex) { break; // 连接断开 } } } @Override public void initialize(URL url, ResourceBundle rb) { // 设置服务器地址 try { List<String> IPList = new LinkedList<>(); Enumeration<NetworkInterface> InterfaceList = NetworkInterface.getNetworkInterfaces(); while (InterfaceList.hasMoreElements()) { NetworkInterface iFace = InterfaceList.nextElement(); if(iFace.isLoopback() || iFace.isVirtual() || iFace.isPointToPoint() || !iFace.isUp()) continue; Enumeration<InetAddress> AddrList = iFace.getInetAddresses(); while (AddrList.hasMoreElements()) { InetAddress address = AddrList.nextElement(); if ((address instanceof Inet4Address) || (address instanceof Inet6Address)) { IPList.add(address.getHostAddress()); } } } if(!IPList.isEmpty()) { comboBoxServerIP.setItems(FXCollections.observableList(IPList)); comboBoxServerIP.setValue(IPList.get(0)); } } catch (SocketException ex) { // 异常处理 } } }
FXMLDocument.fxml
<?xml version="1.0" encoding="UTF-8"?> <?import javafx.scene.text.*?> <?import javafx.scene.effect.*?> <?import javafx.geometry.*?> <?import java.lang.*?> <?import java.util.*?> <?import javafx.scene.*?> <?import javafx.scene.control.*?> <?import javafx.scene.layout.*?> <AnchorPane id="AnchorPane" minWidth="600.0" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1" fx:controller="Splash.FXMLDocumentController"> <children> <GridPane minWidth="600.0"> <columnConstraints> <ColumnConstraints /> </columnConstraints> <rowConstraints> <RowConstraints /> <RowConstraints /> <RowConstraints /> <RowConstraints /> </rowConstraints> <children> <GridPane GridPane.hgrow="ALWAYS" GridPane.rowIndex="0"> <columnConstraints> <ColumnConstraints /> <ColumnConstraints hgrow="ALWAYS" /> </columnConstraints> <rowConstraints> <RowConstraints /> <RowConstraints /> <RowConstraints /> <RowConstraints /> </rowConstraints> <children> <Label text="设备地址" GridPane.columnIndex="0" GridPane.halignment="RIGHT" GridPane.rowIndex="0"> <GridPane.margin> <Insets bottom="4.0" left="4.0" right="4.0" top="4.0" /> </GridPane.margin> </Label> <Label text="设备端口" GridPane.columnIndex="0" GridPane.halignment="RIGHT" GridPane.rowIndex="1"> <GridPane.margin> <Insets bottom="4.0" left="4.0" right="4.0" top="4.0" /> </GridPane.margin> </Label> <Label text="服务器地址" GridPane.columnIndex="0" GridPane.halignment="RIGHT" GridPane.rowIndex="2"> <GridPane.margin> <Insets bottom="4.0" left="4.0" right="4.0" top="4.0" /> </GridPane.margin> </Label> <Label text="服务器端口" GridPane.columnIndex="0" GridPane.halignment="RIGHT" GridPane.rowIndex="3"> <GridPane.margin> <Insets bottom="4.0" left="4.0" right="4.0" top="4.0" /> </GridPane.margin> </Label> <TextField fx:id="textFieldDeviceIP" text="192.168.1.18" GridPane.columnIndex="1" GridPane.hgrow="ALWAYS" GridPane.rowIndex="0" GridPane.vgrow="ALWAYS"> <GridPane.margin> <Insets bottom="4.0" left="4.0" right="4.0" top="4.0" /> </GridPane.margin> </TextField> <TextField fx:id="textFieldDevicePort" text="9922" GridPane.columnIndex="1" GridPane.hgrow="ALWAYS" GridPane.rowIndex="1"> <GridPane.margin> <Insets bottom="4.0" left="4.0" right="4.0" top="4.0" /> </GridPane.margin> </TextField> <ComboBox fx:id="comboBoxServerIP" minWidth="200.0" GridPane.columnIndex="1" GridPane.hgrow="ALWAYS" GridPane.rowIndex="2"> <GridPane.margin> <Insets bottom="4.0" left="4.0" right="4.0" top="4.0" /> </GridPane.margin> </ComboBox> <TextField fx:id="textFieldServerPort" editable="false" text="9900" GridPane.columnIndex="1" GridPane.hgrow="ALWAYS" GridPane.rowIndex="3"> <GridPane.margin> <Insets bottom="4.0" left="4.0" right="4.0" top="4.0" /> </GridPane.margin> </TextField> </children> </GridPane> <Button fx:id="buttonSetServerHost" minHeight="40.0" minWidth="100.0" onAction="#handleButtonSetServerHostAction" text="设置服务器" GridPane.halignment="CENTER" GridPane.rowIndex="1"> <GridPane.margin> <Insets bottom="4.0" left="4.0" right="4.0" top="4.0" /> </GridPane.margin> </Button> <GridPane GridPane.rowIndex="2"> <columnConstraints> <ColumnConstraints /> <ColumnConstraints /> </columnConstraints> <rowConstraints> <RowConstraints /> </rowConstraints> <children> <Button fx:id="buttonClear" minHeight="40.0" minWidth="80.0" onAction="#handleButtonClearAction" text="清空" GridPane.columnIndex="0" GridPane.halignment="LEFT" GridPane.hgrow="ALWAYS"> <GridPane.margin> <Insets bottom="4.0" left="4.0" right="4.0" top="4.0" /> </GridPane.margin> </Button> <Button fx:id="buttonStartListener" minHeight="40.0" minWidth="80.0" onAction="#handleButtonStartListenerAction" text="开启侦听" GridPane.columnIndex="1" GridPane.halignment="RIGHT" GridPane.hgrow="ALWAYS"> <GridPane.margin> <Insets bottom="4.0" left="4.0" right="4.0" top="4.0" /> </GridPane.margin> </Button> </children> </GridPane> <TextArea fx:id="textAreaRecords" editable="false" minHeight="400.0" minWidth="600.0" wrapText="true" GridPane.hgrow="ALWAYS" GridPane.rowIndex="3" GridPane.vgrow="ALWAYS"> <GridPane.margin> <Insets bottom="4.0" left="4.0" right="4.0" top="4.0" /> </GridPane.margin> </TextArea> </children> </GridPane> </children> </AnchorPane>