栏目分类:
子分类:
返回
文库吧用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
文库吧 > IT > 前沿技术 > 云计算 > Docker/k8s

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

Docker/k8s 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力



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

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

https://harmonyos.51cto.co

引言

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

功能介绍

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

前提:

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

开发指南 1.在config.json中添加permisssion权限

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

  1. "reqPermissions": [     { 
  2.         "name": "ohos.permission.DISTRIBUTED_DATASYNC"     } 
2.在MainAbility中添加权限
  1. @Override public void onStart(Intent intent) { 
  2.   super.onStart(intent);   super.setMainRoute(MainAbilitySlice.class.getName()); 
  3.   //实现Ability的代码中显式声明需要使用多设备协同访问的权限   requestPermissionsFromUser(new String[]{ 
  4.       "ohos.permission.DISTRIBUTED_DATASYNC"}, 0);  
3.根据配置构造分布式数据库管理类实例KvManager以及创建分布式数据库对象SingleKvStore

//实现数据库的初始化

  1. // 初入的参数context: Context context = getApplicationContext()获得;storeId为分布式数据库id,String类型,可自行定义,例如“testApp”。 public static SingleKvStore initOrGetDB(Context context, String storeId) { 
  2.   KvManagerConfig kvManagerConfig = new KvManagerConfig(context);   kvManager = KvManagerFactory.getInstance().createKvManager(kvManagerConfig); 
  3.   Options options = new Options();   options.setCreateIfMissing(true) 
  4.     .setEncrypt(false)     .setKvStoreType(KvStoreType.SINGLE_VERSION) //数据库类型:单版本分布式数据库 
  5.     .setAutoSync(true); //自动同步为true,手动同步为false   singleKvStore = kvManager.getKvStore(options, storeId); 
  6.   return singleKvStore; } 
4.将数据写入单版本分布式数据库
  1. //以key-value形式存储到分布式数据库 try { 
  2.   //将采集的数据以key-value形式存入分布式数据库中   DataModle dataModle=new DataModle(); 
  3.   dataModle.setTemp(temp);   dataModle.setHumi(humi); 
  4.   dataModle.setCo2(co2);   String jsonString= ZSONObject.toZSonString(dataModle); 
  5.   singleKvStore.putString("data",jsonString); } catch (KvStoreException e) { 
  6.   LogUtils.debug(TAG, "DataServiceAbility::updateData()"+e.getMessage()); }  
5.订阅分布式数据变化。客户端需要实现KvStoreObserver接口,监听数据变化
  1. //订阅类型SubscribeType.SUBSCRIBE_TYPE_ALL意思可以同步到本机和其他外围设备   innerKvStoreObserver = new InnerKvStoreObserver(); 
  2.   singleKvStore.subscribe(SubscribeType.SUBSCRIBE_TYPE_ALL, innerKvStoreObserver); } catch (KvStoreException e) { 
  3.   e.printStackTrace(); } 
  4.  public class InnerKvStoreObserver implements KvStoreObserver { 
  5.    @Override 
  6.   public void onChange(ChangeNotification changeNotification) {     //刷新页面上的数据,同样有一个坑,onChange方法实质上,在一个子线程里执行 
  7.     MainAbilitySlice.taskDispatcher.asyncDispatch(() -> {       //在这里执行页面ui组件的显示刷新 
  8.       flushUIData();     }); 
  9.   } } 
6.获取分布式数据库数据
  1.  //查询分布式数据的数据,获取数据可以通过get(String key)或者 getEntries(String key)方法获取数据 List entries = singleKvStore.getEntries("data"); 
  2. if (entries.size() > 0) {   ZSONObject zsonObject = ZSONObject.stringToZSON(entries.get(0).getValue().getString()); 
  3.   double temp = zsonObject.getDouble("temp");   double humi = zsonObject.getDouble("humi"); 
  4.   double co2 = zsonObject.getDouble("co2");   String strTemp = String.format("%.1f", temp); 
  5.   String strHumi = String.format("%.1f", humi);   String strCO2 = String.format("%.1f", co2); 
  6.   tvTemp.setText(strTemp+"℃");   tvHumi.setText(strHumi+"%RH"); 
  7.   tvCo2.setText(strCO2+"ppm"); } 
7.解除订阅,一般在页面销毁时调用,也就是在onStop()中调用
  1. if (singleKvStore != null) {   singleKvStore.unSubscribe(innerKvStoreObserver); 
8.同步数据到其他设备。获取已连接的设备列表,选择同步方式进行数据同步
  1. List onlineDevices = DeviceManager     .getDeviceList(DeviceInfo.FLAG_GET_ONLINE_DEVICE); 
  2. List deviceIdList = new ArrayList<>(); for (DeviceInfo deviceInfo : deviceInfoList) { 
  3.     deviceIdList.add(deviceInfo.getId()); } 
  4. //迁移到指定设备,传入设备ID列表 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 {   private SingleKvStore singleKvStore; 
  2.   private InnerKvStoreObserver innerKvStoreObserver;   private Intent serviceIntent; 
  3.   private Text tvTemp;   private Text tvHumi; 
  4.   private Text tvCo2;   private DeviceData chooseDevice; 
  5.   private DevicesProvider devicesProvider;   private CommonDialog commonDialog; 
  6.   private String TAG="MainAbilitySlice";   private ListdeviceIdList; 
  7.   @Override   public void onStart(Intent intent) { 
  8.     super.onStart(intent);     super.setUIContent(ResourceTable.Layout_ability_main); 
  9.     //设置沉浸式状态栏  getWindow().addFlags(WindowManager.LayoutConfig.MARK_TRANSLUCENT_STATUS);     initView(); 
  10.     initService();     try { 
  11.       //获取数据库       singleKvStore = DBUtils.initOrGetDB(this, DBUtils.KV_STORE_NAME); 
  12.       innerKvStoreObserver = new InnerKvStoreObserver();       //订阅分布式数据库 
  13.       singleKvStore.subscribe(SubscribeType.SUBSCRIBE_TYPE_ALL, innerKvStoreObserver);     } catch (KvStoreException e) { 
  14.       LogUtils.debug(TAG, "MainAbilitySlice::onStart/"+e.getMessage());     } 
  15.   }   private void initService() { 
  16.     //启动ServiceAbility     serviceIntent = new Intent(); 
  17.     Operation operation = new Intent.OperationBuilder()         .withDeviceId("") 
  18.         .withBundleName("com.isoftstone.distributeddata")         .withAbilityName("com.isoftstone.distributeddata.DataServiceAbility") 
  19.         .build();     serviceIntent.setOperation(operation); 
  20.     startAbility(serviceIntent);   } 
  21.   private void initView() {     tvTemp = (Text) findComponentById(ResourceTable.Id_text_temp); 
  22.     tvHumi = (Text) findComponentById(ResourceTable.Id_text_humi);     tvCo2 = (Text) findComponentById(ResourceTable.Id_text_co2); 
  23.     Button bt = (Button) findComponentById(ResourceTable.Id_bt_continue);     bt.setClickedListener(component -> { 
  24.       if (component.getId() == ResourceTable.Id_bt_continue) {         //查看在线设备 
  25.         List onlineDevices = DeviceManager             .getDeviceList(DeviceInfo.FLAG_GET_ONLINE_DEVICE); 
  26.         List deviceDatas = new ArrayList<>();         if (onlineDevices == null || onlineDevices.size() < 1) { 
  27.           CustomerDialog.showToastDialog(getAbility(), "无组网在线设备");         } else { 
  28.           for (DeviceInfo deviceInfo : onlineDevices) {             deviceDatas.add(new DeviceData(false, deviceInfo)); 
  29.           }           showDevices(deviceDatas); 
  30.         }       } 
  31.     });   } 
  32.   private void showDevices(List deviceDatas) {     chooseDevice = null; 
  33.     commonDialog = new CommonDialog(this);     Component component = LayoutScatter.getInstance(this) 
  34.         .parse(ResourceTable.Layout_dialog_layout_device, null, true);     ListContainer listContainer = (ListContainer) component.findComponentById(ResourceTable.Id_list_container_device); 
  35.     devicesProvider = new DevicesProvider(this, deviceDatas);     listContainer.setItemProvider(devicesProvider); 
  36.     listContainer.setItemClickedListener((listContainer1, component1, position, l) -> {       chooseDevice = deviceDatas.get(position); 
  37.       for (int i = 0; i < deviceDatas.size(); i++) {         if (i == position) { 
  38.           deviceDatas.set(i, new DeviceData(true, deviceDatas.get(i).getDeviceInfo()));         } else { 
  39.           deviceDatas.set(i, new DeviceData(false, deviceDatas.get(i).getDeviceInfo()));         } 
  40.       }       devicesProvider = new DevicesProvider(this, deviceDatas); 
  41.       listContainer1.setItemProvider(devicesProvider);     }); 
  42.     Text tvCancle = (Text) component.findComponentById(ResourceTable.Id_operate_no);     Text tvSure = (Text) component.findComponentById(ResourceTable.Id_operate_yes); 
  43.      tvCancle.setClickedListener(component12 -> commonDialog.destroy()); 
  44.      tvSure.setClickedListener(component13 -> { 
  45.       if (chooseDevice == null) {         CustomerDialog.showToastDialog(this, "请选择设备"); 
  46.       } else {         try { 
  47.           deviceIdList=new ArrayList<>();           deviceIdList.add(chooseDevice.getDeviceInfo().getDeviceId()); 
  48.           //手动同步的设备列表           singleKvStore.sync(deviceIdList, SyncMode.PUSH_ONLY); 
  49.           commonDialog.destroy();         } catch (IllegalStateException e) { 
  50.           //流转异常捕获,防止进程存在再次发起流转           LogUtils.debug(TAG, "MainAbilitySlice::singleKvStore.sync()/"+e.getMessage()); 
  51.         }       } 
  52.     });     commonDialog.setSize(MATCH_PARENT, MATCH_CONTENT); 
  53.     commonDialog.setAlignment(LayoutAlignment.BOTTOM);     commonDialog.setCornerRadius(10); 
  54.     commonDialog.setAutoClosable(true);     commonDialog.setContentCustomComponent(component); 
  55.     commonDialog.setTransparent(true);     commonDialog.show(); 
  56.   }   public class InnerKvStoreObserver implements KvStoreObserver { 
  57.      @Override 
  58.     public void onChange(ChangeNotification changeNotification) {       //onChange方法实质上,在一个子线程里执行 
  59.       getUITaskDispatcher().asyncDispatch(() -> {         //在这里执行页面ui组件的显示刷新 
  60.         asyncUpdateData();       }); 
  61.     }   } 
  62.   public void asyncUpdateData(){     //查询分布式数据的数据 
  63.     List entries = singleKvStore.getEntries("data");     if (entries.size() > 0) { 
  64.       ZSONObject zsonObject = ZSONObject.stringToZSON(entries.get(0).getValue().getString());       double temp = zsonObject.getDouble("temp"); 
  65.       double humi = zsonObject.getDouble("humi");       double co2 = zsonObject.getDouble("co2"); 
  66.       String strTemp = String.format("%.1f", temp);       String strHumi = String.format("%.1f", humi); 
  67.       String strCO2 = String.format("%.1f", co2);       tvTemp.setText(strTemp+"℃"); 
  68.       tvHumi.setText(strHumi+"%RH");       tvCo2.setText(strCO2+"ppm"); 
  69.       //手动同步的设备列表       if(singleKvStore!=null){ 
  70.         if(deviceIdList!=null&&deviceIdList.size()>0){           singleKvStore.sync(deviceIdList, SyncMode.PUSH_ONLY); 
  71.         }       } 
  72.     }   } 
  73.    @Override 
  74.   public void onActive() {     super.onActive(); 
  75.   }   @Override 
  76.   public void onForeground(Intent intent) {     super.onForeground(intent); 
  77.   }   @Override 
  78.   protected void onStop() {     super.onStop(); 
  79.     //销毁service     stopAbility(serviceIntent); 
  80.     //删除数据库     DBUtils.clearDB(); 
  81.     //解除订阅     if (singleKvStore != null) { 
  82.       if(innerKvStoreObserver!=null){         singleKvStore.unSubscribe(innerKvStoreObserver); 
  83.       }     } 
  84.   } } 

2. DataServiceAbility

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

3.DBUtils

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

4. MainAbility

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

 5. DataModle

  1. public class DataModle {   private double temp; 
  2.   private double humi;   private double co2; 
  3.   public double getTemp() {     return temp; 
  4.   }   public void setTemp(double temp) { 
  5.     this.temp = temp;   } 
  6.    public double getHumi() { 
  7.     return humi;   } 
  8.   public void setHumi(double humi) {     this.humi = humi; 
  9.   }   public double getCo2() { 
  10.     return co2;   } 
  11.   public void setCo2(double co2) {     this.co2 = co2; 
  12.   } } 

6. DeviceData

  1. public class DeviceData {     private boolean isChecked; 
  2.     private DeviceInfo deviceInfo;          public DeviceData(boolean isChecked, DeviceInfo deviceInfo) { 
  3.         this.isChecked = isChecked;         this.deviceInfo = deviceInfo; 
  4.     }     public DeviceInfo getDeviceInfo() { 
  5.         return deviceInfo;     } 
  6.     public void setDeviceInfo(DeviceInfo deviceInfo) {         this.deviceInfo = deviceInfo; 
  7.     }     public boolean isChecked() { 
  8.         return isChecked;     } 
  9.     public void setChecked(boolean checked) {         isChecked = checked; 
  10.     } } 

7. DevicesProvider

  1. public class DevicesProvider extends baseItemProvider {  
  2.  private List data;  private LayoutScatter layoutScatter; 
  3.   public DevicesProvider(Context context, List data) { 
  4.    this.data = data;    this.layoutScatter = LayoutScatter.getInstance(context); 
  5.  }  
  6.  @Override  public int getCount() { 
  7.    return data.size();  } 
  8.   @Override 
  9.  public Object getItem(int i) {    return data.get(i); 
  10.  }  
  11.  @Override  public long getItemId(int i) { 
  12.    return i;  } 
  13.   @Override 
  14.  public Component getComponent(int position, Component component,      ComponentContainer componentContainer) { 
  15.    ViewHolder viewHolder;    // component相当于Android中的view,其他的和Android中ListView的适配器adapter差不多。 
  16.    // 名字区别也不大,不过Android中ListView基本被淘汰了。    if (component == null) { 
  17.      component = layoutScatter.parse(ResourceTable.Layout_dialog_device_item, null, false);      viewHolder = new ViewHolder(); 
  18.      viewHolder.imgType = (Image) component.findComponentById(ResourceTable.Id_item_type);      viewHolder.tvName = (Text) component.findComponentById(ResourceTable.Id_item_name); 
  19.      viewHolder.imgCheck = (Image) component.findComponentById(ResourceTable.Id_item_check);      component.setTag(viewHolder); 
  20.    } else {      viewHolder = (ViewHolder) component.getTag(); 
  21.    }    DeviceData deviceData = data.get(position); 
  22.    DeviceType deviceType=deviceData.getDeviceInfo().getDeviceType();    switch (deviceType){ 
  23.      case SMART_WATCH:        viewHolder.imgType.setPixelMap(ResourceTable.Media_dv_watch); 
  24.        break;      case SMART_PAD: 
  25.        viewHolder.imgType.setPixelMap(ResourceTable.Media_dv_pad);        break; 
  26.      case SMART_PHONE:        viewHolder.imgType.setPixelMap(ResourceTable.Media_dv_phone); 
  27.        break;    } 
  28.    viewHolder.tvName.setText(deviceData.getDeviceInfo().getDeviceName());    if(deviceData.isChecked()){ 
  29. viewHolder.imgCheck.setImageAndDecodeBounds(ResourceTable.Media_check2); }else {  viewHolder.imgCheck.setImageAndDecodeBounds(ResourceTable.Media_uncheck2);    } 
  30.    return component;  } 
  31.    
  32.  private static class ViewHolder {    private Image imgType; 
  33.    private Text tvName;    private Image imgCheck; 
  34.  } } 

8. CustomerDialog

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

9. MyApplication

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

 10. config.json 文件

  1. "app": {   "bundleName": " com.isoftstone.distributeddata ", 
  2.   "vendor": "isoftstone",   "version": { 
  3.     "code": 1000000,     "name": "1.0.0" 
  4.   } }, 
  5. "deviceConfig": {}, "module": { 
  6.   "package": "com.isoftstone.distributeddata",   "name": ".MyApplication", 
  7.   "mainAbility": "com.isoftstone.distributeddata.MainAbility",   "deviceType": [ 
  8.     "phone"   ], 
  9.   "distro": {     "deliveryWithInstall": true, 
  10.     "moduleName": "entry",     "moduleType": "entry", 
  11.     "installationFree": false   }, 
  12.   "reqPermissions": [     { 
  13.       "name": "ohos.permission.DISTRIBUTED_DATASYNC"     }, 
  14.     { 添加此权限,才能查找分布式在线设备 
  15.       "name": "ohos.permission.GET_DISTRIBUTED_DEVICE_INFO"     }, 
  16.     { 将service设置为前台服务,需要添加的权限 
  17.       "name": "ohos.permission.KEEP_BACKGROUND_RUNNING"      } 
  18.   ],   "abilities": [ 
  19.     {       "skills": [ 
  20.         {           "entities": [ 
  21.             "entity.system.home"           ], 
  22.           "actions": [             "action.system.home" 
  23.           ]         } 
  24.       ],       "orientation": "unspecified", 
  25.       "name": "com.isoftstone.distributeddata.MainAbility",       "icon": "$media:icon", 
  26.       "description": "$string:mainability_description",       "label": "$string:entry_MainAbility", 
  27.       "type": "page",       "launchType": "standard" 
  28.     },     { 
  29.       "name": "com.isoftstone.distributeddata.DataServiceAbility",       "icon": "$media:icon", 
  30.       "description": "$string:dataserviceability_description",       "type": "service", 
  31.       "visible": true,       "backgroundModes": [ 
  32.         "dataTransfer",         "location" 
  33.       ]     } 
  34.    ], 
  35.   "metaData": {     "customizeData": [ 
  36.       {         "name": "hwc-theme", 
  37.         "value": "androidhwext:style/Theme.Emui.NoTitleBar",         "extra": "" 
  38.       }     ] 
  39.   } } 

11.ability_main.xml布局文件

  1.    xmlns:ohos="http://schemas.huawei.com/res/ohos"   ohos:height="match_parent" 
  2.   ohos:width="match_parent"   ohos:orientation="vertical"> 
  3.        ohos:width="match_parent"     ohos:height="match_content" 
  4.     ohos:orientation="horizontal"     ohos:top_padding="50vp" 
  5.     ohos:bottom_padding="20vp"     ohos:left_padding="20vp" 
  6.     ohos:right_padding="20vp"     ohos:background_element="$graphic:background_ability_main"> 
  7.           ohos:height="match_content"       ohos:text="农业大棚数据监测" 
  8.       ohos:text_size="26vp"       ohos:text_color="#ffffff" 
  9.       ohos:center_in_parent="true"/>           ohos:id="$+id:bt_continue"       ohos:width="25vp" 
  10.       ohos:height="25vp"       ohos:background_element="$media:conti" 
  11.       ohos:align_parent_right="true"       ohos:vertical_center="true"/> 
  12.          ohos:height="match_content"     ohos:width="match_parent" 
  13.     ohos:background_element="#f4f5f7"     ohos:left_padding="15vp" 
  14.     ohos:right_padding="15vp"     ohos:top_padding="10vp" 
  15.     ohos:bottom_padding="10vp">  
  16.           ohos:width="match_content"       ohos:text="温度:" 
  17.       ohos:text_color="#000000"       ohos:text_size="18fp" 
  18.       ohos:vertical_center="true"/>  
  19.           ohos:height="match_content"       ohos:width="match_content" 
  20.       ohos:text="数据正在采集 "       ohos:text_color="#00ff00" 
  21.       ohos:text_size="18fp"       ohos:left_margin="50vp" 
  22.       ohos:vertical_center="true"/>    
  23.        ohos:height="2vp"     ohos:width="match_content" 
  24.     ohos:background_element="#FFFFFF"/>  
  25.       ohos:width="match_parent"     ohos:background_element="#f4f5f7" 
  26.     ohos:left_padding="15vp"     ohos:right_padding="15vp" 
  27.     ohos:top_padding="10vp"     ohos:bottom_padding="10vp"> 
  28.            ohos:height="match_content"       ohos:width="match_content" 
  29.       ohos:text="湿度:"       ohos:text_color="#000000" 
  30.       ohos:text_size="18fp"       ohos:vertical_center="true"/> 
  31.            ohos:id="$+id:text_humi"       ohos:height="match_content" 
  32.       ohos:width="match_content"       ohos:text="数据正在采集 " 
  33.       ohos:text_color="#00ff00"       ohos:text_size="18fp" 
  34.       ohos:left_margin="50vp"       ohos:vertical_center="true"/> 
  35.     
  36.       ohos:width="match_content"     ohos:background_element="#FFFFFF"/> 
  37.        ohos:height="match_content"     ohos:width="match_parent" 
  38.     ohos:background_element="#f4f5f7"     ohos:left_padding="15vp" 
  39.     ohos:right_padding="15vp"     ohos:top_padding="10vp" 
  40.     ohos:bottom_padding="10vp">  
  41.           ohos:width="match_content"       ohos:text="CO2:" 
  42.       ohos:text_color="#000000"       ohos:text_size="18fp" 
  43.       ohos:vertical_center="true"/>  
  44.           ohos:height="match_content"       ohos:width="match_content" 
  45.       ohos:text="数据正在采集 "       ohos:text_color="#00ff00" 
  46.       ohos:text_size="18fp"       ohos:left_margin="50vp" 
  47.       ohos:vertical_center="true"/>    
  48.   
  49.  

12. dialog_device_item.xml

  1.      xmlns:ohos="http://schemas.huawei.com/res/ohos"     ohos:height="70vp" 
  2.     ohos:width="match_parent"     ohos:orientation="horizontal"> 
  3.              ohos:id="$+id:item_type"         ohos:height="45vp" 
  4.         ohos:width="50vp"         ohos:image_src="$media:dv_phone" 
  5.         ohos:layout_alignment="vertical_center"         ohos:left_margin="10vp" 
  6.         ohos:scale_mode="inside"/>  
  7.             ohos:height="match_parent"         ohos:width="0vp" 
  8.         ohos:max_text_lines="1"         ohos:text="Huawei P40" 
  9.         ohos:text_alignment="vertical_center"         ohos:text_size="15fp" 
  10.         ohos:weight="1"/>  
  11.             ohos:height="30vp"         ohos:width="30vp" 
  12.         ohos:image_src="$media:uncheck2"  
  1.     ohos:height="340vp"     ohos:width="match_parent" 
  2.     ohos:orientation="vertical">  
  3.             ohos:width="match_parent"         ohos:background_element="$graphic:background_white_radius_10" 
  4.         ohos:bottom_margin="50vp"         ohos:left_margin="20vp" 
  5.         ohos:orientation="vertical"         ohos:right_margin="20vp"> 
  6.                      ohos:height="50vp"             ohos:width="match_parent" 
  7.             ohos:left_padding="20vp"             ohos:text="迁移到其他设备" 
  8.             ohos:text_alignment="vertical_center"             ohos:text_color="#000000" 
  9.             ohos:text_size="16fp"/>  
  10.                     ohos:height="0vp"             ohos:width="match_parent" 
  11.             ohos:weight="1"/>  
  12.                     ohos:width="match_parent"             ohos:orientation="horizontal"> 
  13.                              ohos:id="$+id:operate_no"                 ohos:height="match_parent" 
  14.                 ohos:width="0vp"                 ohos:text="取消" 
  15.                 ohos:text_alignment="center"                 ohos:text_color="#1e90ff" 
  16.                 ohos:text_size="17fp"                 ohos:weight="1"/> 
  17.                              ohos:height="25vp"                 ohos:width="1vp" 
  18.                 ohos:background_element="#cccccc"                 ohos:layout_alignment="vertical_center"/> 
  19.                              ohos:id="$+id:operate_yes"                 ohos:height="match_parent" 
  20.                 ohos:width="0vp"                 ohos:text="确定" 
  21.                 ohos:text_alignment="center"                 ohos:text_color="#1e90ff" 
  22.                 ohos:text_size="17fp"                 ohos:weight="1"/> 
  23.               
  24.  

14. toast_dialog.xml

  1.     ohos:height="match_content"     ohos:width="match_content" 
  2.     ohos:orientation="vertical"     ohos:background_element="$graphic:background_gray_circle"> 
  3.             ohos:height="match_content"         ohos:width="match_content" 
  4.         ohos:left_padding="16vp"         ohos:right_padding="16vp" 
  5.         ohos:top_padding="4vp"         ohos:bottom_padding="4vp" 
  6.         ohos:layout_alignment="center"         ohos:text_size="20fp"/> 
  7.  
TV端

1. TVAbilitySlice

  1.   private Text tvTemp;     private Text tvTempMax; 
  2.     private Text tvTempMin;  
  3.     private Text tvHumi;     private Text tvHumiMax; 
  4.     private Text tvHumiMin;  
  5.     private Text tvCgas;     private Text tvCgasMax; 
  6.     private Text tvCgasMin;  
  7.     private Text tvTempStatus;     private Text tvHumiStatus; 
  8.     private Text tvCgasStatus;  
  9.      private ProgressBar rgbTem; 
  10.     private ProgressBar rgbHumi;     private ProgressBar rgbCgas; 
  11.      private static final HiLogLabel label = new HiLogLabel(HiLog.LOG_APP, 0x0001, "my_log"); 
  12.      private double temp; 
  13.     private double humi;     private double cGas; 
  14.     private SingleKvStore singleKvStore;     private KvStoreObserverClient kvStoreObserverClient; 
  15.      @Override 
  16.     public void onStart(Intent intent) {         super.onStart(intent); 
  17.         super.setUIContent(ResourceTable.Layout_ability_tv);         //设置沉浸式状态栏 
  18.         getWindow().addFlags(WindowManager.LayoutConfig.MARK_TRANSLUCENT_STATUS);  
  19.         tvTemp = (Text) findComponentById(ResourceTable.Id_tvTemp);         tvTempMax = (Text) findComponentById(ResourceTable.Id_tvMaxTemp); 
  20.         tvTempMin = (Text) findComponentById(ResourceTable.Id_tvMinTemp);         rgbTem = (RoundProgressBar) findComponentById(ResourceTable.Id_rgb_tem); 
  21.          tvHumi = (Text) findComponentById(ResourceTable.Id_tvHumi); 
  22.         tvHumiMax = (Text) findComponentById(ResourceTable.Id_tvMaxHumi);         tvHumiMin = (Text) findComponentById(ResourceTable.Id_tvMinHumi); 
  23.         rgbHumi = (RoundProgressBar) findComponentById(ResourceTable.Id_rgb_humi);  
  24.         tvCgas = (Text) findComponentById(ResourceTable.Id_tvCgas);         tvCgasMax = (Text) findComponentById(ResourceTable.Id_tvMaxCgas); 
  25.         tvCgasMin = (Text) findComponentById(ResourceTable.Id_tvMinCgas);         rgbCgas = (RoundProgressBar) findComponentById(ResourceTable.Id_rgb_gas); 
  26.          tvTempStatus = (Text) findComponentById(ResourceTable.Id_tvTempStatus); 
  27.         tvHumiStatus = (Text) findComponentById(ResourceTable.Id_tvHumiStatus);         tvCgasStatus = (Text) findComponentById(ResourceTable.Id_tvCgasStatus); 
  28.          try { 
  29.             KvManagerConfig config = new KvManagerConfig(getContext());             KvManager kvManager = KvManagerFactory.getInstance().createKvManager(config); 
  30.             Options CREATE = new Options();             CREATE.setCreateIfMissing(true).setEncrypt(false) 
  31.                 .setKvStoreType(KvStoreType.SINGLE_VERSION)                 .setAutoSync(true); 
  32.             singleKvStore = kvManager.getKvStore(CREATE, DBUtils.KV_STORE_NAME);             kvStoreObserverClient = new KvStoreObserverClient(); 
  33.             singleKvStore.subscribe(SubscribeType.SUBSCRIBE_TYPE_ALL, kvStoreObserverClient);         } catch (Exception e) { 
  34.             e.printStackTrace();         } 
  35.      } 
  36.      private class KvStoreObserverClient implements KvStoreObserver { 
  37.          @Override 
  38.         public void onChange(ChangeNotification notification) {             //onChange方法实质上,在一个子线程里执行 
  39.             getUITaskDispatcher().asyncDispatch(() -> {                 //在这里执行页面ui组件的显示刷新 
  40.                 asyncUpdateData();             }); 
  41.         }     } 
  42.   
  43.     public void asyncUpdateData(){         //查询分布式数据的数据 
  44.         List entries = singleKvStore.getEntries("data");         if (entries.size() > 0) { 
  45.             ZSONObject zsonObject = ZSONObject.stringToZSON(entries.get(0).getValue().getString());             double temp = zsonObject.getDouble("temp"); 
  46.             double humi = zsonObject.getDouble("humi");             double co2 = zsonObject.getDouble("co2"); 
  47.             String strTemp = String.format("%.1f", temp);             String strHumi = String.format("%.1f", humi); 
  48.             String strCO2 = String.format("%.1f", co2);             initView(strTemp,strHumi,strCO2); 
  49.          } 
  50.     }  
  51.     private void initView(String strTemp,String strHumi,String strCO2) {         temp = Double.valueOf(strTemp); 
  52.         int tempMax = 45;         int tempMin = -10; 
  53.          humi = Double.valueOf(strHumi); 
  54.         int humiMax = 70;         int humiMin = 10; 
  55.          cGas = Double.valueOf(strCO2); 
  56.         int cGasMax = 1000;  
  57.         if (temp > -100) {             if (temp > tempMax || temp < tempMin) { 
  58.                 tvTemp.setTextColor(Color.RED);                 tvTempStatus.setText("异常"); 
  59.                 tvTempStatus.setTextColor(Color.RED);                 rgbTem.setProgressColor(Color.RED); 
  60.             } else {                 tvTemp.setTextColor(Color.GREEN); 
  61.                 tvTempStatus.setText("正常");                 tvTempStatus.setTextColor(Color.GREEN); 
  62.                 rgbTem.setProgressColor(Color.GREEN);  
  63.             }         } else { 
  64.             tvTemp.setTextColor(Color.BLACK);             tvTempStatus.setTextColor(Color.BLACK); 
  65.             tvTempStatus.setText("未知");             rgbTem.setProgressColor(Color.GREEN); 
  66.          } 
  67.         tvTempMax.setText(tempMax + "℃");         tvTempMin.setText(tempMin + "℃"); 
  68.          if (humi > -100) { 
  69.             if (humi > humiMax || humi < humiMin) {                 tvHumi.setTextColor(Color.RED); 
  70.                 tvHumiStatus.setText("异常");                 tvHumiStatus.setTextColor(Color.RED); 
  71.                 rgbHumi.setProgressColor(Color.RED);             } else { 
  72.                 tvHumi.setTextColor(Color.GREEN);                 tvHumiStatus.setText("正常"); 
  73.                 tvHumiStatus.setTextColor(Color.GREEN);                 rgbHumi.setProgressColor(Color.GREEN); 
  74.             }         } else { 
  75.             tvHumi.setTextColor(Color.BLACK);             tvHumiStatus.setText("未知"); 
  76.             tvHumiStatus.setTextColor(Color.BLACK);             rgbHumi.setProgressColor(Color.GREEN); 
  77.          } 
  78.         tvHumiMax.setText(humiMax + "% RH");         tvHumiMin.setText(humiMin + "% RH"); 
  79.          if (cGas > -100) { 
  80.             if (cGas > cGasMax) {                 tvCgas.setTextColor(Color.RED); 
  81.                 tvCgasStatus.setText("异常");                 tvCgasStatus.setTextColor(Color.RED); 
  82.                 rgbCgas.setProgressColor(Color.RED);             } else { 
  83.                 tvCgas.setTextColor(Color.GREEN);                 tvCgasStatus.setText("正常"); 
  84.                 tvCgasStatus.setTextColor(Color.GREEN);             } 
  85.         } else {             tvCgas.setTextColor(Color.BLACK); 
  86.             tvCgasStatus.setText("未知");             tvCgasStatus.setTextColor(Color.BLACK); 
  87.             rgbCgas.setProgressColor(Color.GREEN);  
  88.         }  
  89.         tvCgasMax.setText(cGasMax + " ppm");  
  90.         tvCgasMin.setText(0 + " ppm");  
  91.         if (temp <= -100) {             tvTemp.setText("未知"); 
  92.             rgbTem.setProgressValue(0);         } else { 
  93.             tvTemp.setText(temp + "℃");             rgbTem.setProgressValue((int) temp); 
  94.         }         if (humi <= -100) { 
  95.             tvHumi.setText("未知");             rgbHumi.setProgressValue(0); 
  96.         } else {             tvHumi.setText(humi + "% RH"); 
  97.             rgbHumi.setProgressValue((int) humi);         } 
  98.         if (cGas <= -100) {             tvCgas.setText("未知"); 
  99.             rgbCgas.setProgressValue(0);         } else { 
  100.             tvCgas.setText(cGas + " ppm");             rgbCgas.setProgressValue((int) cGas); 
  101.         }  
  102.     }  
  103.      @Override 
  104.     protected void onStop() {         super.onStop(); 
  105.         //解除订阅 //        if (singleKvStore != null) { 
  106. //            if(kvStoreObserverClient!=null){ //                singleKvStore.unSubscribe(kvStoreObserverClient); 
  107. //            } //        } 
  108.     } } 

2. TVAbility

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

 3. ability_tv.xml

  1.    xmlns:ohos="http://schemas.huawei.com/res/ohos"   ohos:height="match_parent" 
  2.   ohos:width="match_parent"   ohos:orientation="vertical" 
  3.   ohos:background_element="$media:haibao">  
  4.       ohos:width="match_content"     ohos:text="大棚数据监测" 
  5.     ohos:text_color="#ffffff"     ohos:text_size="26vp" 
  6.     ohos:layout_alignment="center"     ohos:top_margin="50vp"/> 
  7.        ohos:height="match_parent"     ohos:width="match_parent"> 
  8.            ohos:height="match_content"       ohos:width="match_parent" 
  9.       ohos:left_padding="10vp"       ohos:right_padding="10vp" 
  10.       ohos:center_in_parent="true"       ohos:orientation="horizontal"> 
  11.               ohos:width="0"         ohos:weight="1" 
  12.         ohos:layout_alignment="center"         ohos:orientation="vertical"> 
  13.                   ohos:width="match_content"           ohos:text="温度数据" 
  14.           ohos:text_size="20vp"           ohos:padding="5vp" 
  15.           ohos:text_color="#ffffff"           ohos:layout_alignment="center"/> 
  16.                   ohos:width="match_parent"           ohos:background_element="#ffffff" 
  17.           ohos:top_margin="15vp"           ohos:left_margin="20vp" 
  18.           ohos:right_margin="20vp"           ohos:layout_alignment="center" 
  19.           ohos:bottom_margin="15vp"           ohos:visibility="invisible"/> 
  20.                   ohos:width="match_content"           ohos:layout_alignment="center" 
  21.           ohos:orientation="horizontal">                       ohos:height="match_parent"             ohos:width="match_content" 
  22.             ohos:orientation="vertical">                           ohos:height="0"               ohos:width="match_content" 
  23.               ohos:text="最高温度阀值:"               ohos:text_size="16vp" 
  24.               ohos:weight="1"               ohos:text_color="#000000"/> 
  25.                           ohos:width="match_content"               ohos:text="当前温度:" 
  26.               ohos:text_size="16vp"               ohos:weight="1" 
  27.               ohos:text_color="#000000"/>                           ohos:height="0"               ohos:width="match_content" 
  28.               ohos:text="最低温度阀值:"               ohos:text_size="16vp" 
  29.               ohos:weight="1"               ohos:text_color="#000000"/> 
  30.             
  31.                       ohos:width="100vp">                           ohos:id="$+id:rgb_tem"               ohos:height="match_parent" 
  32.               ohos:width="match_parent"               ohos:progress_width="10vp" 
  33.               ohos:progress="0"               ohos:max="100" 
  34.               ohos:start_angle="215"               ohos:max_angle="290" 
  35.               ohos:progress_color="#00ff00"               ohos:center_in_parent="true"/> 
  36.                           ohos:height="match_content"               ohos:width="match_content" 
  37.               ohos:text_size="15vp"               ohos:text_color="#000000" 
  38.               ohos:align_parent_top="true"               ohos:text="未知" 
  39.               ohos:top_margin="8vp"               ohos:horizontal_center="true"/> 
  40.                           ohos:height="match_content"               ohos:width="match_content" 
  41.               ohos:text_size="15vp"               ohos:text_color="#000000" 
  42.               ohos:text="未知"               ohos:center_in_parent="true"/> 
  43.                           ohos:height="match_content"               ohos:width="match_content" 
  44.               ohos:text_size="14vp"               ohos:text_color="#000000" 
  45.               ohos:text="未知"               ohos:bottom_margin="8vp" 
  46.               ohos:align_parent_bottom="true"               ohos:horizontal_center="true"/> 
  47.             
  48.           
  49.                    ohos:height="3vp"           ohos:width="match_parent" 
  50.           ohos:background_element="#ffffff"           ohos:top_margin="15vp" 
  51.           ohos:left_margin="20vp"           ohos:right_margin="20vp" 
  52.           ohos:layout_alignment="center"           ohos:bottom_margin="15vp" 
  53.           ohos:visibility="invisible"/>                   ohos:height="match_content"           ohos:width="match_content" 
  54.           ohos:layout_alignment="center"           ohos:orientation="horizontal"> 
  55.                       ohos:width="match_content"             ohos:text="温度状态:" 
  56.             ohos:text_size="18vp"             ohos:text_color="#000000"/> 
  57.                       ohos:height="match_content"             ohos:width="match_content" 
  58.             ohos:text="未知"             ohos:text_size="18vp" 
  59.             ohos:text_color="#000000"/>          
  60.         
  61.                ohos:height="90vp"         ohos:width="1vp" 
  62.         ohos:background_element="#000000"         ohos:top_margin="6vp" 
  63.         ohos:layout_alignment="center"/>  
  64.               ohos:width="0"         ohos:weight="1" 
  65.         ohos:layout_alignment="center"         ohos:orientation="vertical"> 
  66.                   ohos:width="match_content"           ohos:text="湿度数据" 
  67.           ohos:text_size="20vp"           ohos:padding="5vp" 
  68.           ohos:text_color="#ffffff"           ohos:layout_alignment="center"/> 
  69.                   ohos:width="match_parent"           ohos:background_element="#ffffff" 
  70.           ohos:top_margin="15vp"           ohos:left_margin="20vp" 
  71.           ohos:right_margin="20vp"           ohos:layout_alignment="center" 
  72.           ohos:bottom_margin="15vp"           ohos:visibility="invisible"/> 
  73.   
  74.                   ohos:width="match_content"           ohos:layout_alignment="center" 
  75.           ohos:orientation="horizontal">                       ohos:height="match_parent"             ohos:width="match_content" 
  76.             ohos:orientation="vertical">                           ohos:height="0"               ohos:width="match_content" 
  77.               ohos:text="最大湿度阀值:"               ohos:text_size="16vp" 
  78.               ohos:weight="1"               ohos:text_color="#000000"/> 
  79.                           ohos:width="match_content"               ohos:text="当前湿度:" 
  80.               ohos:text_size="16vp"               ohos:weight="1" 
  81.               ohos:text_color="#000000"/>                           ohos:height="0"               ohos:width="match_content" 
  82.               ohos:text="最小湿度阀值:"               ohos:text_size="16vp" 
  83.               ohos:weight="1"               ohos:text_color="#000000"/> 
  84.             
  85.                       ohos:width="100vp">                           ohos:id="$+id:rgb_humi"               ohos:height="match_parent" 
  86.               ohos:width="match_parent"               ohos:progress_width="10vp" 
  87.               ohos:progress="0"               ohos:max="100" 
  88.               ohos:start_angle="215"               ohos:max_angle="290" 
  89.               ohos:progress_color="#00ff00"               ohos:center_in_parent="true"/> 
  90.                           ohos:height="match_content"               ohos:width="match_content" 
  91.               ohos:text_size="15vp"               ohos:text_color="#000000" 
  92.               ohos:text="未知"               ohos:top_margin="8vp" 
  93.               ohos:horizontal_center="true"               ohos:align_parent_top="true"/> 
  94.                           ohos:height="match_content"               ohos:width="match_content" 
  95.               ohos:text_size="15vp"               ohos:text_color="#000000" 
  96.               ohos:text="未知"               ohos:center_in_parent="true"/> 
  97.                           ohos:height="match_content"               ohos:width="match_content" 
  98.               ohos:text_size="15vp"               ohos:text_color="#000000" 
  99.               ohos:horizontal_center="true"               ohos:text="未知" 
  100.               ohos:bottom_margin="8vp"               ohos:align_parent_bottom="true"/> 
  101.             
  102.           
  103.                   ohos:width="match_parent"           ohos:background_element="#ffffff" 
  104.           ohos:top_margin="15vp"           ohos:left_margin="20vp" 
  105.           ohos:right_margin="20vp"           ohos:layout_alignment="center" 
  106.           ohos:bottom_margin="15vp"           ohos:visibility="invisible"/> 
  107.                   ohos:width="match_content"           ohos:layout_alignment="center" 
  108.           ohos:orientation="horizontal">                       ohos:height="match_content"             ohos:width="match_content" 
  109.             ohos:text="湿度状态:"             ohos:text_size="18vp" 
  110.             ohos:text_color="#000000"/>                       ohos:id="$+id:tvHumiStatus"             ohos:height="match_content" 
  111.             ohos:width="match_content"             ohos:text="未知" 
  112.             ohos:text_size="18vp"             ohos:text_color="#000000"/> 
  113.           
  114.         
  115.   
  116.               ohos:width="1vp"         ohos:background_element="#000000" 
  117.         ohos:top_margin="6vp"         ohos:layout_alignment="center"/> 
  118.   
  119.   
  120.               ohos:width="0"         ohos:weight="1" 
  121.         ohos:layout_alignment="center"         ohos:orientation="vertical"> 
  122.                   ohos:width="match_content"           ohos:text="CO2数据" 
  123.           ohos:text_size="20vp"           ohos:padding="5vp" 
  124.           ohos:text_color="#ffffff"           ohos:layout_alignment="center"/> 
  125.                   ohos:width="match_parent"           ohos:background_element="#ffffff" 
  126.           ohos:top_margin="15vp"           ohos:left_margin="20vp" 
  127.           ohos:right_margin="20vp"           ohos:layout_alignment="center" 
  128.           ohos:bottom_margin="15vp"           ohos:visibility="invisible"/> 
  129.                   ohos:width="match_content"           ohos:layout_alignment="center" 
  130.           ohos:orientation="horizontal">                       ohos:height="match_parent"             ohos:width="match_content" 
  131.             ohos:orientation="vertical">                           ohos:height="0"               ohos:width="match_content" 
  132.               ohos:text="最大气体增量:"               ohos:text_size="16vp" 
  133.               ohos:weight="1"               ohos:text_color="#000000"/> 
  134.                           ohos:width="match_content"               ohos:text="当前增量:" 
  135.               ohos:text_size="16vp"               ohos:weight="1" 
  136.               ohos:text_color="#000000"/>                           ohos:height="0"               ohos:width="match_content" 
  137.               ohos:text="最小气体增量:"               ohos:text_size="16vp" 
  138.               ohos:weight="1"               ohos:text_color="#000000"/> 
  139.             
  140.                       ohos:width="100vp">                           ohos:id="$+id:rgb_gas"               ohos:height="match_parent" 
  141.               ohos:width="match_parent"               ohos:progress_width="10vp" 
  142.               ohos:progress="0"               ohos:max="1000" 
  143.               ohos:start_angle="215"               ohos:max_angle="290" 
  144.               ohos:progress_color="#00ff00"               ohos:center_in_parent="true"/> 
  145.                           ohos:height="match_content"               ohos:width="match_content" 
  146.               ohos:text_size="15vp"               ohos:text="未知" 
  147.               ohos:text_color="#000000"               ohos:top_margin="8vp" 
  148.               ohos:horizontal_center="true"               ohos:align_parent_top="true"/> 
  149.                           ohos:height="match_content"               ohos:width="match_content" 
  150.               ohos:text_size="15vp"               ohos:text="未知" 
  151.               ohos:text_color="#000000"               ohos:center_in_parent="true"/> 
  152.                           ohos:height="match_content"               ohos:width="match_content" 
  153.               ohos:text_size="15vp"               ohos:text="未知" 
  154.               ohos:text_color="#000000"               ohos:bottom_margin="8vp" 
  155.               ohos:horizontal_center="true"               ohos:align_parent_bottom="true"/> 
  156.                     
  157.                    ohos:height="3vp"           ohos:width="match_parent" 
  158.           ohos:background_element="#ffffff"           ohos:top_margin="15vp" 
  159.           ohos:left_margin="20vp"           ohos:right_margin="20vp" 
  160.           ohos:layout_alignment="center"           ohos:bottom_margin="15vp" 
  161.           ohos:visibility="invisible"/>  
  162.                    ohos:height="match_content"           ohos:width="match_content" 
  163.           ohos:layout_alignment="center"           ohos:orientation="horizontal"> 
  164.                       ohos:width="match_content"             ohos:text="气体状态:" 
  165.             ohos:text_size="18vp"             ohos:text_color="#000000"/> 
  166.                       ohos:height="match_content"             ohos:width="match_content" 
  167.             ohos:text="未知"             ohos:text_size="18vp" 
  168.             ohos:text_color="#000000"/>          
  169.             
  170.     
  171.  

4.config.json

  1. {   "app": { 
  2.     "bundleName": "com.isoftstone. distributeddata ",     "vendor": "isoftstone", 
  3.     "version": {       "code": 1000000, 
  4.       "name": "1.0.0"     } 
  5.   },   "deviceConfig": {}, 
  6.   "module": {     "package": "com.isoftstone.distributeddata", 
  7.     "name": ".MyApplication",     "mainAbility": "com.isoftstone.distributeddata.com.isoftstone.distributeddata.TVAbility", 
  8.     "deviceType": [       "phone" 
  9.     ],     "distro": { 
  10.       "deliveryWithInstall": true,       "moduleName": "entry", 
  11.       "moduleType": "entry",       "installationFree": false 
  12.     },     "reqPermissions": [ 
  13.       {         "name": "ohos.permission.DISTRIBUTED_DATASYNC" 
  14.       }     ], 
  15.     "abilities": [       { 
  16.         "skills": [           { 
  17.             "entities": [               "entity.system.home" 
  18.             ],             "actions": [ 
  19.               "action.system.home"             ] 
  20.           }         ], 
  21.         "orientation": "landscape",         "name": "com.isoftstone.distributeddata.TVAbility", 
  22.         "icon": "$media:icon",         "description": "$string:tvability_description", 
  23.         "label": "$string:entry_TVAbility",         "type": "page", 
  24.         "launchType": "standard"       } 
  25.     ],     "metaData": { 
  26.       "customizeData": [         { 
  27.           "name": "hwc-theme",           "value": "androidhwext:style/Theme.Emui.NoTitleBar", 
  28.           "extra": ""         } 
  29.       ]     } 
  30.   } } 

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

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

https://harmonyos.51cto.co



 

转载请注明:文章转载自 www.wk8.com.cn
本文地址:https://www.wk8.com.cn/it/796688.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 wk8.com.cn

ICP备案号:晋ICP备2021003244-6号