HarmonyOS分布式应用农业大棚数据监测解读

系统 分布式 OpenHarmony
分布式数据服务(Distributed Data Service,DDS) 为应用程序提供不同设备间数据库数据分布式的能力。通过调用分布式数据接口,应用程序将数据保存到分布式数据库中。

[[440298]]

想了解更多内容,请访问:

51CTO和华为官方合作共建的鸿蒙技术社区

https://harmonyos.51cto.co

引言

分布式数据服务(Distributed Data Service,DDS) 为应用程序提供不同设备间数据库数据分布式的能力。通过调用分布式数据接口,应用程序将数据保存到分布式数据库中。通过结合帐号、应用和数据库三元组,分布式数据服务对属于不同应用的数据进行隔离,保证不同应用之间的数据不能通过分布式数据服务互相访问。在通过可信认证的设备间,分布式数据服务支持应用数据相互同步,为用户提供在多种终端设备上最终一致的数据访问体验。

功能介绍

此次基于HarmonyOS的分布式数据服务能力,一方面模拟农业大棚的温度、湿度、二氧化碳浓度等数据的采集,并在手机端进行采集数据展示;另一方面,可以把手机端的数据,迁移到其他设备(如智慧屏、手表、PAD等),可以做一些数据分析展示。

前提:

在不同设备之间,要实现分布式数据服务的同步能力,需要同一个华为账号登录、并一个应用包名、同一个网络之间进行,也可以是两个设备同时开启蓝牙。

开发指南

1.在config.json中添加permisssion权限

// 添加在abilities同一目录层级

  1. "reqPermissions": [ 
  2.     { 
  3.         "name""ohos.permission.DISTRIBUTED_DATASYNC" 
  4.     } 

2.在MainAbility中添加权限

  1. @Override 
  2. public void onStart(Intent intent) { 
  3.   super.onStart(intent); 
  4.   super.setMainRoute(MainAbilitySlice.class.getName()); 
  5.   //实现Ability的代码中显式声明需要使用多设备协同访问的权限 
  6.   requestPermissionsFromUser(new String[]{ 
  7.       "ohos.permission.DISTRIBUTED_DATASYNC"}, 0); 
  8.  

3.根据配置构造分布式数据库管理类实例KvManager以及创建分布式数据库对象SingleKvStore

//实现数据库的初始化

  1. // 初入的参数context: Context context = getApplicationContext()获得;storeId为分布式数据库id,String类型,可自行定义,例如“testApp”。 
  2. public static SingleKvStore initOrGetDB(Context context, String storeId) { 
  3.   KvManagerConfig kvManagerConfig = new KvManagerConfig(context); 
  4.   kvManager = KvManagerFactory.getInstance().createKvManager(kvManagerConfig); 
  5.   Options options = new Options(); 
  6.   options.setCreateIfMissing(true
  7.     .setEncrypt(false
  8.     .setKvStoreType(KvStoreType.SINGLE_VERSION) //数据库类型:单版本分布式数据库 
  9.     .setAutoSync(true); //自动同步为true,手动同步为false 
  10.   singleKvStore = kvManager.getKvStore(options, storeId); 
  11.   return singleKvStore; 

4.将数据写入单版本分布式数据库

  1. //以key-value形式存储到分布式数据库 
  2. try { 
  3.   //将采集的数据以key-value形式存入分布式数据库中 
  4.   DataModle dataModle=new DataModle(); 
  5.   dataModle.setTemp(temp); 
  6.   dataModle.setHumi(humi); 
  7.   dataModle.setCo2(co2); 
  8.   String jsonString= ZSONObject.toZSONString(dataModle); 
  9.   singleKvStore.putString("data",jsonString); 
  10. } catch (KvStoreException e) { 
  11.   LogUtils.debug(TAG, "DataServiceAbility::updateData()"+e.getMessage()); 
  12.  

5.订阅分布式数据变化。客户端需要实现KvStoreObserver接口,监听数据变化

  1. //订阅类型SubscribeType.SUBSCRIBE_TYPE_ALL意思可以同步到本机和其他外围设备 
  2.   innerKvStoreObserver = new InnerKvStoreObserver(); 
  3.   singleKvStore.subscribe(SubscribeType.SUBSCRIBE_TYPE_ALL, innerKvStoreObserver); 
  4. } catch (KvStoreException e) { 
  5.   e.printStackTrace(); 
  6.  
  7. public class InnerKvStoreObserver implements KvStoreObserver { 
  8.  
  9.   @Override 
  10.   public void onChange(ChangeNotification changeNotification) { 
  11.     //刷新页面上的数据,同样有一个坑,onChange方法实质上,在一个子线程里执行 
  12.     MainAbilitySlice.taskDispatcher.asyncDispatch(() -> { 
  13.       //在这里执行页面ui组件的显示刷新 
  14.       flushUIData(); 
  15.     }); 
  16.   } 

6.获取分布式数据库数据

  1.  //查询分布式数据的数据,获取数据可以通过get(String key)或者 getEntries(String key)方法获取数据 
  2. List<Entry> entries = singleKvStore.getEntries("data"); 
  3. if (entries.size() > 0) { 
  4.   ZSONObject zsonObject = ZSONObject.stringToZSON(entries.get(0).getValue().getString()); 
  5.   double temp = zsonObject.getDouble("temp"); 
  6.   double humi = zsonObject.getDouble("humi"); 
  7.   double co2 = zsonObject.getDouble("co2"); 
  8.   String strTemp = String.format("%.1f"temp); 
  9.   String strHumi = String.format("%.1f", humi); 
  10.   String strCO2 = String.format("%.1f", co2); 
  11.   tvTemp.setText(strTemp+"℃"); 
  12.   tvHumi.setText(strHumi+"%RH"); 
  13.   tvCo2.setText(strCO2+"ppm"); 

7.解除订阅,一般在页面销毁时调用,也就是在onStop()中调用

  1. if (singleKvStore != null) { 
  2.   singleKvStore.unSubscribe(innerKvStoreObserver); 

8.同步数据到其他设备。获取已连接的设备列表,选择同步方式进行数据同步

  1. List<DeviceInfo> onlineDevices = DeviceManager 
  2.     .getDeviceList(DeviceInfo.FLAG_GET_ONLINE_DEVICE); 
  3. List<String> deviceIdList = new ArrayList<>(); 
  4. for (DeviceInfo deviceInfo : deviceInfoList) { 
  5.     deviceIdList.add(deviceInfo.getId()); 
  6. //迁移到指定设备,传入设备ID列表 
  7. singleKvStore.sync(deviceIdList, SyncMode.PUSH_ONLY); 

 项目中采用在后台service中开启定时任务,模拟农业大棚采集数据,实时保存数据到分布式数据库,然后在主界面,监听数据变化,实时更新数据。当选择迁移的设备时,就可以把数据迁移到相应设备。

#星光计划2.0#HarmonyOS分布式应用农业大棚数据监测解读-鸿蒙HarmonyOS技术社区

手机侧应用刚打开时界面

#星光计划2.0#HarmonyOS分布式应用农业大棚数据监测解读-鸿蒙HarmonyOS技术社区

TV侧应用刚打开时界面

#星光计划2.0#HarmonyOS分布式应用农业大棚数据监测解读-鸿蒙HarmonyOS技术社区

点击右上角迁移按钮,并选择迁移设备(P40-0036)

#星光计划2.0#HarmonyOS分布式应用农业大棚数据监测解读-鸿蒙HarmonyOS技术社区
#星光计划2.0#HarmonyOS分布式应用农业大棚数据监测解读-鸿蒙HarmonyOS技术社区

迁移后的左侧设备数据和右侧设备数据就会同步一致

附上源码

手机端

1. PhoneAbilitySlice

  1. public class PhoneAbilitySlice extends AbilitySlice { 
  2.   private SingleKvStore singleKvStore; 
  3.   private InnerKvStoreObserver innerKvStoreObserver; 
  4.   private Intent serviceIntent; 
  5.   private Text tvTemp; 
  6.   private Text tvHumi; 
  7.   private Text tvCo2; 
  8.   private DeviceData chooseDevice; 
  9.   private DevicesProvider devicesProvider; 
  10.   private CommonDialog commonDialog; 
  11.   private String TAG="MainAbilitySlice"
  12.   private List<String>deviceIdList; 
  13.   @Override 
  14.   public void onStart(Intent intent) { 
  15.     super.onStart(intent); 
  16.     super.setUIContent(ResourceTable.Layout_ability_main); 
  17.     //设置沉浸式状态栏  getWindow().addFlags(WindowManager.LayoutConfig.MARK_TRANSLUCENT_STATUS); 
  18.     initView(); 
  19.     initService(); 
  20.     try { 
  21.       //获取数据库 
  22.       singleKvStore = DBUtils.initOrGetDB(this, DBUtils.KV_STORE_NAME); 
  23.       innerKvStoreObserver = new InnerKvStoreObserver(); 
  24.       //订阅分布式数据库 
  25.       singleKvStore.subscribe(SubscribeType.SUBSCRIBE_TYPE_ALL, innerKvStoreObserver); 
  26.     } catch (KvStoreException e) { 
  27.       LogUtils.debug(TAG, "MainAbilitySlice::onStart/"+e.getMessage()); 
  28.     } 
  29.   } 
  30.   private void initService() { 
  31.     //启动ServiceAbility 
  32.     serviceIntent = new Intent(); 
  33.     Operation operation = new Intent.OperationBuilder() 
  34.         .withDeviceId(""
  35.         .withBundleName("com.isoftstone.distributeddata"
  36.         .withAbilityName("com.isoftstone.distributeddata.DataServiceAbility"
  37.         .build(); 
  38.     serviceIntent.setOperation(operation); 
  39.     startAbility(serviceIntent); 
  40.   } 
  41.   private void initView() { 
  42.     tvTemp = (Text) findComponentById(ResourceTable.Id_text_temp); 
  43.     tvHumi = (Text) findComponentById(ResourceTable.Id_text_humi); 
  44.     tvCo2 = (Text) findComponentById(ResourceTable.Id_text_co2); 
  45.     Button bt = (Button) findComponentById(ResourceTable.Id_bt_continue); 
  46.     bt.setClickedListener(component -> { 
  47.       if (component.getId() == ResourceTable.Id_bt_continue) { 
  48.         //查看在线设备 
  49.         List<DeviceInfo> onlineDevices = DeviceManager 
  50.             .getDeviceList(DeviceInfo.FLAG_GET_ONLINE_DEVICE); 
  51.         List<DeviceData> deviceDatas = new ArrayList<>(); 
  52.         if (onlineDevices == null || onlineDevices.size() < 1) { 
  53.           CustomerDialog.showToastDialog(getAbility(), "无组网在线设备"); 
  54.         } else { 
  55.           for (DeviceInfo deviceInfo : onlineDevices) { 
  56.             deviceDatas.add(new DeviceData(false, deviceInfo)); 
  57.           } 
  58.           showDevices(deviceDatas); 
  59.         } 
  60.       } 
  61.     }); 
  62.   } 
  63.   private void showDevices(List<DeviceData> deviceDatas) { 
  64.     chooseDevice = null
  65.     commonDialog = new CommonDialog(this); 
  66.     Component component = LayoutScatter.getInstance(this) 
  67.         .parse(ResourceTable.Layout_dialog_layout_device, nulltrue); 
  68.     ListContainer listContainer = (ListContainer) component.findComponentById(ResourceTable.Id_list_container_device); 
  69.     devicesProvider = new DevicesProvider(this, deviceDatas); 
  70.     listContainer.setItemProvider(devicesProvider); 
  71.     listContainer.setItemClickedListener((listContainer1, component1, position, l) -> { 
  72.       chooseDevice = deviceDatas.get(position); 
  73.       for (int i = 0; i < deviceDatas.size(); i++) { 
  74.         if (i == position) { 
  75.           deviceDatas.set(i, new DeviceData(true, deviceDatas.get(i).getDeviceInfo())); 
  76.         } else { 
  77.           deviceDatas.set(i, new DeviceData(false, deviceDatas.get(i).getDeviceInfo())); 
  78.         } 
  79.       } 
  80.       devicesProvider = new DevicesProvider(this, deviceDatas); 
  81.       listContainer1.setItemProvider(devicesProvider); 
  82.     }); 
  83.     Text tvCancle = (Text) component.findComponentById(ResourceTable.Id_operate_no); 
  84.     Text tvSure = (Text) component.findComponentById(ResourceTable.Id_operate_yes); 
  85.  
  86.     tvCancle.setClickedListener(component12 -> commonDialog.destroy()); 
  87.  
  88.     tvSure.setClickedListener(component13 -> { 
  89.       if (chooseDevice == null) { 
  90.         CustomerDialog.showToastDialog(this, "请选择设备"); 
  91.       } else { 
  92.         try { 
  93.           deviceIdList=new ArrayList<>(); 
  94.           deviceIdList.add(chooseDevice.getDeviceInfo().getDeviceId()); 
  95.           //手动同步的设备列表 
  96.           singleKvStore.sync(deviceIdList, SyncMode.PUSH_ONLY); 
  97.           commonDialog.destroy(); 
  98.         } catch (IllegalStateException e) { 
  99.           //流转异常捕获,防止进程存在再次发起流转 
  100.           LogUtils.debug(TAG, "MainAbilitySlice::singleKvStore.sync()/"+e.getMessage()); 
  101.         } 
  102.       } 
  103.     }); 
  104.     commonDialog.setSize(MATCH_PARENT, MATCH_CONTENT); 
  105.     commonDialog.setAlignment(LayoutAlignment.BOTTOM); 
  106.     commonDialog.setCornerRadius(10); 
  107.     commonDialog.setAutoClosable(true); 
  108.     commonDialog.setContentCustomComponent(component); 
  109.     commonDialog.setTransparent(true); 
  110.     commonDialog.show(); 
  111.   } 
  112.   public class InnerKvStoreObserver implements KvStoreObserver { 
  113.  
  114.     @Override 
  115.     public void onChange(ChangeNotification changeNotification) { 
  116.       //onChange方法实质上,在一个子线程里执行 
  117.       getUITaskDispatcher().asyncDispatch(() -> { 
  118.         //在这里执行页面ui组件的显示刷新 
  119.         asyncUpdateData(); 
  120.       }); 
  121.     } 
  122.   } 
  123.   public void asyncUpdateData(){ 
  124.     //查询分布式数据的数据 
  125.     List<Entry> entries = singleKvStore.getEntries("data"); 
  126.     if (entries.size() > 0) { 
  127.       ZSONObject zsonObject = ZSONObject.stringToZSON(entries.get(0).getValue().getString()); 
  128.       double temp = zsonObject.getDouble("temp"); 
  129.       double humi = zsonObject.getDouble("humi"); 
  130.       double co2 = zsonObject.getDouble("co2"); 
  131.       String strTemp = String.format("%.1f"temp); 
  132.       String strHumi = String.format("%.1f", humi); 
  133.       String strCO2 = String.format("%.1f", co2); 
  134.       tvTemp.setText(strTemp+"℃"); 
  135.       tvHumi.setText(strHumi+"%RH"); 
  136.       tvCo2.setText(strCO2+"ppm"); 
  137.       //手动同步的设备列表 
  138.       if(singleKvStore!=null){ 
  139.         if(deviceIdList!=null&&deviceIdList.size()>0){ 
  140.           singleKvStore.sync(deviceIdList, SyncMode.PUSH_ONLY); 
  141.         } 
  142.       } 
  143.     } 
  144.   } 
  145.  
  146.   @Override 
  147.   public void onActive() { 
  148.     super.onActive(); 
  149.   } 
  150.   @Override 
  151.   public void onForeground(Intent intent) { 
  152.     super.onForeground(intent); 
  153.   } 
  154.   @Override 
  155.   protected void onStop() { 
  156.     super.onStop(); 
  157.     //销毁service 
  158.     stopAbility(serviceIntent); 
  159.     //删除数据库 
  160.     DBUtils.clearDB(); 
  161.     //解除订阅 
  162.     if (singleKvStore != null) { 
  163.       if(innerKvStoreObserver!=null){ 
  164.         singleKvStore.unSubscribe(innerKvStoreObserver); 
  165.       } 
  166.     } 
  167.   } 

2. DataServiceAbility

  1. public class DataServiceAbility extends Ability { 
  2.   private static final HiLogLabel LABEL_LOG = new HiLogLabel(3, 0xD001100, "Demo"); 
  3.   private SingleKvStore singleKvStore; 
  4.   private NotificationRequest request; 
  5.   private Timer mTimer; 
  6.   private TimerTask mTimerTask; 
  7.   private String TAG="DataServiceAbility"
  8.   @Override 
  9.   public void onStart(Intent intent) { 
  10.     LogUtils.debug(TAG, "DataServiceAbility::onStart"); 
  11.     super.onStart(intent); 
  12.     //创建前台service 
  13.     createForeService(); 
  14.     try { 
  15.       singleKvStore = DBUtils.initOrGetDB(this, DBUtils.KV_STORE_NAME); 
  16.     } catch (Exception e) { 
  17.       LogUtils.debug(TAG, "DataServiceAbility::onStart()"+e.getMessage()); 
  18.     } 
  19.     //每隔10秒,模拟传感器采集一次大棚数据。 
  20.     if(mTimer==null){ 
  21.       mTimer=new Timer(); 
  22.     } 
  23.     if(mTimerTask==null){ 
  24.       mTimerTask=new TimerTask() { 
  25.         @Override 
  26.         public void run() { 
  27.           updateData(); 
  28.         } 
  29.       }; 
  30.     } 
  31.     mTimer.schedule(mTimerTask,0,1000*10); 
  32.   } 
  33.   private void updateData() { 
  34.     //获取随机温度0-100; 
  35.     double temp= new Random().nextDouble()*100; 
  36.     //获取随机湿度0-100; 
  37.     double humi= new Random().nextDouble()*100; 
  38.     //获取随机CO2浓度0-1000 
  39.     double co2= new Random().nextDouble()*1000; 
  40.     try { 
  41.       //将采集的数据以key-value形式存入分布式数据库中 
  42.       DataModle dataModle=new DataModle(); 
  43.       dataModle.setTemp(temp); 
  44.       dataModle.setHumi(humi); 
  45.       dataModle.setCo2(co2); 
  46.       String jsonString= ZSONObject.toZSONString(dataModle); 
  47.       singleKvStore.putString("data",jsonString); 
  48.     } catch (KvStoreException e) { 
  49.       LogUtils.debug(TAG, "DataServiceAbility::updateData()"+e.getMessage()); 
  50.     } 
  51.   } 
  52.   private void createForeService() { 
  53.     // 创建通知,其中1005为notificationId 
  54.     request = new NotificationRequest(1005); 
  55.     NotificationRequest.NotificationNormalContent content = new NotificationRequest.NotificationNormalContent(); 
  56.     content.setTitle("农业大棚").setText("数据采集服务开启中"); 
  57.     NotificationRequest.NotificationContent notificationContent = new NotificationRequest.NotificationContent(content); 
  58.     request.setContent(notificationContent); 
  59.     //绑定通知,1005为创建通知时传入的notificationId 
  60.     keepBackgroundRunning(1005, request); 
  61.   } 
  62.   @Override 
  63.   public void onBackground() { 
  64.     super.onBackground(); 
  65.     LogUtils.debug(TAG, "DataServiceAbility::onBackground()"); 
  66.   } 
  67.  
  68.   @Override 
  69.   public void onStop() { 
  70.     super.onStop(); 
  71.     if (mTimerTask != null) { 
  72.       mTimerTask.cancel(); 
  73.       mTimerTask=null
  74.     } if (mTimer != null) { 
  75.       mTimer.cancel(); 
  76.       mTimer=null
  77.     } 
  78.     //停止前台Service。 
  79.     cancelBackgroundRunning(); 
  80.     LogUtils.debug(TAG, "DataServiceAbility::onStop()"); 
  81.   } 
  82.  
  83.   @Override 
  84.   public void onCommand(Intent intent, boolean restart, int startId) { 
  85.   } 
  86.   @Override 
  87.   public IRemoteObject onConnect(Intent intent) { 
  88.     return null
  89.   } 
  90.   @Override 
  91.   public void onDisconnect(Intent intent) { 
  92.   } 

3.DBUtils

  1. public class DBUtils { 
  2.   private static KvManager kvManager; 
  3.   private static SingleKvStore singleKvStore; 
  4.   public static String KV_STORE_NAME="farm_data"
  5.   //具体的实现数据库的初始化 
  6.   public static SingleKvStore initOrGetDB(Context context, String storeId) { 
  7.     KvManagerConfig kvManagerConfig = new KvManagerConfig(context); 
  8.     kvManager = KvManagerFactory.getInstance().createKvManager(kvManagerConfig); 
  9.     Options options = new Options(); 
  10.     options.setCreateIfMissing(true
  11.         .setEncrypt(false
  12.         .setKvStoreType(KvStoreType.SINGLE_VERSION) 
  13.         .setAutoSync(false);//自动同步为true,手动同步为false 
  14.     singleKvStore = kvManager.getKvStore(options, storeId); 
  15.     return singleKvStore; 
  16.   } 
  17.   // 如果数据库中的字段有修改,只能先关闭,后删除,然后重新创建才生效 
  18.   public static void clearDB() { 
  19.     kvManager.closeKvStore(singleKvStore); 
  20.     kvManager.deleteKvStore(KV_STORE_NAME); 
  21.   } 

4. MainAbility

  1. @Override 
  2.  public void onStart(Intent intent) { 
  3.      super.onStart(intent); 
  4.      super.setMainRoute(PhoneAbilitySlice.class.getName()); 
  5.      //实现Ability的代码中显式声明需要使用多设备协同访问的权限 
  6.      requestPermissionsFromUser(new String[]{"ohos.permission.DISTRIBUTED_DATASYNC",}, 0); 
  7.  } 

 5. DataModle

  1. public class DataModle { 
  2.   private double temp
  3.   private double humi; 
  4.   private double co2; 
  5.   public double getTemp() { 
  6.     return temp
  7.   } 
  8.   public void setTemp(double temp) { 
  9.     this.temp = temp
  10.   } 
  11.  
  12.   public double getHumi() { 
  13.     return humi; 
  14.   } 
  15.   public void setHumi(double humi) { 
  16.     this.humi = humi; 
  17.   } 
  18.   public double getCo2() { 
  19.     return co2; 
  20.   } 
  21.   public void setCo2(double co2) { 
  22.     this.co2 = co2; 
  23.   } 

6. DeviceData

  1. public class DeviceData { 
  2.     private boolean isChecked; 
  3.     private DeviceInfo deviceInfo; 
  4.     /** 
  5.      * DeviceData 
  6.      * 
  7.      * @param isChecked isChecked 
  8.      * @param deviceInfo deviceInfo 
  9.      */ 
  10.     public DeviceData(boolean isChecked, DeviceInfo deviceInfo) { 
  11.         this.isChecked = isChecked; 
  12.         this.deviceInfo = deviceInfo; 
  13.     } 
  14.     public DeviceInfo getDeviceInfo() { 
  15.         return deviceInfo; 
  16.     } 
  17.     public void setDeviceInfo(DeviceInfo deviceInfo) { 
  18.         this.deviceInfo = deviceInfo; 
  19.     } 
  20.     public boolean isChecked() { 
  21.         return isChecked; 
  22.     } 
  23.     public void setChecked(boolean checked) { 
  24.         isChecked = checked; 
  25.     } 

7. DevicesProvider

  1. public class DevicesProvider extends BaseItemProvider { 
  2.  
  3.  private List<DeviceData> data; 
  4.  private LayoutScatter layoutScatter; 
  5.  
  6.  public DevicesProvider(Context context, List<DeviceData> data) { 
  7.    this.data = data; 
  8.    this.layoutScatter = LayoutScatter.getInstance(context); 
  9.  } 
  10.  
  11.  @Override 
  12.  public int getCount() { 
  13.    return data.size(); 
  14.  } 
  15.  
  16.  @Override 
  17.  public Object getItem(int i) { 
  18.    return data.get(i); 
  19.  } 
  20.  
  21.  @Override 
  22.  public long getItemId(int i) { 
  23.    return i; 
  24.  } 
  25.  
  26.  @Override 
  27.  public Component getComponent(int position, Component component, 
  28.      ComponentContainer componentContainer) { 
  29.    ViewHolder viewHolder; 
  30.    // component相当于Android中的view,其他的和Android中ListView的适配器adapter差不多。 
  31.    // 名字区别也不大,不过Android中ListView基本被淘汰了。 
  32.    if (component == null) { 
  33.      component = layoutScatter.parse(ResourceTable.Layout_dialog_device_item, nullfalse); 
  34.      viewHolder = new ViewHolder(); 
  35.      viewHolder.imgType = (Image) component.findComponentById(ResourceTable.Id_item_type); 
  36.      viewHolder.tvName = (Text) component.findComponentById(ResourceTable.Id_item_name); 
  37.      viewHolder.imgCheck = (Image) component.findComponentById(ResourceTable.Id_item_check); 
  38.      component.setTag(viewHolder); 
  39.    } else { 
  40.      viewHolder = (ViewHolder) component.getTag(); 
  41.    } 
  42.    DeviceData deviceData = data.get(position); 
  43.    DeviceType deviceType=deviceData.getDeviceInfo().getDeviceType(); 
  44.    switch (deviceType){ 
  45.      case SMART_WATCH: 
  46.        viewHolder.imgType.setPixelMap(ResourceTable.Media_dv_watch); 
  47.        break; 
  48.      case SMART_PAD: 
  49.        viewHolder.imgType.setPixelMap(ResourceTable.Media_dv_pad); 
  50.        break; 
  51.      case SMART_PHONE: 
  52.        viewHolder.imgType.setPixelMap(ResourceTable.Media_dv_phone); 
  53.        break; 
  54.    } 
  55.    viewHolder.tvName.setText(deviceData.getDeviceInfo().getDeviceName()); 
  56.    if(deviceData.isChecked()){ 
  57. viewHolder.imgCheck.setImageAndDecodeBounds(ResourceTable.Media_check2); }else {  viewHolder.imgCheck.setImageAndDecodeBounds(ResourceTable.Media_uncheck2); 
  58.    } 
  59.    return component; 
  60.  } 
  61.  
  62.  /** 
  63.   * 类似于Android中的listView缓存。 将已经显示在屏幕上的item缓存在ViewHolder中,下次再次出现直接从缓存中读取 
  64.   */ 
  65.  private static class ViewHolder { 
  66.    private Image imgType; 
  67.    private Text tvName; 
  68.    private Image imgCheck; 
  69.  } 

8. CustomerDialog

  1. public class CustomerDialog { 
  2.   public static void showToastDialog(Context context, String str) { 
  3.     DirectionalLayout toastLayout = (DirectionalLayout) LayoutScatter.getInstance(context) 
  4.         .parse(ResourceTable.Layout_toast_dialog, nullfalse); 
  5.     Text text = (Text) toastLayout.findComponentById(ResourceTable.Id_toast); 
  6.     text.setText(str); 
  7.     new ToastDialog(context) 
  8.         .setContentCustomComponent(toastLayout) 
  9.         .setSize(DirectionalLayout.LayoutConfig.MATCH_CONTENT, 
  10.             DirectionalLayout.LayoutConfig.MATCH_CONTENT) 
  11.         .setAlignment(LayoutAlignment.CENTER) 
  12.         .show(); 
  13.   } 

9. MyApplication

  1.   @Override 
  2.   public void onInitialize() { 
  3.     super.onInitialize(); 
  4.   } 

 10. config.json 文件

  1. "app": { 
  2.   "bundleName"" com.isoftstone.distributeddata "
  3.   "vendor""isoftstone"
  4.   "version": { 
  5.     "code": 1000000, 
  6.     "name""1.0.0" 
  7.   } 
  8. }, 
  9. "deviceConfig": {}, 
  10. "module": { 
  11.   "package""com.isoftstone.distributeddata"
  12.   "name"".MyApplication"
  13.   "mainAbility""com.isoftstone.distributeddata.MainAbility"
  14.   "deviceType": [ 
  15.     "phone" 
  16.   ], 
  17.   "distro": { 
  18.     "deliveryWithInstall"true
  19.     "moduleName""entry"
  20.     "moduleType""entry"
  21.     "installationFree"false 
  22.   }, 
  23.   "reqPermissions": [ 
  24.     { 
  25.       "name""ohos.permission.DISTRIBUTED_DATASYNC" 
  26.     }, 
  27.     { 
  28. 添加此权限,才能查找分布式在线设备 
  29.       "name""ohos.permission.GET_DISTRIBUTED_DEVICE_INFO" 
  30.     }, 
  31.     { 
  32. 将service设置为前台服务,需要添加的权限 
  33.       "name""ohos.permission.KEEP_BACKGROUND_RUNNING"  
  34.     } 
  35.   ], 
  36.   "abilities": [ 
  37.     { 
  38.       "skills": [ 
  39.         { 
  40.           "entities": [ 
  41.             "entity.system.home" 
  42.           ], 
  43.           "actions": [ 
  44.             "action.system.home" 
  45.           ] 
  46.         } 
  47.       ], 
  48.       "orientation""unspecified"
  49.       "name""com.isoftstone.distributeddata.MainAbility"
  50.       "icon""$media:icon"
  51.       "description""$string:mainability_description"
  52.       "label""$string:entry_MainAbility"
  53.       "type""page"
  54.       "launchType""standard" 
  55.     }, 
  56.     { 
  57.       "name""com.isoftstone.distributeddata.DataServiceAbility"
  58.       "icon""$media:icon"
  59.       "description""$string:dataserviceability_description"
  60.       "type""service"
  61.       "visible"true
  62.       "backgroundModes": [ 
  63.         "dataTransfer"
  64.         "location" 
  65.       ] 
  66.     } 
  67.  
  68.   ], 
  69.   "metaData": { 
  70.     "customizeData": [ 
  71.       { 
  72.         "name""hwc-theme"
  73.         "value""androidhwext:style/Theme.Emui.NoTitleBar"
  74.         "extra""" 
  75.       } 
  76.     ] 
  77.   } 

11.ability_main.xml布局文件

  1. <?xml version="1.0" encoding="utf-8"?> 
  2. <DirectionalLayout 
  3.   xmlns:ohos="http://schemas.huawei.com/res/ohos" 
  4.   ohos:height="match_parent" 
  5.   ohos:width="match_parent" 
  6.   ohos:orientation="vertical"
  7.  
  8.   <DependentLayout 
  9.     ohos:width="match_parent" 
  10.     ohos:height="match_content" 
  11.     ohos:orientation="horizontal" 
  12.     ohos:top_padding="50vp" 
  13.     ohos:bottom_padding="20vp" 
  14.     ohos:left_padding="20vp" 
  15.     ohos:right_padding="20vp" 
  16.     ohos:background_element="$graphic:background_ability_main"
  17.     <Text 
  18.       ohos:width="match_content" 
  19.       ohos:height="match_content" 
  20.       ohos:text="农业大棚数据监测" 
  21.       ohos:text_size="26vp" 
  22.       ohos:text_color="#ffffff" 
  23.       ohos:center_in_parent="true"/> 
  24.     <Button 
  25.       ohos:id="$+id:bt_continue" 
  26.       ohos:width="25vp" 
  27.       ohos:height="25vp" 
  28.       ohos:background_element="$media:conti" 
  29.       ohos:align_parent_right="true" 
  30.       ohos:vertical_center="true"/> 
  31.   </DependentLayout> 
  32.   <DependentLayout 
  33.     ohos:height="match_content" 
  34.     ohos:width="match_parent" 
  35.     ohos:background_element="#f4f5f7" 
  36.     ohos:left_padding="15vp" 
  37.     ohos:right_padding="15vp" 
  38.     ohos:top_padding="10vp" 
  39.     ohos:bottom_padding="10vp"
  40.  
  41.     <Text 
  42.       ohos:height="match_content" 
  43.       ohos:width="match_content" 
  44.       ohos:text="温度:" 
  45.       ohos:text_color="#000000" 
  46.       ohos:text_size="18fp" 
  47.       ohos:vertical_center="true"/> 
  48.  
  49.     <Text 
  50.       ohos:id="$+id:text_temp" 
  51.       ohos:height="match_content" 
  52.       ohos:width="match_content" 
  53.       ohos:text="数据正在采集 " 
  54.       ohos:text_color="#00ff00" 
  55.       ohos:text_size="18fp" 
  56.       ohos:left_margin="50vp" 
  57.       ohos:vertical_center="true"/> 
  58.   </DependentLayout> 
  59.  
  60.   <Component 
  61.     ohos:height="2vp" 
  62.     ohos:width="match_content" 
  63.     ohos:background_element="#FFFFFF"/> 
  64.  
  65.   <DependentLayout 
  66.     ohos:height="match_content" 
  67.     ohos:width="match_parent" 
  68.     ohos:background_element="#f4f5f7" 
  69.     ohos:left_padding="15vp" 
  70.     ohos:right_padding="15vp" 
  71.     ohos:top_padding="10vp" 
  72.     ohos:bottom_padding="10vp"
  73.  
  74.     <Text 
  75.       ohos:height="match_content" 
  76.       ohos:width="match_content" 
  77.       ohos:text="湿度:" 
  78.       ohos:text_color="#000000" 
  79.       ohos:text_size="18fp" 
  80.       ohos:vertical_center="true"/> 
  81.  
  82.     <Text 
  83.       ohos:id="$+id:text_humi" 
  84.       ohos:height="match_content" 
  85.       ohos:width="match_content" 
  86.       ohos:text="数据正在采集 " 
  87.       ohos:text_color="#00ff00" 
  88.       ohos:text_size="18fp" 
  89.       ohos:left_margin="50vp" 
  90.       ohos:vertical_center="true"/> 
  91.   </DependentLayout> 
  92.  
  93.   <Component 
  94.     ohos:height="2vp" 
  95.     ohos:width="match_content" 
  96.     ohos:background_element="#FFFFFF"/> 
  97.  
  98.   <DependentLayout 
  99.     ohos:height="match_content" 
  100.     ohos:width="match_parent" 
  101.     ohos:background_element="#f4f5f7" 
  102.     ohos:left_padding="15vp" 
  103.     ohos:right_padding="15vp" 
  104.     ohos:top_padding="10vp" 
  105.     ohos:bottom_padding="10vp"
  106.  
  107.     <Text 
  108.       ohos:height="match_content" 
  109.       ohos:width="match_content" 
  110.       ohos:text="CO2:" 
  111.       ohos:text_color="#000000" 
  112.       ohos:text_size="18fp" 
  113.       ohos:vertical_center="true"/> 
  114.  
  115.     <Text 
  116.       ohos:id="$+id:text_co2" 
  117.       ohos:height="match_content" 
  118.       ohos:width="match_content" 
  119.       ohos:text="数据正在采集 " 
  120.       ohos:text_color="#00ff00" 
  121.       ohos:text_size="18fp" 
  122.       ohos:left_margin="50vp" 
  123.       ohos:vertical_center="true"/> 
  124.   </DependentLayout> 
  125.  
  126.  
  127. </DirectionalLayout> 

12. dialog_device_item.xml

  1. <?xml version="1.0" encoding="utf-8"?> 
  2. <DirectionalLayout 
  3.     xmlns:ohos="http://schemas.huawei.com/res/ohos" 
  4.     ohos:height="70vp" 
  5.     ohos:width="match_parent" 
  6.     ohos:orientation="horizontal"
  7.  
  8.     <Image 
  9.         ohos:id="$+id:item_type" 
  10.         ohos:height="45vp" 
  11.         ohos:width="50vp" 
  12.         ohos:image_src="$media:dv_phone" 
  13.         ohos:layout_alignment="vertical_center" 
  14.         ohos:left_margin="10vp" 
  15.         ohos:scale_mode="inside"/> 
  16.  
  17.     <Text 
  18.         ohos:id="$+id:item_name" 
  19.         ohos:height="match_parent" 
  20.         ohos:width="0vp" 
  21.         ohos:max_text_lines="1" 
  22.         ohos:text="Huawei P40" 
  23.         ohos:text_alignment="vertical_center" 
  24.         ohos:text_size="15fp" 
  25.         ohos:weight="1"/> 
  26.  
  27.     <Image 
  28.         ohos:id="$+id:item_check" 
  29.         ohos:height="30vp" 
  30.         ohos:width="30vp" 
  31.         ohos:image_src="$media:uncheck2" 
  32.  
  1. <DirectionalLayout 
  2.     xmlns:ohos="http://schemas.huawei.com/res/ohos" 
  3.     ohos:height="340vp" 
  4.     ohos:width="match_parent" 
  5.     ohos:orientation="vertical"
  6.  
  7.     <DirectionalLayout 
  8.         ohos:height="match_parent" 
  9.         ohos:width="match_parent" 
  10.         ohos:background_element="$graphic:background_white_radius_10" 
  11.         ohos:bottom_margin="50vp" 
  12.         ohos:left_margin="20vp" 
  13.         ohos:orientation="vertical" 
  14.         ohos:right_margin="20vp"
  15.  
  16.         <Text 
  17.             ohos:height="50vp" 
  18.             ohos:width="match_parent" 
  19.             ohos:left_padding="20vp" 
  20.             ohos:text="迁移到其他设备" 
  21.             ohos:text_alignment="vertical_center" 
  22.             ohos:text_color="#000000" 
  23.             ohos:text_size="16fp"/> 
  24.  
  25.         <ListContainer 
  26.             ohos:id="$+id:list_container_device" 
  27.             ohos:height="0vp" 
  28.             ohos:width="match_parent" 
  29.             ohos:weight="1"/> 
  30.  
  31.         <DirectionalLayout 
  32.             ohos:height="50vp" 
  33.             ohos:width="match_parent" 
  34.             ohos:orientation="horizontal"
  35.  
  36.             <Text 
  37.                 ohos:id="$+id:operate_no" 
  38.                 ohos:height="match_parent" 
  39.                 ohos:width="0vp" 
  40.                 ohos:text="取消" 
  41.                 ohos:text_alignment="center" 
  42.                 ohos:text_color="#1e90ff" 
  43.                 ohos:text_size="17fp" 
  44.                 ohos:weight="1"/> 
  45.  
  46.             <Component 
  47.                 ohos:height="25vp" 
  48.                 ohos:width="1vp" 
  49.                 ohos:background_element="#cccccc" 
  50.                 ohos:layout_alignment="vertical_center"/> 
  51.  
  52.             <Text 
  53.                 ohos:id="$+id:operate_yes" 
  54.                 ohos:height="match_parent" 
  55.                 ohos:width="0vp" 
  56.                 ohos:text="确定" 
  57.                 ohos:text_alignment="center" 
  58.                 ohos:text_color="#1e90ff" 
  59.                 ohos:text_size="17fp" 
  60.                 ohos:weight="1"/> 
  61.         </DirectionalLayout> 
  62.     </DirectionalLayout> 
  63. </DirectionalLayout> 

14. toast_dialog.xml

  1. <DirectionalLayout 
  2.     xmlns:ohos="http://schemas.huawei.com/res/ohos" 
  3.     ohos:height="match_content" 
  4.     ohos:width="match_content" 
  5.     ohos:orientation="vertical" 
  6.     ohos:background_element="$graphic:background_gray_circle"
  7.     <Text 
  8.         ohos:id="$+id:toast" 
  9.         ohos:height="match_content" 
  10.         ohos:width="match_content" 
  11.         ohos:left_padding="16vp" 
  12.         ohos:right_padding="16vp" 
  13.         ohos:top_padding="4vp" 
  14.         ohos:bottom_padding="4vp" 
  15.         ohos:layout_alignment="center" 
  16.         ohos:text_size="20fp"/> 
  17. </DirectionalLayout> 

TV端

1. TVAbilitySlice

  1.   private Text tvTemp; 
  2.     private Text tvTempMax; 
  3.     private Text tvTempMin; 
  4.  
  5.     private Text tvHumi; 
  6.     private Text tvHumiMax; 
  7.     private Text tvHumiMin; 
  8.  
  9.     private Text tvCgas; 
  10.     private Text tvCgasMax; 
  11.     private Text tvCgasMin; 
  12.  
  13.     private Text tvTempStatus; 
  14.     private Text tvHumiStatus; 
  15.     private Text tvCgasStatus; 
  16.  
  17.  
  18.     private ProgressBar rgbTem; 
  19.     private ProgressBar rgbHumi; 
  20.     private ProgressBar rgbCgas; 
  21.  
  22.     private static final HiLogLabel label = new HiLogLabel(HiLog.LOG_APP, 0x0001, "my_log"); 
  23.  
  24.     private double temp
  25.     private double humi; 
  26.     private double cGas; 
  27.     private SingleKvStore singleKvStore; 
  28.     private KvStoreObserverClient kvStoreObserverClient; 
  29.  
  30.     @Override 
  31.     public void onStart(Intent intent) { 
  32.         super.onStart(intent); 
  33.         super.setUIContent(ResourceTable.Layout_ability_tv); 
  34.         //设置沉浸式状态栏 
  35.         getWindow().addFlags(WindowManager.LayoutConfig.MARK_TRANSLUCENT_STATUS); 
  36.  
  37.         tvTemp = (Text) findComponentById(ResourceTable.Id_tvTemp); 
  38.         tvTempMax = (Text) findComponentById(ResourceTable.Id_tvMaxTemp); 
  39.         tvTempMin = (Text) findComponentById(ResourceTable.Id_tvMinTemp); 
  40.         rgbTem = (RoundProgressBar) findComponentById(ResourceTable.Id_rgb_tem); 
  41.  
  42.         tvHumi = (Text) findComponentById(ResourceTable.Id_tvHumi); 
  43.         tvHumiMax = (Text) findComponentById(ResourceTable.Id_tvMaxHumi); 
  44.         tvHumiMin = (Text) findComponentById(ResourceTable.Id_tvMinHumi); 
  45.         rgbHumi = (RoundProgressBar) findComponentById(ResourceTable.Id_rgb_humi); 
  46.  
  47.         tvCgas = (Text) findComponentById(ResourceTable.Id_tvCgas); 
  48.         tvCgasMax = (Text) findComponentById(ResourceTable.Id_tvMaxCgas); 
  49.         tvCgasMin = (Text) findComponentById(ResourceTable.Id_tvMinCgas); 
  50.         rgbCgas = (RoundProgressBar) findComponentById(ResourceTable.Id_rgb_gas); 
  51.  
  52.         tvTempStatus = (Text) findComponentById(ResourceTable.Id_tvTempStatus); 
  53.         tvHumiStatus = (Text) findComponentById(ResourceTable.Id_tvHumiStatus); 
  54.         tvCgasStatus = (Text) findComponentById(ResourceTable.Id_tvCgasStatus); 
  55.  
  56.         try { 
  57.             KvManagerConfig config = new KvManagerConfig(getContext()); 
  58.             KvManager kvManager = KvManagerFactory.getInstance().createKvManager(config); 
  59.             Options CREATE = new Options(); 
  60.             CREATE.setCreateIfMissing(true).setEncrypt(false
  61.                 .setKvStoreType(KvStoreType.SINGLE_VERSION) 
  62.                 .setAutoSync(true); 
  63.             singleKvStore = kvManager.getKvStore(CREATE, DBUtils.KV_STORE_NAME); 
  64.             kvStoreObserverClient = new KvStoreObserverClient(); 
  65.             singleKvStore.subscribe(SubscribeType.SUBSCRIBE_TYPE_ALL, kvStoreObserverClient); 
  66.         } catch (Exception e) { 
  67.             e.printStackTrace(); 
  68.         } 
  69.  
  70.     } 
  71.  
  72.     private class KvStoreObserverClient implements KvStoreObserver { 
  73.  
  74.         @Override 
  75.         public void onChange(ChangeNotification notification) { 
  76.             //onChange方法实质上,在一个子线程里执行 
  77.             getUITaskDispatcher().asyncDispatch(() -> { 
  78.                 //在这里执行页面ui组件的显示刷新 
  79.                 asyncUpdateData(); 
  80.             }); 
  81.         } 
  82.     } 
  83.  
  84.  
  85.     public void asyncUpdateData(){ 
  86.         //查询分布式数据的数据 
  87.         List<Entry> entries = singleKvStore.getEntries("data"); 
  88.         if (entries.size() > 0) { 
  89.             ZSONObject zsonObject = ZSONObject.stringToZSON(entries.get(0).getValue().getString()); 
  90.             double temp = zsonObject.getDouble("temp"); 
  91.             double humi = zsonObject.getDouble("humi"); 
  92.             double co2 = zsonObject.getDouble("co2"); 
  93.             String strTemp = String.format("%.1f"temp); 
  94.             String strHumi = String.format("%.1f", humi); 
  95.             String strCO2 = String.format("%.1f", co2); 
  96.             initView(strTemp,strHumi,strCO2); 
  97.  
  98.         } 
  99.     } 
  100.  
  101.     private void initView(String strTemp,String strHumi,String strCO2) { 
  102.         temp = Double.valueOf(strTemp); 
  103.         int tempMax = 45; 
  104.         int tempMin = -10; 
  105.  
  106.         humi = Double.valueOf(strHumi); 
  107.         int humiMax = 70; 
  108.         int humiMin = 10; 
  109.  
  110.         cGas = Double.valueOf(strCO2); 
  111.         int cGasMax = 1000; 
  112.  
  113.         if (temp > -100) { 
  114.             if (temp > tempMax || temp < tempMin) { 
  115.                 tvTemp.setTextColor(Color.RED); 
  116.                 tvTempStatus.setText("异常"); 
  117.                 tvTempStatus.setTextColor(Color.RED); 
  118.                 rgbTem.setProgressColor(Color.RED); 
  119.             } else { 
  120.                 tvTemp.setTextColor(Color.GREEN); 
  121.                 tvTempStatus.setText("正常"); 
  122.                 tvTempStatus.setTextColor(Color.GREEN); 
  123.                 rgbTem.setProgressColor(Color.GREEN); 
  124.  
  125.             } 
  126.         } else { 
  127.             tvTemp.setTextColor(Color.BLACK); 
  128.             tvTempStatus.setTextColor(Color.BLACK); 
  129.             tvTempStatus.setText("未知"); 
  130.             rgbTem.setProgressColor(Color.GREEN); 
  131.  
  132.         } 
  133.         tvTempMax.setText(tempMax + "℃"); 
  134.         tvTempMin.setText(tempMin + "℃"); 
  135.  
  136.         if (humi > -100) { 
  137.             if (humi > humiMax || humi < humiMin) { 
  138.                 tvHumi.setTextColor(Color.RED); 
  139.                 tvHumiStatus.setText("异常"); 
  140.                 tvHumiStatus.setTextColor(Color.RED); 
  141.                 rgbHumi.setProgressColor(Color.RED); 
  142.             } else { 
  143.                 tvHumi.setTextColor(Color.GREEN); 
  144.                 tvHumiStatus.setText("正常"); 
  145.                 tvHumiStatus.setTextColor(Color.GREEN); 
  146.                 rgbHumi.setProgressColor(Color.GREEN); 
  147.             } 
  148.         } else { 
  149.             tvHumi.setTextColor(Color.BLACK); 
  150.             tvHumiStatus.setText("未知"); 
  151.             tvHumiStatus.setTextColor(Color.BLACK); 
  152.             rgbHumi.setProgressColor(Color.GREEN); 
  153.  
  154.         } 
  155.         tvHumiMax.setText(humiMax + "% RH"); 
  156.         tvHumiMin.setText(humiMin + "% RH"); 
  157.  
  158.         if (cGas > -100) { 
  159.             if (cGas > cGasMax) { 
  160.                 tvCgas.setTextColor(Color.RED); 
  161.                 tvCgasStatus.setText("异常"); 
  162.                 tvCgasStatus.setTextColor(Color.RED); 
  163.                 rgbCgas.setProgressColor(Color.RED); 
  164.             } else { 
  165.                 tvCgas.setTextColor(Color.GREEN); 
  166.                 tvCgasStatus.setText("正常"); 
  167.                 tvCgasStatus.setTextColor(Color.GREEN); 
  168.             } 
  169.         } else { 
  170.             tvCgas.setTextColor(Color.BLACK); 
  171.             tvCgasStatus.setText("未知"); 
  172.             tvCgasStatus.setTextColor(Color.BLACK); 
  173.             rgbCgas.setProgressColor(Color.GREEN); 
  174.  
  175.         } 
  176.  
  177.         tvCgasMax.setText(cGasMax + " ppm"); 
  178.  
  179.         tvCgasMin.setText(0 + " ppm"); 
  180.  
  181.         if (temp <= -100) { 
  182.             tvTemp.setText("未知"); 
  183.             rgbTem.setProgressValue(0); 
  184.         } else { 
  185.             tvTemp.setText(temp + "℃"); 
  186.             rgbTem.setProgressValue((inttemp); 
  187.         } 
  188.         if (humi <= -100) { 
  189.             tvHumi.setText("未知"); 
  190.             rgbHumi.setProgressValue(0); 
  191.         } else { 
  192.             tvHumi.setText(humi + "% RH"); 
  193.             rgbHumi.setProgressValue((int) humi); 
  194.         } 
  195.         if (cGas <= -100) { 
  196.             tvCgas.setText("未知"); 
  197.             rgbCgas.setProgressValue(0); 
  198.         } else { 
  199.             tvCgas.setText(cGas + " ppm"); 
  200.             rgbCgas.setProgressValue((int) cGas); 
  201.         } 
  202.  
  203.     } 
  204.  
  205.  
  206.     @Override 
  207.     protected void onStop() { 
  208.         super.onStop(); 
  209.         //解除订阅 
  210. //        if (singleKvStore != null) { 
  211. //            if(kvStoreObserverClient!=null){ 
  212. //                singleKvStore.unSubscribe(kvStoreObserverClient); 
  213. //            } 
  214. //        } 
  215.     } 

2. TVAbility

  1. public class TVAbility extends Ability { 
  2.  
  3.   @Override 
  4.   public void onStart(Intent intent) { 
  5.     super.onStart(intent); 
  6.     super.setMainRoute(TVAbilitySlice.class.getName()); 
  7.     //实现Ability的代码中显式声明需要使用多设备协同访问的权限 
  8.     requestPermissionsFromUser(new String[]{"ohos.permission.DISTRIBUTED_DATASYNC",}, 0); 
  9.   } 

 3. ability_tv.xml

  1. <?xml version="1.0" encoding="utf-8"?> 
  2. <DirectionalLayout 
  3.   xmlns:ohos="http://schemas.huawei.com/res/ohos" 
  4.   ohos:height="match_parent" 
  5.   ohos:width="match_parent" 
  6.   ohos:orientation="vertical" 
  7.   ohos:background_element="$media:haibao"
  8.  
  9.   <Text 
  10.     ohos:height="match_content" 
  11.     ohos:width="match_content" 
  12.     ohos:text="大棚数据监测" 
  13.     ohos:text_color="#ffffff" 
  14.     ohos:text_size="26vp" 
  15.     ohos:layout_alignment="center" 
  16.     ohos:top_margin="50vp"/> 
  17.  
  18.   <DependentLayout 
  19.     ohos:height="match_parent" 
  20.     ohos:width="match_parent"
  21.  
  22.     <DirectionalLayout 
  23.       ohos:height="match_content" 
  24.       ohos:width="match_parent" 
  25.       ohos:left_padding="10vp" 
  26.       ohos:right_padding="10vp" 
  27.       ohos:center_in_parent="true" 
  28.       ohos:orientation="horizontal"
  29.       <DirectionalLayout 
  30.         ohos:height="match_content" 
  31.         ohos:width="0" 
  32.         ohos:weight="1" 
  33.         ohos:layout_alignment="center" 
  34.         ohos:orientation="vertical"
  35.         <Text 
  36.           ohos:height="match_content" 
  37.           ohos:width="match_content" 
  38.           ohos:text="温度数据" 
  39.           ohos:text_size="20vp" 
  40.           ohos:padding="5vp" 
  41.           ohos:text_color="#ffffff" 
  42.           ohos:layout_alignment="center"/> 
  43.         <DirectionalLayout 
  44.           ohos:height="3vp" 
  45.           ohos:width="match_parent" 
  46.           ohos:background_element="#ffffff" 
  47.           ohos:top_margin="15vp" 
  48.           ohos:left_margin="20vp" 
  49.           ohos:right_margin="20vp" 
  50.           ohos:layout_alignment="center" 
  51.           ohos:bottom_margin="15vp" 
  52.           ohos:visibility="invisible"/> 
  53.         <DirectionalLayout 
  54.           ohos:height="match_content" 
  55.           ohos:width="match_content" 
  56.           ohos:layout_alignment="center" 
  57.           ohos:orientation="horizontal"
  58.           <DirectionalLayout 
  59.             ohos:height="match_parent" 
  60.             ohos:width="match_content" 
  61.             ohos:orientation="vertical"
  62.             <Text 
  63.               ohos:height="0" 
  64.               ohos:width="match_content" 
  65.               ohos:text="最高温度阀值:" 
  66.               ohos:text_size="16vp" 
  67.               ohos:weight="1" 
  68.               ohos:text_color="#000000"/> 
  69.             <Text 
  70.               ohos:height="0" 
  71.               ohos:width="match_content" 
  72.               ohos:text="当前温度:" 
  73.               ohos:text_size="16vp" 
  74.               ohos:weight="1" 
  75.               ohos:text_color="#000000"/> 
  76.             <Text 
  77.               ohos:height="0" 
  78.               ohos:width="match_content" 
  79.               ohos:text="最低温度阀值:" 
  80.               ohos:text_size="16vp" 
  81.               ohos:weight="1" 
  82.               ohos:text_color="#000000"/> 
  83.           </DirectionalLayout> 
  84.  
  85.           <DependentLayout 
  86.             ohos:height="100vp" 
  87.             ohos:width="100vp"
  88.             <RoundProgressBar 
  89.               ohos:id="$+id:rgb_tem" 
  90.               ohos:height="match_parent" 
  91.               ohos:width="match_parent" 
  92.               ohos:progress_width="10vp" 
  93.               ohos:progress="0" 
  94.               ohos:max="100" 
  95.               ohos:start_angle="215" 
  96.               ohos:max_angle="290" 
  97.               ohos:progress_color="#00ff00" 
  98.               ohos:center_in_parent="true"/> 
  99.             <Text 
  100.               ohos:id="$+id:tvMaxTemp" 
  101.               ohos:height="match_content" 
  102.               ohos:width="match_content" 
  103.               ohos:text_size="15vp" 
  104.               ohos:text_color="#000000" 
  105.               ohos:align_parent_top="true" 
  106.               ohos:text="未知" 
  107.               ohos:top_margin="8vp" 
  108.               ohos:horizontal_center="true"/> 
  109.             <Text 
  110.               ohos:id="$+id:tvTemp" 
  111.               ohos:height="match_content" 
  112.               ohos:width="match_content" 
  113.               ohos:text_size="15vp" 
  114.               ohos:text_color="#000000" 
  115.               ohos:text="未知" 
  116.               ohos:center_in_parent="true"/> 
  117.             <Text 
  118.               ohos:id="$+id:tvMinTemp" 
  119.               ohos:height="match_content" 
  120.               ohos:width="match_content" 
  121.               ohos:text_size="14vp" 
  122.               ohos:text_color="#000000" 
  123.               ohos:text="未知" 
  124.               ohos:bottom_margin="8vp" 
  125.               ohos:align_parent_bottom="true" 
  126.               ohos:horizontal_center="true"/> 
  127.           </DependentLayout> 
  128.  
  129.         </DirectionalLayout> 
  130.  
  131.  
  132.         <DirectionalLayout 
  133.           ohos:height="3vp" 
  134.           ohos:width="match_parent" 
  135.           ohos:background_element="#ffffff" 
  136.           ohos:top_margin="15vp" 
  137.           ohos:left_margin="20vp" 
  138.           ohos:right_margin="20vp" 
  139.           ohos:layout_alignment="center" 
  140.           ohos:bottom_margin="15vp" 
  141.           ohos:visibility="invisible"/> 
  142.         <DirectionalLayout 
  143.           ohos:height="match_content" 
  144.           ohos:width="match_content" 
  145.           ohos:layout_alignment="center" 
  146.           ohos:orientation="horizontal"
  147.           <Text 
  148.             ohos:height="match_content" 
  149.             ohos:width="match_content" 
  150.             ohos:text="温度状态:" 
  151.             ohos:text_size="18vp" 
  152.             ohos:text_color="#000000"/> 
  153.           <Text 
  154.             ohos:id="$+id:tvTempStatus" 
  155.             ohos:height="match_content" 
  156.             ohos:width="match_content" 
  157.             ohos:text="未知" 
  158.             ohos:text_size="18vp" 
  159.             ohos:text_color="#000000"/> 
  160.         </DirectionalLayout> 
  161.       </DirectionalLayout> 
  162.  
  163.  
  164.       <DirectionalLayout 
  165.         ohos:height="90vp" 
  166.         ohos:width="1vp" 
  167.         ohos:background_element="#000000" 
  168.         ohos:top_margin="6vp" 
  169.         ohos:layout_alignment="center"/> 
  170.  
  171.       <DirectionalLayout 
  172.         ohos:height="match_content" 
  173.         ohos:width="0" 
  174.         ohos:weight="1" 
  175.         ohos:layout_alignment="center" 
  176.         ohos:orientation="vertical"
  177.         <Text 
  178.           ohos:height="match_content" 
  179.           ohos:width="match_content" 
  180.           ohos:text="湿度数据" 
  181.           ohos:text_size="20vp" 
  182.           ohos:padding="5vp" 
  183.           ohos:text_color="#ffffff" 
  184.           ohos:layout_alignment="center"/> 
  185.         <DirectionalLayout 
  186.           ohos:height="3vp" 
  187.           ohos:width="match_parent" 
  188.           ohos:background_element="#ffffff" 
  189.           ohos:top_margin="15vp" 
  190.           ohos:left_margin="20vp" 
  191.           ohos:right_margin="20vp" 
  192.           ohos:layout_alignment="center" 
  193.           ohos:bottom_margin="15vp" 
  194.           ohos:visibility="invisible"/> 
  195.  
  196.  
  197.         <DirectionalLayout 
  198.           ohos:height="match_content" 
  199.           ohos:width="match_content" 
  200.           ohos:layout_alignment="center" 
  201.           ohos:orientation="horizontal"
  202.           <DirectionalLayout 
  203.             ohos:height="match_parent" 
  204.             ohos:width="match_content" 
  205.             ohos:orientation="vertical"
  206.             <Text 
  207.               ohos:height="0" 
  208.               ohos:width="match_content" 
  209.               ohos:text="最大湿度阀值:" 
  210.               ohos:text_size="16vp" 
  211.               ohos:weight="1" 
  212.               ohos:text_color="#000000"/> 
  213.             <Text 
  214.               ohos:height="0" 
  215.               ohos:width="match_content" 
  216.               ohos:text="当前湿度:" 
  217.               ohos:text_size="16vp" 
  218.               ohos:weight="1" 
  219.               ohos:text_color="#000000"/> 
  220.             <Text 
  221.               ohos:height="0" 
  222.               ohos:width="match_content" 
  223.               ohos:text="最小湿度阀值:" 
  224.               ohos:text_size="16vp" 
  225.               ohos:weight="1" 
  226.               ohos:text_color="#000000"/> 
  227.           </DirectionalLayout> 
  228.  
  229.           <DependentLayout 
  230.             ohos:height="100vp" 
  231.             ohos:width="100vp"
  232.             <RoundProgressBar 
  233.               ohos:id="$+id:rgb_humi" 
  234.               ohos:height="match_parent" 
  235.               ohos:width="match_parent" 
  236.               ohos:progress_width="10vp" 
  237.               ohos:progress="0" 
  238.               ohos:max="100" 
  239.               ohos:start_angle="215" 
  240.               ohos:max_angle="290" 
  241.               ohos:progress_color="#00ff00" 
  242.               ohos:center_in_parent="true"/> 
  243.             <Text 
  244.               ohos:id="$+id:tvMaxHumi" 
  245.               ohos:height="match_content" 
  246.               ohos:width="match_content" 
  247.               ohos:text_size="15vp" 
  248.               ohos:text_color="#000000" 
  249.               ohos:text="未知" 
  250.               ohos:top_margin="8vp" 
  251.               ohos:horizontal_center="true" 
  252.               ohos:align_parent_top="true"/> 
  253.             <Text 
  254.               ohos:id="$+id:tvHumi" 
  255.               ohos:height="match_content" 
  256.               ohos:width="match_content" 
  257.               ohos:text_size="15vp" 
  258.               ohos:text_color="#000000" 
  259.               ohos:text="未知" 
  260.               ohos:center_in_parent="true"/> 
  261.             <Text 
  262.               ohos:id="$+id:tvMinHumi" 
  263.               ohos:height="match_content" 
  264.               ohos:width="match_content" 
  265.               ohos:text_size="15vp" 
  266.               ohos:text_color="#000000" 
  267.               ohos:horizontal_center="true" 
  268.               ohos:text="未知" 
  269.               ohos:bottom_margin="8vp" 
  270.               ohos:align_parent_bottom="true"/> 
  271.           </DependentLayout> 
  272.  
  273.         </DirectionalLayout> 
  274.  
  275.         <DirectionalLayout 
  276.           ohos:height="3vp" 
  277.           ohos:width="match_parent" 
  278.           ohos:background_element="#ffffff" 
  279.           ohos:top_margin="15vp" 
  280.           ohos:left_margin="20vp" 
  281.           ohos:right_margin="20vp" 
  282.           ohos:layout_alignment="center" 
  283.           ohos:bottom_margin="15vp" 
  284.           ohos:visibility="invisible"/> 
  285.         <DirectionalLayout 
  286.           ohos:height="match_content" 
  287.           ohos:width="match_content" 
  288.           ohos:layout_alignment="center" 
  289.           ohos:orientation="horizontal"
  290.           <Text 
  291.             ohos:height="match_content" 
  292.             ohos:width="match_content" 
  293.             ohos:text="湿度状态:" 
  294.             ohos:text_size="18vp" 
  295.             ohos:text_color="#000000"/> 
  296.           <Text 
  297.             ohos:id="$+id:tvHumiStatus" 
  298.             ohos:height="match_content" 
  299.             ohos:width="match_content" 
  300.             ohos:text="未知" 
  301.             ohos:text_size="18vp" 
  302.             ohos:text_color="#000000"/> 
  303.         </DirectionalLayout> 
  304.  
  305.       </DirectionalLayout> 
  306.  
  307.  
  308.  
  309.       <DirectionalLayout 
  310.         ohos:height="90vp" 
  311.         ohos:width="1vp" 
  312.         ohos:background_element="#000000" 
  313.         ohos:top_margin="6vp" 
  314.         ohos:layout_alignment="center"/> 
  315.  
  316.  
  317.  
  318.  
  319.       <DirectionalLayout 
  320.         ohos:height="match_content" 
  321.         ohos:width="0" 
  322.         ohos:weight="1" 
  323.         ohos:layout_alignment="center" 
  324.         ohos:orientation="vertical"
  325.         <Text 
  326.           ohos:height="match_content" 
  327.           ohos:width="match_content" 
  328.           ohos:text="CO2数据" 
  329.           ohos:text_size="20vp" 
  330.           ohos:padding="5vp" 
  331.           ohos:text_color="#ffffff" 
  332.           ohos:layout_alignment="center"/> 
  333.         <DirectionalLayout 
  334.           ohos:height="3vp" 
  335.           ohos:width="match_parent" 
  336.           ohos:background_element="#ffffff" 
  337.           ohos:top_margin="15vp" 
  338.           ohos:left_margin="20vp" 
  339.           ohos:right_margin="20vp" 
  340.           ohos:layout_alignment="center" 
  341.           ohos:bottom_margin="15vp" 
  342.           ohos:visibility="invisible"/> 
  343.         <DirectionalLayout 
  344.           ohos:height="match_content" 
  345.           ohos:width="match_content" 
  346.           ohos:layout_alignment="center" 
  347.           ohos:orientation="horizontal"
  348.           <DirectionalLayout 
  349.             ohos:height="match_parent" 
  350.             ohos:width="match_content" 
  351.             ohos:orientation="vertical"
  352.             <Text 
  353.               ohos:height="0" 
  354.               ohos:width="match_content" 
  355.               ohos:text="最大气体增量:" 
  356.               ohos:text_size="16vp" 
  357.               ohos:weight="1" 
  358.               ohos:text_color="#000000"/> 
  359.             <Text 
  360.               ohos:height="0" 
  361.               ohos:width="match_content" 
  362.               ohos:text="当前增量:" 
  363.               ohos:text_size="16vp" 
  364.               ohos:weight="1" 
  365.               ohos:text_color="#000000"/> 
  366.             <Text 
  367.               ohos:height="0" 
  368.               ohos:width="match_content" 
  369.               ohos:text="最小气体增量:" 
  370.               ohos:text_size="16vp" 
  371.               ohos:weight="1" 
  372.               ohos:text_color="#000000"/> 
  373.           </DirectionalLayout> 
  374.  
  375.           <DependentLayout 
  376.             ohos:height="100vp" 
  377.             ohos:width="100vp"
  378.             <RoundProgressBar 
  379.               ohos:id="$+id:rgb_gas" 
  380.               ohos:height="match_parent" 
  381.               ohos:width="match_parent" 
  382.               ohos:progress_width="10vp" 
  383.               ohos:progress="0" 
  384.               ohos:max="1000" 
  385.               ohos:start_angle="215" 
  386.               ohos:max_angle="290" 
  387.               ohos:progress_color="#00ff00" 
  388.               ohos:center_in_parent="true"/> 
  389.             <Text 
  390.               ohos:id="$+id:tvMaxCgas" 
  391.               ohos:height="match_content" 
  392.               ohos:width="match_content" 
  393.               ohos:text_size="15vp" 
  394.               ohos:text="未知" 
  395.               ohos:text_color="#000000" 
  396.               ohos:top_margin="8vp" 
  397.               ohos:horizontal_center="true" 
  398.               ohos:align_parent_top="true"/> 
  399.             <Text 
  400.               ohos:id="$+id:tvCgas" 
  401.               ohos:height="match_content" 
  402.               ohos:width="match_content" 
  403.               ohos:text_size="15vp" 
  404.               ohos:text="未知" 
  405.               ohos:text_color="#000000" 
  406.               ohos:center_in_parent="true"/> 
  407.             <Text 
  408.               ohos:id="$+id:tvMinCgas" 
  409.               ohos:height="match_content" 
  410.               ohos:width="match_content" 
  411.               ohos:text_size="15vp" 
  412.               ohos:text="未知" 
  413.               ohos:text_color="#000000" 
  414.               ohos:bottom_margin="8vp" 
  415.               ohos:horizontal_center="true" 
  416.               ohos:align_parent_bottom="true"/> 
  417.           </DependentLayout> 
  418.         </DirectionalLayout> 
  419.  
  420.         <DirectionalLayout 
  421.           ohos:height="3vp" 
  422.           ohos:width="match_parent" 
  423.           ohos:background_element="#ffffff" 
  424.           ohos:top_margin="15vp" 
  425.           ohos:left_margin="20vp" 
  426.           ohos:right_margin="20vp" 
  427.           ohos:layout_alignment="center" 
  428.           ohos:bottom_margin="15vp" 
  429.           ohos:visibility="invisible"/> 
  430.  
  431.  
  432.         <DirectionalLayout 
  433.           ohos:height="match_content" 
  434.           ohos:width="match_content" 
  435.           ohos:layout_alignment="center" 
  436.           ohos:orientation="horizontal"
  437.           <Text 
  438.             ohos:height="match_content" 
  439.             ohos:width="match_content" 
  440.             ohos:text="气体状态:" 
  441.             ohos:text_size="18vp" 
  442.             ohos:text_color="#000000"/> 
  443.           <Text 
  444.             ohos:id="$+id:tvCgasStatus" 
  445.             ohos:height="match_content" 
  446.             ohos:width="match_content" 
  447.             ohos:text="未知" 
  448.             ohos:text_size="18vp" 
  449.             ohos:text_color="#000000"/> 
  450.         </DirectionalLayout> 
  451.       </DirectionalLayout> 
  452.     </DirectionalLayout> 
  453.   </DependentLayout> 
  454.  
  455. </DirectionalLayout> 

4.config.json

  1.   "app": { 
  2.     "bundleName""com.isoftstone. distributeddata "
  3.     "vendor""isoftstone"
  4.     "version": { 
  5.       "code": 1000000, 
  6.       "name""1.0.0" 
  7.     } 
  8.   }, 
  9.   "deviceConfig": {}, 
  10.   "module": { 
  11.     "package""com.isoftstone.distributeddata"
  12.     "name"".MyApplication"
  13.     "mainAbility""com.isoftstone.distributeddata.com.isoftstone.distributeddata.TVAbility"
  14.     "deviceType": [ 
  15.       "phone" 
  16.     ], 
  17.     "distro": { 
  18.       "deliveryWithInstall"true
  19.       "moduleName""entry"
  20.       "moduleType""entry"
  21.       "installationFree"false 
  22.     }, 
  23.     "reqPermissions": [ 
  24.       { 
  25.         "name""ohos.permission.DISTRIBUTED_DATASYNC" 
  26.       } 
  27.     ], 
  28.     "abilities": [ 
  29.       { 
  30.         "skills": [ 
  31.           { 
  32.             "entities": [ 
  33.               "entity.system.home" 
  34.             ], 
  35.             "actions": [ 
  36.               "action.system.home" 
  37.             ] 
  38.           } 
  39.         ], 
  40.         "orientation""landscape"
  41.         "name""com.isoftstone.distributeddata.TVAbility"
  42.         "icon""$media:icon"
  43.         "description""$string:tvability_description"
  44.         "label""$string:entry_TVAbility"
  45.         "type""page"
  46.         "launchType""standard" 
  47.       } 
  48.     ], 
  49.     "metaData": { 
  50.       "customizeData": [ 
  51.         { 
  52.           "name""hwc-theme"
  53.           "value""androidhwext:style/Theme.Emui.NoTitleBar"
  54.           "extra""" 
  55.         } 
  56.       ] 
  57.     } 
  58.   } 

想了解更多内容,请访问:

51CTO和华为官方合作共建的鸿蒙技术社区

https://harmonyos.51cto.co

 

责任编辑:jianghua 来源: 鸿蒙社区
相关推荐

2021-12-13 11:07:10

鸿蒙HarmonyOS应用

2021-12-09 16:49:51

鸿蒙HarmonyOS应用

2019-02-13 13:41:07

MemCache分布式HashMap

2020-11-19 11:43:26

HarmonyOS

2020-11-20 09:45:19

HarmonyOS

2013-06-18 14:00:59

HDFS分布式文件系统

2021-01-21 09:45:36

鸿蒙HarmonyOS分布式

2020-11-19 11:36:24

HarmonyOS

2021-11-16 09:38:10

鸿蒙HarmonyOS应用

2021-10-21 10:03:09

鸿蒙HarmonyOS应用

2021-05-28 09:52:00

鸿蒙HarmonyOS应用

2012-07-20 14:40:22

2020-11-06 12:12:35

HarmonyOS

2018-12-14 10:06:22

缓存分布式系统

2021-07-22 10:20:21

鸿蒙HarmonyOS应用

2021-07-23 08:57:32

鸿蒙HarmonyOS应用

2019-10-10 09:16:34

Zookeeper架构分布式

2021-11-08 10:52:02

数据库分布式技术

2019-06-19 15:40:06

分布式锁RedisJava

2023-05-29 14:07:00

Zuul网关系统
点赞
收藏

51CTO技术栈公众号