JAVA SDK 使用说明 - 单双色系列
1. 平台支持
JAVA SDK 在设计过程中,充分考虑了跨平台的需求。本 SDK 可以支持 windows/linux/android 操作系统,同时支持网络与串口通讯。而且在不同平台下,所有的操作都拥有统一的接口。
2. 获取 SDK
a. windows/linux sdk demo:
https://github.com/onbonlab/bx.dual.java.git
b. android demo:
https://github.com/onbonlab/bx.dual.android.git
c. android 串口通讯 sdk 与 demo:
https://github.com/onbonlab/bx.dual.android.serial.git
3. 使用说明
对于五代和六代控制器,我们提供了不同的 JAR 包,而其接口定义遵循了相同的命名规则,五代控制器的接口通常命名为 Bx5Gxxxx, 而相对应的六代控制器通常命名为 Bx6Gxxx。而以下接口说明中,为了简便只提到了五代SDK的接口,而六代SDK的接口,可根据命名规则自行推断或查看SDK中附带的相应的 JAVADOC 文档。API调用流程:
st=>start: Bx6GEnv.initial();
初始化
op=>operation: Bx6GScreen screen = new Bx6GScreen("screen",new Bx6E());
创建screen对象,用于与控制卡交互
op1=>operation: screen.connect(ip,port);
创建连接
cond=>condition: 更新节目或者更新动态区
op2=>operation: ProgramBxFile pf = new ProgramBxFile(0,screen.getProfile());
创建节目
op3=>operation: TextCaptionBxArea area2 = new TextCaptionBxArea(0,0,64,96,screen.getProfile());
创建图文区
op4=>operation: TextBxPage page2 = new TextBxPage("仰邦科技欢迎您!");
创建数据页
op5=>operation: area2.addPage(page2);
数据页添加到图文区
op6=>operation: pf.addArea(area1);
图文区添加到节目
op7=>operation: screen.writeProgram(pf);
更新节目
op8=>operation: DynamicBxAreaRule rule = new DynamicBxAreaRule();
创建动态区规则
op9=>operation: DynamicBxArea area = new DynamicBxArea(0,0,160,16,screen.getProfile());
创建动态区
op10=>operation: TextBxPage page = new TextBxPage( "雨天路滑,小心驾驶" );
创建数据页
op11=>operation: area.addPage(page);
数据页添加到动态区
op12=>operation: screen.writeDynamic(area);
更新动态区
e=>end: screen.disconnect();
断开连接
st->op
op->op1->cond
cond(yes)->op2
op2->op3
op3->op4
op4->op5
op5->op6
op6->op7
op7->e
cond(no)->op8
op8->op9
op9->op10
op10->op11
op11->op12
op12->e
3.1 SDK初始化
在使用 SDK 之前,必需先对整个 SDK 进行初始化。而初始化操作,在整个应用中只能进行一次(注: 非常重要)。如果反复调用 initial() 接口,会导致系统的 cpu load 变高。其调用方法如下:
五代控制器
// 五代控制器
// 初始化SDK
// 初始化有3种方法,如下
Bx5GEnv.initial();
// log.properties是日志配置文件
Bx5GEnv.initial("log.properties");
// 30000为通讯超时时间,单位是毫秒
Bx6GEnv.initial("log.properties",30000);
// 六代控制卡
// 初始化SDK
// 初始化有3种方法,如下
Bx6GEnv.initial();
// log.properties是日志配置文件
Bx6GEnv.initial("log.properties");
// 30000为通讯超时时间,单位是毫秒
Bx6GEnv.initial("log.properties",30000);
3.2 Screen类
要SDK中与控制器的所有交互都需要通过Bx5GScreen类或其子类来进行,其子类包括: Bx5GScreenClient(client模式使用),Bx5GScreenRS(串口模式使用),Bx5GScreenServer(server模式使用)。创建screen对象的通常代码如下:
五代控制器
// 五代控制器
// 创建screen对象,用于对控制器进行访问,客户端模式
Bx5GScreenClient screen = new Bx5GScreenClient("MyScreen");
// 创建screen对象,用于对控制器进行访问,串口模式
Bx5GScreenRS screen = new Bx5GScreenRS("MyScreen");
// 六代控制器创建screen对象方法,以BX-6M系列为例
// Bx6M 为控制卡型号,只有型号对应才能通讯正常,否则会出现逾时未回应
// 如果使用的控制器型号在SDK中没有定义,则用Bx6M替代
// 创建screen对象,用于对控制器进行访问,客户端模式
Bx6GScreenClient screen = new Bx6GScreenClient("MyScreen",new Bx6M());
// 创建screen对象,用于对控制器进行访问,串口模式
Bx6GScreenRS screen = new Bx6GScreenRS("MyScreen",new Bx6M());
在六代 SDK 中创建Screen对象时,需要传入相应的控制器型号,例如:new Bx6Q(), new Bx6M() 等,如果 SDK 中未定义可使用 new Bx6M()。
3.3 屏幕连接
在对控制器交互之前,需要先与控制器建立连接,代码如下:
// 连接控制器
// 其中,192.168.100.199为控制器的实际IP地址,请根据实际情况填写
// 端口号默认为5005
// 五代控制器和六代控制器屏幕连接方法一样
screen.connect("192.168.100.199",5005);
// 断开与控制器之间的连接
screen.disconnect();
注2:如果不知道控制器IP地址,请先使用LedshowTW软件设置IP地址,软件下载地址:https://www.onbonbx.com/download/165.html
3.4 屏幕控制
SDK 还提供了一些接口,用于对 屏幕进行一些常用操作。
3.4.1 开关机
// 关机
screen.turnOff();
// 开机
screen.turnOn();
3.4.2 校正时钟
控制器上的时钟不准确时,可以通过此命令对其进行校正。
// 校时
screen.syncTime();
3.4.3 锁定屏幕
// 锁定屏幕当前画面
screen.lock();
// 解除锁定屏幕当前画面
screen.unlock();
屏幕锁定后,画面将被锁定不动。
3.4.4 锁定节目
节目锁定后,控制器将仅播放当前锁定的节目,不再轮播其它节目。
// 锁定指定节目
screen.lockProgram(programId, lockDuration);
// 解除节目锁定
screen.unlockProgram(programId);
其中,
programId - 节目的 id
lockDuration - 锁定的时间长度,如果为0,则一直锁定
3.4.5 查询固件版本
// 查询控制器当前固件版本
screen.checkFirmware();
3.4.6 获取控制器状态
控制器状态中,包含连接在控制器上的传感器的值。如下所示:
// 通过以下接口回读控制器状态
Bx5GScreen.Result<ReturnControllersStatus> result = screen.checkControllerStatus();
if(result.isOK()){
ReturnControllerStatus status = result.reply;
// 取得亮度值
status.getBrightness();
// 取得温度传感器温度值
status.getTemperature1();
// status还有很多接口,根据实际应用进行调用
...
}
else{
ErrorType error = result.getError();
System.out.println(error);
}
3.5 节目与区域
节目主要用于组合屏幕上现实的内容,它由多个区域组成。控制器同一时间只能播放一个节目,它是控制器显示内容可以单独更新的最小单位(除动态区外)。 以下,我们将按步骤创建一个节目,并将其发送到控制器进行显示。
注:此处以五代控制器为例
步骤1:
创建节目文件,如下所示:
// 创建节目文件
// 第二个参数为显示屏属性,具体可以参照Bx5GScreenProfile类
Bx5GScreenProfile profile = screen.getProfile();
ProgramBxFile p0 = new ProgramBxFile(programId, profile);
// 关于节目类的其他接口可以参考ProgramBxFile类
步骤2:
创建相关区域,并将相关区域添加到节目文件中。
控制器支持的区域有很多种,例如:图文区、时间区、表盘区和传感器区等。其中,最常用的是图文区。图文区可以用于显示文本和图片。文字或图片可以按顺序依次添加到图文区中,而每页数据均可以设置特技方式,停留时间等属性。而创建一个图文区的步骤大致如下:
-
创建TextCaptionBxArea对象
-
创建TextBxPage或ImageFileBxPage对象
-
将创建好的page对象添加到TextCaptionBxArea中
下例代码,创建一个文本区,并向这个区域中添加一个文本页
// 创建一个图文区
// 参数为X、Y、width、heigth
// 注意区域左边和宽度高度,不要越界
TextCaptionBxArea area = new TextCaptionBxArea(0,0,160,64);
// 创建一个数据页,并希望显示“仰邦科技”这几个字
TextBxPage page = new TextBxPage("仰邦科技");
// 将page添加到area中
area.addPage(page);
// 将图文区添加到节目中
p0.addArea(area);
时间区也是比较常用的区域,而时间区的创建过程大致如下:
-
创建DateTimeBxArea对象
-
设置各时间单元显示格式
-
将DateTimeBxArea添加到节目中
具体代码如下:
// 下面代码创建了一个时间区
// 注意:只需输入时间区的起始坐标,区域的宽度和高度SDK会根据字体和显示方式自动计算
DateTimeBxArea dtArea = new DateTimeBxArea(0,0,screen.getProfile());
// 设置字体
dtArea.setFont(new Font("宋体",Font.PLAIN,12));
// 设置显示颜色
dtArea.setForeground(Color.yellow);
// 多行显示还是单行显示
dtArea.setMultiline(true);
// 年月日显示格式
// 如果不需要显示,设置为null
dtArea.setDateStyle(DateStyle.YYY_MM_DD_1);
dtArea.setTimeStyle(TimeStyle.HH_MM_SS_1);
dtArea.setWeekStyle(null);
// 将时间区添加到节目中
p0.addArea(dtArea);
// 关于DateTimeBxArea类的更多接口,请参考JAVADOC中相关类的说明
发送更新节目
节目文件创建好后,即可将节目发送到控制器以进行显示。其代码如下所示:
// 以下为更新节目命令
screen.WriteProgram(p0);
// 更新节目还有很多命令,请参考JAVADOC
3.6 动态区
动态区是一种比较特殊的区域(关于动态区),其有以下几个主要特点:
- 刷新次数没有限制
- 内容掉电不保存
- 独立于节目进行编辑
-
可以支持多个区域,且每个区域可以进行单独更新
-
可以和单个活多个节目绑定显示,即作为节目的一个区域进行显示
- 可以作为单独一个节目进行独立播放
- 灵活的控制方式:超时时间控制、是否立即显示灯
以下代码创建了一个动态区,将将其更新到控制器上显示。
五代控制器
// 五代控制器动态区(BX-5E系列)
// BX-5E系列控制卡最高支持4个动态区,当屏幕上需要同时显示多个动态区时,动态区ID不可以相同
// DynamicBxRule(id,runMode,immediatePlay,timeout);
// runMode 运行模式
// 0:循环显示
// 1:显示完成后静止显示最后一页数据
// 2:循环显示,超过设定时间后数据仍未更新时不显示
// 3:循环显示,超过设定时间后数据仍未更新时显示Logo信息
// 4:循环显示,显示完最后一页后不再显示
// immediatePlay
// 0:与异步节目一起播放
// 1:异步节目停止播放,仅播放动态区
// 2:当播放完节目编号最高的异步节目后播放该动态区
DynamicBxAreaRule rule = new DynamicBxRule(0,(byte)0,(byte)1,0);
TextCaptionBxArea darea = new TextCaptionBxArea(0,0,160,64,screen.getProfile());
TextBxPage dapge = new TextBxPage("动态区123abc");
darea.addPage(dpage);
screen.writeDynamic(rule,darea);
// 六代控制器动态区
DynamicBxAreaRule rule = new DynamicBxAreaRule();
// 设定动态区ID,此处ID为0,多个动态区ID不能相同
rule.setId(0);
// 设定异步节目停止播放,仅播放动态区
// 0:动态区与异步节目一起播放
// 1:异步节目停止播放,仅播放动态区
// 2:当播放完节目编号最高的异步节目后播放该动态区
rule.setImmediatePlay((byte)1);
// 设定动态区循环播放
// 0:循环播放
// 1:显示完成后静置显示最后一页数据
// 2:循环显示,超过设定时间后仍未更新时不再显示
// 3:循环显示,超过设定时间后仍未更新时显示Logo信息
// 4:显示完成最后一页后就不再显示
rule.setRunMode((byte)0);
DynamicBxArea area = new DynamicBxArea(0,0,160,32,screen.getProfile());
TextBxPage page = new TextBxPage("动态区abc");
area.addPage(page);
screen.writeDynamic(rule,area);
注意:对于单双色控制器,区域之间不能出现重叠。
4. Server模式
Server模式通常应用于广域网或者 GPRS/3G/4G 无线通讯的场合。在SDK中,Bx5GServer/Bx6GServer 对 server进行封装。它实现了控制器与 server 之间的链接维护,心跳解析,上下线提醒等功能。您可以像client模式一样,对广域网上的屏幕进行控制。
4.1 模式简介
Server的使用流程通常如下:
- 初始化API(在一个进程内只需要初始化一次)
- 建立并启动 Server
- 设定监听等待屏幕的连线与断线事件
- 获取在线屏幕
- 通过相应的 screen 对象对控制器进行相应的操作
// 初始化 SDK
Bx5GEnv.initial();
// 建立并启动服务器
// 此端口号为server进行监听的端口号
// 其必需与控制器参数中设置的 server port 一致
Bx5GServer server = new Bx5GServer("Hello Screen", 8036);
// 添加监听
server.addListener(new ConnectionListener());
// 启动服务器
server.start();
//
while(true) {
//
// 获取在线的控制器列表
ArrayList<Bx5GScreen> screens = (ArrayList<Bx5GScreen>) server.getOnlineScreens();
// 对相应的控制器进行操作
......
}
// 监听
public class ConnectionListener implements Bx5GServerListener {
@Override
public void connected(String socketId, String controllerAddr, Bx5GScreen screen) {
// 控制器上线后,会触发此事件
Result<ReturnPingStatus> result1 = screen.ping();
Result<ReturnControllerStatus> result2 = screen.checkControllerStatus();
......
}
@Override
public void disconnected(String socketId, String controllerAddr, Bx5GScreen screen) {
// 控制器下线后,会触发此事件
......
}
}
4.2 Demo说明
您可以从以下链接获取相应的 demo:
https://github.com/onbonlab/bx.dual.java.server.git
此项目主要用于测试仰邦五代和六代网口控制器的服务器模式。其工作方式如下:
-
服务端启动后,开始等待控制器上线
-
每隔5秒,检查一下在线控制器
- 依次发送节目至在线的控制器
- 如果控制器支持动态区,则更新动态区
其主要包含以下一个类:
- Bx5GTestbench: 五代控制器的测试平台
调用方式如下:
//
// 获取 testbench 实例
Bx5GTestbench g5tb = Bx5GTestbench.getInstance();
//
// run
g5tb.run(8001);
5. Android平台
5.1 使用说明
步骤1: 导入 sdk
将所有库文件拷贝至 libs 文件夹,并引入工程,如下所示:
在 module 的 build.gradle 中添加如下代码:
implementation files('libs/bx05-0.5.0-SNAPSHOT.jar')
implementation files('libs/bx05.message-0.5.0-SNAPSHOT.jar')
implementation files('libs/bx06-0.6.0-SNAPSHOT.jar')
implementation files('libs/bx06.message-0.6.0-SNAPSHOT.jar')
implementation files('libs/log4j-1.2.14.jar')
implementation files('libs/simple-xml-2.7.1.jar')
implementation files('libs/uia-comm-0.3.3.jar')
implementation files('libs/uia-utils-0.2.0.jar')
implementation files('libs/uia-message-0.6.0.jar')
implementation(name: 'java.awt4a-0.1-release', ext: 'aar')
在 project 的 build.gradle 中添加如下代码:
allprojects {
repositories {
google()
jcenter()
flatDir {
dirs 'libs'
}
}
}
步骤2: sdk 初始化
SDK 初始化在整个 APP 中只能调用一次,因此,我们将其放在 application 的 onCreate() 接口调用。如下所示:
public class MyApp extends Application {
private static final String TAG="MyApp";
@Override
public void onCreate() {
super.onCreate();
try {
// java.awt for android 初始化
AwtEnv.link(this);
// 是否启动抗锯齿
AwtEnv.configPaintAntiAliasFlag(false);
// 初始化五代
Bx5GEnv.initial();
// 建立 BX6G API 運行環境。
Bx6GEnv.initial();
Log.d(TAG, "sdk 6 version:" + Bx6GEnv.VER_INFO);
}
catch (Exception ex) {
Log.d(TAG, "sdk init error");
}
}
}
步骤3: 在 manifest.xml 中添加相关权限
对于网络通讯,必需先在 manifest 文件中申请相关网络访问的权限,否则会出现通讯失败。
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.onbonbx.demo">
<!-- 允许联网 -->
<!-- 获取GSM(2g)、WCDMA(联通3g)等网络状态的信息 -->
<uses-permission android:name="android.permission.INTERNET" />
<!-- 获取wifi网络状态的信息 -->
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<!-- 获取wifi网络状态的信息 -->
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<!-- 保持CPU 运转,屏幕和键盘灯有可能是关闭的,用于文件上传和下载 -->
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
<application
android:name=".MyApp"
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
步骤4: 在线程中调用相关接口
在 Android 系统中,网络通讯不能放在主线程中调用,而必需另起线程。通常如下:
new Thread(new Runnable() {
@Override
public void run() {
Bx5GScreenClient screen = new Bx5GScreenClient("screen");
try {
// 连接控制器
screen.connect(ip.getText().toString(), 5005);
// 获取控制器状态
screen.ping();
// 断开链接
screen.disconnect();
} catch (Bx5GException e) {
e.printStackTrace();
return;
}
}
}).start();
5.2 获取SDK与DEMO
您可以通过如下链接获取 ANDROID SDK 与 DEMO:
a. android demo:
https://github.com/onbonlab/bx.dual.android.git
b. android 串口通讯 sdk 与 demo:
https://github.com/onbonlab/bx.dual.android.serial.git
6. 常见问题
6.1 中文字体显示异常
如果您发现将中文字符发送到屏幕上不显示,或者显示为方块,此时通常是由于您选择的字体不支持中文,或者选择的字体在操作系统中没有安装。此时,选择支持中文的字体或在操作系统中安装相应字体即可解决。
6.2 文本对齐方式设置
SDK 提供了一些文本对齐方式的设置,接口如下:
// 水平方向
// 设置居左对齐
page.setHorizontalAlignment(TextBinary.Alignment.NEAR);
// 设置居中对齐
page.setHorizontalAlignment(TextBinary.Alignment.CENTER);
// 设置居右对齐
page.setHorizontalAlignment(TextBinary.Alignment.FAR);
// 垂直方向
// 设置居上对齐
page.setVerticalAlignment(TextBinary.Alignmet.NEAR);
// 设置居中对齐
page.setVerticalAlignment(TextBinary.Alignmet.CENTER);
// 设置居下对齐
page.setVerticalAlignment(TextBinary.Alignmet.FAR);
6.3 节目发送成功却不显示
如果发送节目时,返回成功,但是屏上却不显示。此时,最大的可能性是区域越界造成的。例如:一个屏幕的宽度为 128, 高度为32。而一个区域如果其 (x,y) 为 (0,0), 宽高为 (192, 32),则此区域即超过了屏幕参数的大小,此时节目发送成功后,不会被显示出来。
调试过程中,可以通过如下方式获取屏幕的参数信息。
// 获取屏幕的一些基本信息
Bx5GScreenProfile profile = screen.getProfile();
// 获取屏幕宽度
profile.getWidth();
// 获取屏幕高度
profile.getHeight();
如果使用的是节目,则在添加完区域后,可以通过 validate() 接口进行检查,如下所示:
// pf 为ProgramBxFile 对象
// 如果返回值不库null,说明有些区域参数越界, 而返回的即存在参数越界的BxArea对象
if(pf.validate()!=null){
System.out.println("pf out of range");
return;
}
6.4 如何显示表格
由于表格的编排非常复杂,因此,SDK没有集成表格功能。如果您想在屏幕上显示表格,则可以先将表格绘制成图片,然后再使用SDK的图片接口,将图片发送至屏幕。
而将绘制文字和表格,可以使用 Graphics2D 相关类。
6.5 如何升级固件
控制器的固件可以通过LedshowTW软来更新。可以在 “设置 -> 控制器程序维护” (密码: 888) 页面下操作。
6.6 如何实现文本换行
控制文本换行显示有2种方法,一种是通过换行符来强制换行,另一种是通过SDK中的接口来实现换行。代码如下所示:
// 通过换行符换行
TextBxPage page = new TextBxPage("第一行\r\n第二行");
// 通过接口换行
TextBxPage page = new TextBxPage("第一行");
page.newLine("第二行");
6.7 CPU LOAD 过高
使用 SDK 过程中,如果发现 CPU LOAD 过高,通常可能是以下原因造成:
- 多次调用 Bx6GEnv.initial()/Bx5GEnv.initial() 接口
- screen.connect() 后没有调用相应 screen.disconnect(),从而造成 screen 对象一直未释放