Epidemic Service Assistant 疫情服务助手卡片 原创 精华

Buty9147
发布于 2021-8-31 21:17
浏览
7收藏

@toc

Epidemic Service Assistant 疫情服务助手卡片

介绍

前段时间国内的新冠疫情又出现了一些波动,公司也要求每天上报健康码和行程码,就想着能不能用服务卡片做一个,于是就开始行动了,想着大体可以分成2步走,需要先设计UI,然后对接相关的接口,不过对接接口要麻烦一些,需要有相关的开放接口,目前还没实现。

搭建环境

安装DevEco Studio,详情请参考DevEco Studio下载
设置DevEco Studio开发环境,DevEco Studio开发环境需要依赖于网络环境,需要连接上网络才能确保工具的正常使用,可以根据如下两种情况来配置开发环境:

如果可以直接访问Internet,只需进行下载HarmonyOS SDK操作。
如果网络不能直接访问Internet,需要通过代理服务器才可以访问,请参考配置开发环境

效果展示

Epidemic Service Assistant 疫情服务助手卡片-鸿蒙开发者社区

项目结构

Epidemic Service Assistant 疫情服务助手卡片-鸿蒙开发者社区

实现步骤

1.编写界面

ability_main.xml 主界面
这个界面会显示获取到城市,以及地区的风险等级,然后就是安康码和行程卡的入口。
Epidemic Service Assistant 疫情服务助手卡片-鸿蒙开发者社区

itinerary_card_slice.xml行程卡界面
行程卡的显示界面,上半部分是通过短信验证码获取行程信息,下半部分是显示获取到的行程信息。
Epidemic Service Assistant 疫情服务助手卡片-鸿蒙开发者社区

health_code_slice安康码界面
安康码的显示界面,上半部部分显示当前所在城市,下半部分显示获取的安康码信息,然后是一个行程卡的入口。
Epidemic Service Assistant 疫情服务助手卡片-鸿蒙开发者社区

form_image_with_info_date_card_2_2.xml 2x2的卡片界面
Epidemic Service Assistant 疫情服务助手卡片-鸿蒙开发者社区

form_image_with_info_date_card_2_4.xml 2x4的卡片界面
Epidemic Service Assistant 疫情服务助手卡片-鸿蒙开发者社区

2.编写启动应用代码

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<Intent> 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<Form> 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": "2*2",
            "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"
      }
    ]
  }
}

问题总结

1.解决页面布局问题,模拟器看到的效果和真机显示不完整存在差异
//卡片布局中 ohos:remote=“true” 一定要加
2.解决一个卡片,不同功能区跳转到不同的Slice问题

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

3.解决获取位置问题

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

4.二维码生成的问题
使用到了QRCodeUtil工具类,
官方指导:
https://developer.huawei.com/consumer/cn/codelabsPortal/carddetails/HarmonyOS-QRCode

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

完整代码

附件直接下载

©著作权归作者所有,如需转载,请注明出处,否则将追究法律责任
EpidemicServiceAssistant.zip 6.5M 276次下载
已于2021-9-1 13:45:00修改
11
收藏 7
回复
举报
4条回复
按时间正序
/
按时间倒序
mb609898e2cfb86
mb609898e2cfb86

疫情期间还是不能掉以轻心,鸿蒙的卡片确实对需要扫码的地方十分方便。

回复
2021-9-1 10:11:22
vsrrrrrb
vsrrrrrb

请问楼主,setImagePixelMap,我设置了int id和pixelMap,但是就是没效果。你遇到这个问题没?

回复
2021-10-23 17:07:56
Buty9147
Buty9147 回复了 vsrrrrrb
请问楼主,setImagePixelMap,我设置了int id和pixelMap,但是就是没效果。你遇到这个问题没?

有,在创建服务卡片的时候,想生成QR码显示在卡片上,不生效,最后用setImageContent方法设置了一张默认的QR码。卡片更新的时候却能生效,很奇怪。

//设置默认的QR码
componentProvider.setImageContent(ResourceTable.Id_image_ankang_right_2x2, ResourceTable.Media_icon_qr);
回复
2021-10-25 18:36:27
vsrrrrrb
vsrrrrrb 回复了 Buty9147
有,在创建服务卡片的时候,想生成QR码显示在卡片上,不生效,最后用setImageContent方法设置了一张默认的QR码。卡片更新的时候却能生效,很奇怪。 //设置默认的QR码 componentProvider.setImageContent(ResourceTable.Id_image_ankang_right_2x2, ResourceTable.Media_icon_qr);

那个setImageContent我试了没问题,能显示。问题出在setImagePixelMap(RT.Id,pixelMap),其中pixelMap我能打印出来值,并且实验在其他组件,例如setPixelmap(pixelMap)也没问题,就是setImagePixelMap没效果,哭死了。看来只能js去解决卡片获取网络图片的问题了。

回复
2021-10-25 21:56:53
回复
    相关推荐