SensorTile物联网开发套件(4)——DIY遥控LED
往期回顾:
先上图片:
图片中实现的功能是用手机遥控控制LED,这个功能在Blue-MS是有的,但是在ST提供的SDK-Example中没有,那么就跟随我一起一步一步的实现吧!
SensorTile中烧录BM1固件,然后下载SDK,在帖子最后有下载,代码是托管在Github上的,用Android Studio 2.X打开,如果编译时提示缺少所需的编译工具,翻墙点击下载即可,或者直接修改代码中的编译工具版本。
整个工程分为BlueSTSDK和BlueSTExample两个部分,前者是SDK,后者是一个简单的例程,连接后可以显示所有的传感器数据,就像上面GIF图片中所示,点击列表就会出现详细的传感器数据。
打开工程后修改布局文件activity_demo.xml,添加一个按钮和两个线性布局,代码如下:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:weightSum="1" tools:context="com.st.BlueSTSDK.Example.FeatureListActivity">
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/Btn_LED"
android:text="LED"/>
</LinearLayout>
<ListView android:id="@+id/featureList"
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</LinearLayout>
然后找到FeatureListActivity,给按钮添加响应函数,这里采用OnClickListener监听,而不直接在布局文件中添加android:onClick方法的原因是AppCompatActivity类并不支持。给FeatureListActivity添加接口类:
View.OnClickListener
添加LED按钮的全局变量:
private Button LED;
在onCreat函数中给按钮添加监听:
LED = (Button) findViewById(R.id.Btn_LED);
LED.setOnClickListener(this);
在onCreat外添加按钮实现函数:
public void onClick(View view){
switch (view.getId()){
case R.id.Btn_LED:
FeatureSwitch f = mNode.getFeature(FeatureSwitch.class); //get Feature Switch class
if(!mNode.isEnableNotification(f))//Ensure the Switch is EnableNotification
mNode.enableNotification(f);
if(f.getSwitchStatus(f.getSample())==0){//Check the led state
f.changeSwitchStatus((byte)0x01);//Tuen on LED
}else {
f.changeSwitchStatus((byte) 0x00);//Tuen off LED
}
break;
}
}
代码都进行了注释,界面上之所以显示这些类的信息是因为APP检测到有这些Feature类可用,如果注册了算法库后,会发现可用的Feature类变多,在点击了按钮之后,先获取Switch的类,然后判断该节点中Switch类是否Notification,,在没有点击列表中的Feature类的时候是没有Notification该类的,也就是说不会关注该Feature类的任何变动,对其各种操作也是不可行的。因此在这里先判断是否已经Notification了Switch类,如果没有就开启,这样无论是否点击列表中的Switch类都可以实现对LED的控制。
然后调用Switch类中的获取LED灯状态的函数,该函数中需要Sample变量,该变量是收到的数据,这里同样需要调用Switch类中的获取Sample函数,这里获取到的是上一次收到的数据,根据LED的状态来控制LED灯,就实现了一键交替开关LED的效果。
有了以上的代码已经能够实现灯的开关操作了,但是却不敢保证LED灯按照要求控制了,还需要一个回馈,因此修改onUpdate函数如下:
public void onUpdate(Feature f, Feature.Sample sample) {
final String featureDump = f.toString();
if( f.getName().equals("Switch")){//if the Feature is Switch
FeatureSwitch Switch = mNode.getFeature(FeatureSwitch.class);
if(Switch.getSwitchStatus(sample)==0){//Check the led state
LED_State=true;
}else{
LED_State=false;
}
FeatureListActivity.this.runOnUiThread(new Runnable() {
@Override
public void run() {
if(LED_State) {
LED.setText("Turn On");//update button text
}else {
LED.setText("Tuen Off");//update button text
}
}
});
}
FeatureListActivity.this.runOnUiThread(new Runnable() {
@Override
public void run() {
mTextView.setText(featureDump);//Modify the button's text
}
});
}//onUpdate
SensorTile所有的数据更新都是通过调用onUpdate函数来实现的,在该函数中调用各个Feature中的toString函数,将收到的数据转换为字符串,最后在UI更新线程中更新。由于所有的Feature的数据更新都会调用onUpdate,那就可以在函数中根据不同的Feature来进行不同的操作。首先获取Feature的名字,如果是“Switch”就往下处理,获取该节点的Switch的类,然后调用该类中的getSwitchStatus,这里sample直接用,不调用Switch类中getsample方法。得到了LED灯的状态就给全局变量LED_State赋值,最后根据LED_State的值改变按钮上的文字,这就可以确保准确了。这里注意LED_State变量不能定义在函数里面,否则在UI线程中会报错。
SDK有很多Feature,熟悉了Switch的使用,其他的也就大同小异了,为以后更复杂的应用打好基础。
回顾整个DIY过程,我们根本没有接触到底层,没有配置服务地址,没有配置特征,没有写发送接收函数,一切都是调用接口函数,却可以满足各种需求,这种开发模式是不是很爽呢。
本帖修改后的SDK源码:https://github.com/flyloong/BlueSTSDK/tree/V1.0.0