鸿蒙疫情助手卡片,太方便了...

淡定哥 2021-09-01 17:51:02 3781

前段时间国内的新冠疫情又出现了一些波动,公司也要求每天上报健康码和行程码,就想着能不能用服务卡片做一个,于是就开始行动了。

想着大体可以分成 2 步走,需要先设计 UI,然后对接相关的接口,不过对接接口要麻烦一些,需要有相关的开放接口,目前还没实现。

搭建环境

安装 DevEco Studio,详情请参考 DevEco Studio 下载:
https://developer.harmonyos.com/cn/develop/deveco-studio

设置 DevEco Studio 开发环境,DevEco Studio 开发环境需要依赖于网络环境,需要连接上网络才能确保工具的正常使用。

可以根据如下两种情况来配置开发环境:

如果可以直接访问 Internet,只需进行下载 HarmonyOS SDK 操作。

如果网络不能直接访问 Internet,需要通过代理服务器才可以访问,请参考配置开发环境。
https://developer.harmonyos.com/cn/docs/documentation/doc-guides/environment_config-0000001052902427

效果展示

如下图:

项目结构

如下图:

现步骤

①编写界面

ability_main.xml 主界面:这个界面会显示获取到城市,以及地区的风险等级,然后就是安康码和行程卡的入口。

itinerary_card_slice.xml 行程卡界面:行程卡的显示界面,上半部分是通过短信验证码获取行程信息,下半部分是显示获取到的行程信息。

health_code_slice 安康码界面:安康码的显示界面,上半部部分显示当前所在城市,下半部分显示获取的安康码信息,然后是一个行程卡的入口。

form_image_with_info_date_card_2_2.xml 2x2 的卡片界面:

form_image_with_info_date_card_2_4.xml 2x4 的卡片界面:

②编写启动应用代码

MainAbility.java:
/**

  • Card Main Ability
    */
    public class MainAbility extends Ability {
    private static final HiLogLabel LABEL = new HiLogLabel(HiLog.LOG_APP, 0x0D1001, "=>MainAbility");
    //卡片规格编号
    private static final int DEFAULT_DIMENSION_2X2 = 2;
    private static final int DEFAULT_DIMENSION_2X4 = 3;
    //ACTION路由
    private final String ACTION_HEALTH_CODE = "action.custom.healthcode";
    private final String ACTION_ITINERARY_CARD = "action.custom.itinerarycard";
    //权限
    private String[] requestPermissions = {SystemPermission.LOCATION};
    //卡片ID
    private long formId;
    //卡片信息
    private ProviderFormInfo formInfo;
    //二维码
    private QRCodeUtil qrCodeUtil;

    //所在城市文本组件
    private Text regionText;

    @Override
    public void onStart(Intent intent) {
    HiLog.info(LABEL, "onStart ");
    super.onStart(intent);
    super.setMainRoute(MainAbilitySlice.class.getName());
    //必要的
    super.setUIContent(ResourceTable.Layout_ability_main);
    //添加ACTION路由
    addActionRoute(ACTION_HEALTH_CODE, HealthCodeSlice.class.getName());
    addActionRoute(ACTION_ITINERARY_CARD, ItineraryCardSlice.class.getName());

    //向用户请求权限
    PermissionsUtils.getInstance(this).requestPermissions(this, requestPermissions);
    
    //获取位置
    regionText = (Text) findComponentById(ResourceTable.Id_text_main_region);
    new LocationHelper().getMyLocation(getContext(), currentRegion -> {
        getUITaskDispatcher().asyncDispatch(() -> {
            regionText.setText(currentRegion);
        });
    });

    }

    @Override
    protected ProviderFormInfo onCreateForm(Intent intent) {
    HiLog.info(LABEL, "创建卡片");
    if (intent == null) {
    return new ProviderFormInfo();
    }
    if (qrCodeUtil == null) {
    qrCodeUtil = new QRCodeUtil(this);
    }

    // 获取卡片id
    if (intent.hasParameter(AbilitySlice.PARAM_FORM_IDENTITY_KEY)) {
        formId = intent.getLongParam(AbilitySlice.PARAM_FORM_IDENTITY_KEY, -1);
    } else {
        HiLog.info(LABEL, "未获取到卡片id....");
        return new ProviderFormInfo();
    }
    HiLog.info(LABEL, "获取卡片id:" + formId);
    // 获取卡片名称
    String formName = "疫情助手";
    if (intent.hasParameter(AbilitySlice.PARAM_FORM_NAME_KEY)) {
        formName = intent.getStringParam(AbilitySlice.PARAM_FORM_NAME_KEY);
    }
    HiLog.info(LABEL, "获取卡片名称:" + formName);
    // 获取卡片规格
    int dimension = DEFAULT_DIMENSION_2X4;
    if (intent.hasParameter(AbilitySlice.PARAM_FORM_DIMENSION_KEY)) {
        dimension = intent.getIntParam(AbilitySlice.PARAM_FORM_DIMENSION_KEY, DEFAULT_DIMENSION_2X4);
    }
    Map<String, Integer> viewIdMap = new HashMap<>();
    
    HiLog.info(LABEL, "获取卡片规格:" + dimension);
    //获取卡片布局ID
    int layoutId = getLayoutId(dimension, viewIdMap);
    
    HiLog.info(LABEL, "通过布局文件id实例化formInfo");
    formInfo = new ProviderFormInfo(layoutId, this);
    // 存储卡片信息
    HiLog.info(LABEL, "存储卡片信息");
    Form form = new Form(formId, formName, dimension);
    
    HiLog.info(LABEL, "根据Form实例化ComponentProvider");
    ComponentProvider componentProvider = getComponentProvider(form, viewIdMap, layoutId, this);
    
    HiLog.info(LABEL, "设置formInfo的 ComponentProvider 对象");
    formInfo.mergeActions(componentProvider);
    
    try {
        HiLog.info(LABEL, "通过DatabaseUtils保存Form信息到DB:" + form.toString());
        DatabaseUtils.getInstance(this).insertForm(form);
    } catch (Exception e) {
        HiLog.info(LABEL, "发生异常,通过DatabaseUtils删除DB中的Form信息");
        DatabaseUtils.getInstance(this).deleteFormData(form.getFormId());
    }
    return formInfo;

    }

    /**

    • @param dimension 卡片规格
    • @param viewIdMap 健康码/行程码所在布局ID
    • @return
      /
      public int getLayoutId(int dimension, Map<String, Integer> viewIdMap) {
      viewIdMap.clear();
      HiLog.info(LABEL, "getLayoutId");
      int layoutId = 0;
      if (dimension == DEFAULT_DIMENSION_2X2) {
      HiLog.info(LABEL, "获取2
      2的布局文件");
      layoutId = ResourceTable.Layout_form_image_with_info_date_card_2_2;

      //
      viewIdMap.put(ACTION_HEALTH_CODE, ResourceTable.Id_layout_ankang_2x2);

      } else if (dimension == DEFAULT_DIMENSION_2X4) {
      HiLog.info(LABEL, "获取2*4的布局文件");
      layoutId = ResourceTable.Layout_form_image_with_info_date_card_2_4;
      //
      viewIdMap.put(ACTION_HEALTH_CODE, ResourceTable.Id_layout_ankang_2x4);
      viewIdMap.put(ACTION_ITINERARY_CARD, ResourceTable.Id_layout_itinerary_2x4);
      }
      return layoutId;
      }

    /**

    • 获取卡片信息提供者对象
    • @param form
    • @param viewIdMap
    • @param layoutId
    • @param context
    • @return
      */
      public ComponentProvider getComponentProvider(Form form, Map<String, Integer> viewIdMap, int layoutId, Context context) {
      HiLog.info(LABEL, "getComponentProvider");
      ComponentProvider componentProvider = new ComponentProvider(layoutId, context);

      for (Map.Entry entry : viewIdMap.entrySet()) {
      String actionKey = (String) entry.getKey();
      int viewId = (int) entry.getValue();
      HiLog.info(LABEL, "actionKey = " + actionKey + ", viewId = " + viewId);

      //设置组件值
      setComponentProviderValue(componentProvider, form);
      //设置跳转事件
      componentProvider.setIntentAgent(viewId, getIntentAgent(actionKey));

      }

      return componentProvider;
      }

    /**

    • 设置卡片信息
    • @param componentProvider
    • @param form
      */
      private void setComponentProviderValue(ComponentProvider componentProvider, Form form) {
      //HiLog.debug(LABEL, "setComponentProviderValue,PixelMap:"+QRCodeUtil.getCurrentPixelMap());
      try {
      if (form.getDimension() == DEFAULT_DIMENSION_2X2) {
      HiLog.info(LABEL, "setComponentProviderValue2x2");
      componentProvider.setText(ResourceTable.Id_text_city, LocationHelper.getCity());
      //设置QR
      componentProvider.setImagePixelMap(ResourceTable.Id_image_ankang_right, QRCodeUtil.getCurrentPixelMap());

      } else {
          HiLog.info(LABEL, "setComponentProviderValue2x4");
          componentProvider.setText(ResourceTable.Id_text_city, LocationHelper.getCity());
          //设置安康码
          componentProvider.setImagePixelMap(ResourceTable.Id_image_ankang_right, QRCodeUtil.getCurrentPixelMap());
      
          //设置行程卡信息
          componentProvider.setImageContent(ResourceTable.Id_image_itinerary_right, ResourceTable.Graphic_icon_itinerary);
      
      }

      } catch (Exception e) {
      HiLog.error(LABEL, "setComponentProviderValueError:" + e.getMessage());
      e.printStackTrace();
      }

    }

    /**

    • 获取IntentAgent,事件控制对象
    • @param ACTION
    • @return
      */
      private IntentAgent getIntentAgent(String ACTION) {
      HiLog.info(LABEL, "getIntentAgent");
      // 设置点击的跳转页面
      Intent intent = new Intent();
      Operation operation = new Intent.OperationBuilder()
      .withDeviceId("")
      .withBundleName(getBundleName())
      .withAbilityName(MainAbility.class)
      .withAction(ACTION)
      .build();
      // 携带参数
      intent.setParam("formId", 1);
      intent.setOperation(operation);
      List intentList = new ArrayList<>();
      intentList.add(intent);
      // 对于不同的响应事件,第一个参数requestCode需要不同,此处用电影id设为requestCode
      IntentAgentInfo paramsInfo = new IntentAgentInfo(200,
      IntentAgentConstant.OperationType.START_ABILITY,
      IntentAgentConstant.Flags.UPDATE_PRESENT_FLAG, intentList, null);
      IntentAgent intentAgent = IntentAgentHelper.getIntentAgent(this, paramsInfo);
      HiLog.info(LABEL, "getIntentAgent:FINISH");
      return intentAgent;
      }

    /**

    • 用户删除卡片时会自动调用
    • @param formId
      */
      @Override
      protected void onDeleteForm(long formId) {
      super.onDeleteForm(formId);
      // 删除数据库中的卡片信息
      HiLog.info(LABEL, "删除DB中的Form信息:" + formId);
      DatabaseUtils.getInstance(this).deleteFormData(formId);
      }

    @Override
    public void onRequestPermissionsFromUserResult(int requestCode, String[] permissions, int[] grantResults) {
    PermissionsUtils.getInstance(this).onRequestPermissionsResult(requestCode, permissions, grantResults);
    }

}

MainAbilitySlice.java:

/**

  • MainAbilitySlice
    */
    public class MainAbilitySlice extends AbilitySlice {
    private static final HiLogLabel LABEL = new HiLogLabel(HiLog.LOG_APP, 0x001003, "=>MainAbilitySlice");

    @Override
    public void onStart(Intent intent) {
    HiLog.info(LABEL, "onStart");
    super.onStart(intent);
    super.setUIContent(ResourceTable.Layout_ability_main);
    //
    initComponent();

    //初始化更新卡片服务
    startServiceAbility();

    }

    private void initComponent() {
    HiLog.info(LABEL, "initComponent");
    //
    Component componentAnkang = findComponentById(ResourceTable.Id_text_bottom_card_ankang);
    Component componentItinerary = findComponentById(ResourceTable.Id_text_bottom_card_itinerary);

    //跳转到健康码和行程卡页面
    componentAnkang.setClickedListener(listener -> present(new HealthCodeSlice(),new Intent()));
    componentItinerary.setClickedListener(listener -> present(new ItineraryCardSlice(), new Intent()));

    }

    /**

    • 启动更新卡片服务Ability
      */
      private void startServiceAbility() {
      // 启动TimerAbility
      Intent intentService = new Intent();
      Operation operation =
      new Intent.OperationBuilder()
      .withDeviceId("")
      .withBundleName(getBundleName())
      .withAbilityName(TimerAbility.class.getName())
      .build();
      intentService.setOperation(operation);
      startAbility(intentService);
      HiLog.info(LABEL, "启动TimerAbility ");
      }

    @Override
    public void onActive() {
    super.onActive();
    }

    @Override
    public void onForeground(Intent intent) {
    super.onForeground(intent);
    }

    @Override
    protected void onStop() {
    }

}

TimerAbility.java 主要实现卡片的数据定时更新,代码如下:

/**

  • 用于定时更新卡片的服务
  • Time PA
    */
    public class TimerAbility extends Ability {
    private static final HiLogLabel LABEL = new HiLogLabel(HiLog.LOG_APP, 0x001003, "=>TimerAbility");
    //卡片规格编号
    public static final int DEFAULT_DIMENSION_2X2 = 2;
    //卡片规格编号
    public static final int DEFAULT_DIMENSION_2X4 = 3;

    //更新卡片周期:毫秒
    private static final long SEND_PERIOD = 10000L;
    private static final int QR_COLOR = 0xFF009900;
    //DB 帮助类
    private DatabaseHelper helper = new DatabaseHelper(this);
    //ORM上下文
    private OrmContext connect;

    //二维码工具类
    private QRCodeUtil qrCodeUtil;

    //全局定时器
    private Timer timer = null;

    @Override
    public void onStart(Intent intent) {
    super.onStart(intent);

    HiLog.info(LABEL, "初始化数据库连接");
    connect = helper.getOrmContext("FormDatabase", "FormDatabase.db", FormDatabase.class);
    
    //
    qrCodeUtil = new QRCodeUtil(this);
    
    //
    HiLog.info(LABEL, "启动定时");
    startTimer();

    }

    /**

    • 启动定时器,定期刷新卡片数据,
    • 一个卡片对应一个定时器
      /
      private void startTimer() {
      /
      if (timer != null) {
      timer.cancel();
      }*/
      timer = new Timer();
      timer.schedule(new TimerTask() {
      @Override
      public void run() {
      updateForms();
      }
      }, 0, SEND_PERIOD);
      }

    /**

    • 更细卡片数据
      */
      private void updateForms() {
      // 从数据库中获取卡片信息
      HiLog.info(LABEL, "从数据库中获取卡片");
      OrmPredicates ormPredicates = new OrmPredicates(Form.class);
      List

      formList = connect.query(ormPredicates);
      int layoutId = 0;
      // 更新时分秒
      if (formList.size() <= 0) {
      return;
      }
      HiLog.info(LABEL, "遍历卡片列表,逐个更新");
      for (Form form : formList) {
      //获取卡片刷新的数据提供对象
      ComponentProvider componentProvider = getComponentProvider(form, this);
      try {
      Long updateFormId = form.getFormId();
      HiLog.info(LABEL, "卡片ID[" + updateFormId + "]");

          //更新卡片数据到数据库
          boolean isSucc = updateForm(updateFormId, componentProvider);
          HiLog.info(LABEL, "更新卡片数据完成," + isSucc);
      
      } catch (FormException e) {
          // 删除不存在的卡片
          DatabaseUtils.getInstance(this).deleteFormData(form.getFormId());
          HiLog.error(LABEL, "更新卡片异常,删除数据库中不存在的卡片");
      }

      }
      }

    /**

    • Obtains the ComponentProvider object
    • @param form form info
    • @param context context
    • @return component provider
      */
      public ComponentProvider getComponentProvider(Form form, Context context) {
      HiLog.info(LABEL, "getComponentProvider:" + form);
      //获取卡片规格
      int layoutId = getLayoutId(form.getDimension());
      HiLog.info(LABEL, "layoutId:" + layoutId);
      ComponentProvider componentProvider = new ComponentProvider(layoutId, context);

      HiLog.info(LABEL, "更新卡片上组件的值");
      setComponentProviderValue(componentProvider, form);

      return componentProvider;
      }

    /**

    • 获取对应规格的布局文件
    • @param dimension
    • @return
      /
      public int getLayoutId(int dimension) {
      HiLog.info(LABEL, "getLayoutId");
      int layoutId = 0;
      if (dimension == DEFAULT_DIMENSION_2X2) {
      HiLog.info(LABEL, "获取2
      2的布局文件");
      layoutId = ResourceTable.Layout_form_image_with_info_date_card_2_2;
      }
      if (dimension == DEFAULT_DIMENSION_2X4) {
      HiLog.info(LABEL, "获取2*4的布局文件");
      layoutId = ResourceTable.Layout_form_image_with_info_date_card_2_4;
      }
      return layoutId;
      }

    /**

    • Set the value of componentProvider
    • 根据规格来更新卡片信息
    • @param componentProvider component provider
      */
      private void setComponentProviderValue(ComponentProvider componentProvider, Form form) {
      HiLog.info(LABEL, "setComponentProviderValue");
      PixelMap pixels;

      if (form.getDimension() == DEFAULT_DIMENSION_2X2) {
      HiLog.info(LABEL, "setComponentProviderValue2x2");
      componentProvider.setText(ResourceTable.Id_text_city, LocationHelper.getCity());
      //设置QR
      pixels = qrCodeUtil.generateColorQRCode(new Date().getTime() + "", QR_COLOR);
      componentProvider.setImagePixelMap(ResourceTable.Id_image_ankang_right, pixels);

      } else {
      HiLog.info(LABEL, "setComponentProviderValue2x4");
      componentProvider.setText(ResourceTable.Id_text_city, LocationHelper.getCity());
      //设置QR
      pixels = qrCodeUtil.generateColorQRCode(new Date().getTime() + "", QR_COLOR);
      componentProvider.setImagePixelMap(ResourceTable.Id_image_ankang_right, pixels);

      //设置行程卡信息
      componentProvider.setImageContent(ResourceTable.Id_image_itinerary_right, ResourceTable.Graphic_icon_itinerary);

      }
      }

    @Override
    public void onBackground() {
    super.onBackground();
    HiLog.info(LABEL, "TimerAbility::onBackground");
    }

    @Override
    public void onStop() {
    super.onStop();
    timer.cancel();
    HiLog.info(LABEL, "TimerAbility::onStop");
    }
    }

HealthCodeSlice.java:

public class HealthCodeSlice extends AbilitySlice {
static final HiLogLabel LABEL = new HiLogLabel(HiLog.LOG_APP, 0x001005, "=>HealthCodeSlice");
private static final String accessToken = "";
/**

  • 随机定义生成不同颜色的二维码.
    */
    private static final int QR_COLOR = 0xFF009900;
    /**
  • 生成英文二维码的内容.
    */
    private final String englishContent = "http://www.huawei.com";
    private EventHandler handler;
    private QRCodeUtil qrCodeUtil;

    /**

  • 显示不同颜色二维码.
    */
    private Image colorQRCode;

    private Text regionText;

    @Override
    public void onStart(Intent intent) {
    HiLog.info(LABEL, "onStart");
    super.onStart(intent);
    super.setUIContent(ResourceTable.Layout_health_code_slice);
    //二维码
    colorQRCode = (Image) findComponentById(ResourceTable.Id_text_main_card_icon);
    //所在城市
    regionText = (Text) findComponentById(ResourceTable.Id_text_health_region);

    //设置行程卡跳转
    Component component = findComponentById(ResourceTable.Id_text_bottom_card_itinerary);
    
    //行程卡跳转
    Intent itineraryIntent = new Intent();
    component.setClickedListener(listener -> present(new ItineraryCardSlice(), itineraryIntent));
    
    //生成安康码
    handler = new EventHandler(EventRunner.create("qr"));
    qrCodeUtil = new QRCodeUtil(this);
    generateColorQRCode();
    
    //获取所在位置
    String currentRegion = LocationHelper.getProvinceAndCity();
    HiLog.info(LABEL, "currentRegion: " + currentRegion);
    regionText.setText(currentRegion);

    }

    /**

  • 生成不同颜色二维码.
    */
    private void generateColorQRCode() {
    handler.postTask(() -> {
    PixelMap pixelMap = qrCodeUtil.generateColorQRCode(
    englishContent, QR_COLOR);
    getMainTaskDispatcher().syncDispatch(() -> {
    // 显示二维码图像
    colorQRCode.setPixelMap(pixelMap);
    });
    });
    }

    @Override
    public void onActive() {
    super.onActive();
    }

    @Override
    public void onForeground(Intent intent) {
    super.onForeground(intent);
    }

    @Override
    protected void onStop() {
    HiLog.info(LABEL, "onStop");
    }

    /**

  • 调用阿里提供API,未实现
    */
    public void queryGovHealthcode() {
    AlipayClient alipayClient = new DefaultAlipayClient("https://openapi.alipay.com/gateway.do", "app_id", "your private_key", "json", "GBK", "alipay_public_key", "RSA2");
    AlipayEbppIndustryGovHealthcodeQueryRequest request = new AlipayEbppIndustryGovHealthcodeQueryRequest();
    request.setBizContent("{" +
    "\"city_code\":\"88684\"," +
    "\"biz_info\":\"{\\"location\\":\\"浙江省杭州市\\",\\"bizTime\\":\\"2020-04-13 14:20:30\\"}\"," +
    "\"biz_type\":\"HEALTHCODE\"" +
    " }");
    AlipayEbppIndustryGovHealthcodeQueryResponse response = null;
    try {
    response = alipayClient.execute(request, accessToken);
    if (response.isSuccess()) {
    System.out.println("调用成功");
    } else {
    System.out.println("调用失败");
    }
    } catch (AlipayApiException e) {
    e.printStackTrace();
    }

    }

}

ItineraryCardSlice.java:

/**

  • 行程卡页面
    */
    public class ItineraryCardSlice extends AbilitySlice {
    static final HiLogLabel LABEL = new HiLogLabel(HiLog.LOG_APP, 0x001003, "=>ItineraryCardSlice");

    @Override
    public void onStart(Intent intent) {
    HiLog.info(LABEL, "onStart");
    super.onStart(intent);
    super.setUIContent(ResourceTable.Layout_itinerary_card_slice);

    //获取传递过来的所在城市
    String currentRegion = intent.getStringParam("currentRegion");
    HiLog.debug(LABEL, "currentRegion:" + currentRegion);
    if (currentRegion!=null) {
    
    }

    }

    @Override
    public void onActive() {
    super.onActive();
    }

    @Override
    public void onForeground(Intent intent) {
    super.onForeground(intent);
    }

    @Override
    protected void onStop() {
    HiLog.info(LABEL, "onStop");
    }

}

LocationHelper.java 获取位置工具类:

/**

  • 获取本机位置信息实现类
  • @since 2021-03-15
    */
    public class LocationHelper {
    static final HiLogLabel LABEL = new HiLogLabel(HiLog.LOG_APP, 0x001205, "=>LocationHelper");
    //当前位置
    private static String provinceAndCity;
    private static String city;
    //当前的经纬度
    private static String longlat;
    private LocCallBack locCallBack;
    private Context context;

    public static String getProvinceAndCity() {
    return provinceAndCity;
    }

    public static void setProvinceAndCity(String provinceAndCity) {
    LocationHelper.provinceAndCity = provinceAndCity;
    }

    public static String getCity() {
    return city;
    }

    public static void setCity(String city) {
    LocationHelper.city = city;
    }

    public static String getLonglat() {
    return longlat;
    }

    public static void setLonglat(String longlat) {
    LocationHelper.longlat = longlat;
    }

    /**

    • 获取本机位置信息
    • @param con Context con
    • @param callBack LocCallBack callBack
      */
      public void getMyLocation(Context con, LocCallBack callBack) {
      locCallBack = callBack;
      context = con;
      Locator locator = new Locator(context);
      if (locator.isLocationSwitchOn()) {
      RequestParam requestParam = new RequestParam(RequestParam.SCENE_NAVIGATION);
      MyLocatorCallback locatorCallback = new MyLocatorCallback();
      locator.requestOnce(requestParam, locatorCallback);

      } else {
      ToastDialog toastDialog = new ToastDialog(context);
      toastDialog.setAutoClosable(false);
      toastDialog.setContentText("请前往设置打开位置开关");
      toastDialog.show();
      }
      }

    /**

    • 调用高德地图逆地理编码api,获取城市编码
    • @param location Location
      */
      public void getRegionDetail(Location location) {
      HiLog.info(LABEL, "getRegionDetail");
      String locations = location.getLongitude() + "," + location.getLatitude();
      HiLog.info(LABEL, "getRegionDetail,locations:" + locations + ",longlat:" + longlat);
      try {
      //如果经纬度和上次的一致就不再地理编码
      if (!locations.isEmpty() && locations.equals(longlat)) {
      HiLog.info(LABEL, "getRegionDetail repeat");

          if (locCallBack != null) {
              locCallBack.locCallBack(provinceAndCity);
          }
      } else {
          String url = String.format(Const.REGION_DETAIL_URL, locations, Const.MAP_KEY);
          HttpUtils.getInstance(context).get(url, result -> {
              HiLog.info(LABEL, "result:" + result);
              if (result != null) {
                  RegionDetailResult regionDetailResult = GsonUtils.jsonToBean(result, RegionDetailResult.class);
                  HiLog.info(LABEL, "regionDetailResult");
                  String province = regionDetailResult.getRegeocode().getAddressComponent().getProvince();
                  String city = regionDetailResult.getRegeocode().getAddressComponent().getCity();
      
                  StringBuilder stringBuilder = new StringBuilder(province);
                  stringBuilder.append("-").append(city);
                  //保存获取的位置
                  setCity(city);
                  setProvinceAndCity(stringBuilder.toString());
                  setLonglat(locations);
                  HiLog.info(LABEL, "regionLocation:" + stringBuilder);
                  //
                  if (locCallBack != null) {
                      locCallBack.locCallBack(provinceAndCity);
                  }
              } else {
                  HiLog.info(LABEL, "get Location Error!");
              }
          });
      }

      } catch (Exception e) {
      HiLog.error(LABEL, "getRegionDetail error:" + e.getMessage());
      e.printStackTrace();
      }
      }

    /**

    • 获取位置信息后的回调接口
    • @since 2021-03-15
      */
      public interface LocCallBack {
      /**
      • locCallBack
      • @param currentRegion 当前位置
        */
        void locCallBack(String currentRegion);
        }

    /**

    • MyLocatorCallback
    • @since 2021-03-12
      */
      private class MyLocatorCallback implements LocatorCallback {
      @Override
      public void onLocationReport(Location location) {
      HiLog.info(LABEL, "onLocationReport:" + location);
      //经纬度转地理位置
      getRegionDetail(location);
      }

      @Override
      public void onStatusChanged(int type) {
      HiLog.info(LABEL, "onStatusChanged:" + type);
      }

      @Override
      public void onErrorReport(int type) {
      HiLog.info(LABEL, "onErrorReport:" + type);
      }
      }
      }

全局 config.json 配置文件:

{
"app": {
"bundleName": "com.buty.esa",
"vendor": "huawei",
"version": {
"code": 1000000,
"name": "1.0"
}
},
"deviceConfig": {
"default": {
"keepAlive": true
}
},
"module": {
"package": "com.huawei.learnharmony",
"name": "com.huawei.learnharmony.MyApplication",
"deviceType": [
"phone"
],
"distro": {
"deliveryWithInstall": true,
"moduleName": "entry",
"moduleType": "entry",
"installationFree": false
},
"abilities": [
{
"skills": [
{
"entities": [
"entity.system.home"
],
"actions": [
"action.system.home",
"action.custom.healthcode",
"action.custom.itinerarycard"
]
}
],
"orientation": "unspecified",
"name": "com.huawei.learnharmony.MainAbility",
"icon": "$media:icon",
"description": "$string:mainability_description",
"label": "$string:app_name",
"type": "page",
"launchType": "singleton",
"formsEnabled": true,
"visible": true,
"forms": [
{
"landscapeLayouts": [
"$layout:form_image_with_info_date_card_2_2",
"$layout:form_image_with_info_date_card_2_4"
],
"isDefault": true,
"scheduledUpdateTime": "10:30",
"defaultDimension": "22",
"name": "EpidemicCard",
"description": "查看安康码、行程卡",
"colorMode": "auto",
"type": "Java",
"supportDimensions": [
"2
2",
"2*4"
],
"portraitLayouts": [
"$layout:form_image_with_info_date_card_2_2",
"$layout:form_image_with_info_date_card_2_4"
],
"updateEnabled": true,
"updateDuration": 1,
"formVisibleNotify": true
}
],
"metaData":{
"customizeData":[
{
"name" :"hwc-theme",
"value":"androidhwext:style/Theme.Emui.Light.NoTitleBar",
"extra":""
}
]
}
},
{
"name": "com.huawei.learnharmony.TimerAbility",
"icon": "$media:icon",
"description": "$string:TimeAbility_description",
"type": "service",
"visible": true
}
],
"reqPermissions": [
{
"reason": "获取您所在城市",
"name": "ohos.permission.LOCATION",
"usedScene": {
"ability": [
"com.huawei.learnharmony.MainAbility"
],
"when": "always"
}
},
{
"name": "ohos.permission.LOCATION_IN_BACKGROUND"
},
{
"name": "ohos.permission.INTERNET"
},
{
"name": "ohos.permission.GET_BUNDLE_INFO"
},
{
"name": "ohos.permission.GET_NETWORK_INFO"
},
{
"name": "ohos.permission.SET_NETWORK_INFO"
}
]
}
}

问题总结

①解决页面布局问题,模拟器看到的效果和真机显示不完整存在差异:
//卡片布局中 ohos:remote=“true” 一定要加

②解决一个卡片,不同功能区跳转到不同的 Slice 问题:

//设置跳转事件
componentProvider.setIntentAgent(viewId, getIntentAgent(actionKey));

③解决获取位置问题:

使用LocationHelper,HttpUtils,GsonUtils工具类,获取经纬度后还需要逆地理编码
//获取位置
regionText = (Text) findComponentById(ResourceTable.Id_text_main_region);
new LocationHelper().getMyLocation(getContext(), currentRegion -> {
getUITaskDispatcher().asyncDispatch(() -> {
regionText.setText(currentRegion);
});
});

④二维码生成的问题,使用到了 QRCodeUtil 工具类,官方指导:

https://developer.huawei.com/consumer/cn/codelabsPortal/carddetails/HarmonyOS-QRCode

⑤待解决安康码,行程卡相关接口调用问题,需要找到相关的开放接口。

完整代码

点击“阅读原文”在附件出直接下载:

https://harmonyos.51cto.com/posts/8081

来源:鸿蒙技术社区

声明:本文内容由易百纳平台入驻作者撰写,文章观点仅代表作者本人,不代表易百纳立场。如有内容侵权或者其他问题,请联系本站进行删除。
红包 93 收藏 评论 打赏
评论
0个
内容存在敏感词
手气红包
    易百纳技术社区暂无数据
相关专栏
置顶时间设置
结束时间
删除原因
  • 广告/SPAM
  • 恶意灌水
  • 违规内容
  • 文不对题
  • 重复发帖
打赏作者
易百纳技术社区
淡定哥
您的支持将鼓励我继续创作!
打赏金额:
¥1易百纳技术社区
¥5易百纳技术社区
¥10易百纳技术社区
¥50易百纳技术社区
¥100易百纳技术社区
支付方式:
微信支付
支付宝支付
易百纳技术社区微信支付
易百纳技术社区
打赏成功!

感谢您的打赏,如若您也想被打赏,可前往 发表专栏 哦~

举报反馈

举报类型

  • 内容涉黄/赌/毒
  • 内容侵权/抄袭
  • 政治相关
  • 涉嫌广告
  • 侮辱谩骂
  • 其他

详细说明

审核成功

发布时间设置
发布时间:
是否关联周任务-专栏模块

审核失败

失败原因
备注
拼手气红包 红包规则
祝福语
恭喜发财,大吉大利!
红包金额
红包最小金额不能低于5元
红包数量
红包数量范围10~50个
余额支付
当前余额:
可前往问答、专栏板块获取收益 去获取
取 消 确 定

小包子的红包

恭喜发财,大吉大利

已领取20/40,共1.6元 红包规则

    易百纳技术社区