From ffea43e9b8deeb577b7082ea6085b69882f8d33f Mon Sep 17 00:00:00 2001 From: zengyawen Date: Fri, 15 Oct 2021 19:11:26 +0800 Subject: [PATCH] format modification Signed-off-by: zengyawen --- zh-cn/application-dev/Readme-CN.md | 193 +++ .../application-dev/application-dev-guide.md | 6 +- .../application-dev/connectivity/Readme-CN.md | 9 +- .../ipc-rpc-development-guideline.md | 270 ++-- .../connectivity/ipc-rpc-overview.md | 17 +- zh-cn/application-dev/connectivity/ipc-rpc.md | 9 +- .../public_sys-resources/icon-caution.gif | Bin 0 -> 580 bytes .../public_sys-resources/icon-danger.gif | Bin 0 -> 580 bytes .../public_sys-resources/icon-note.gif | Bin 0 -> 394 bytes .../public_sys-resources/icon-notice.gif | Bin 0 -> 406 bytes .../public_sys-resources/icon-tip.gif | Bin 0 -> 253 bytes .../public_sys-resources/icon-warning.gif | Bin 0 -> 580 bytes .../connectivity/subscribe-remote-state.md | 16 +- .../application-dev/js-reference/Readme-CN.md | 34 +- .../js-reference/apis/js-apis-call.md | 870 +++---------- .../js-reference/apis/js-apis-fileio.md | 36 +- .../js-reference/apis/js-apis-radio.md | 1105 ++++------------- .../js-reference/apis/js-apis-sim.md | 693 ++--------- .../js-reference/apis/js-apis-sms.md | 924 +++----------- .../js-reference/component/Readme-CN.md | 4 +- .../component/js-components-svg-0.md | 128 -- .../component/js-components-svg.md | 159 ++- .../js-reference/component/js-svg.md | 33 + zh-cn/application-dev/media/Readme-CN.md | 10 +- .../application-dev/media/audio-management.md | 363 ++---- zh-cn/application-dev/media/audio-overview.md | 35 +- zh-cn/application-dev/media/audio-playback.md | 347 ++---- zh-cn/application-dev/media/audio-recorder.md | 375 ++---- zh-cn/application-dev/media/audio.md | 11 +- .../figures/zh-cn_image_0000001182608857.png | Bin .../public_sys-resources/icon-caution.gif | Bin 0 -> 580 bytes .../public_sys-resources/icon-danger.gif | Bin 0 -> 580 bytes .../media/public_sys-resources/icon-note.gif | Bin 0 -> 394 bytes .../public_sys-resources/icon-notice.gif | Bin 0 -> 406 bytes .../media/public_sys-resources/icon-tip.gif | Bin 0 -> 253 bytes .../public_sys-resources/icon-warning.gif | Bin 0 -> 580 bytes .../application-dev/quick-start/Readme-CN.md | 28 +- .../configuring-openharmony-app-signature.md | 129 +- .../configuring-openharmony-sdk.md | 258 ++-- .../quick-start/create-openharmony-project.md | 7 +- .../quick-start/deveco-studio-overview.md | 116 +- .../deveco-studio-release-notes.md | 18 +- ...eveco-studio-user-guide-for-openharmony.md | 15 +- .../quick-start/figures/1-0.png | Bin 3725 -> 0 bytes .../page-ability-lifecycle-callbacks.png | Bin 50304 -> 0 bytes .../figures/page-ability-lifecycle.png | Bin 14658 -> 0 bytes ...2.png => zh-cn_image_0000001166582138.png} | Bin ...2.png => zh-cn_image_0000001166740700.png} | Bin .../figures/zh-cn_image_0000001166744640.png | Bin 0 -> 5353 bytes ...3.png => zh-cn_image_0000001166904552.png} | Bin ...2.png => zh-cn_image_0000001166904582.png} | Bin ...2.png => zh-cn_image_0000001212062065.png} | Bin ...1.png => zh-cn_image_0000001212066021.png} | Bin ...8.png => zh-cn_image_0000001212142015.png} | Bin .../import-sample-to-create-project.md | 41 +- .../quick-start/installing-openharmony-app.md | 44 +- .../quick-start/package-structure.md | 13 +- .../public_sys-resources/icon-caution.gif | Bin 0 -> 580 bytes .../public_sys-resources/icon-danger.gif | Bin 0 -> 580 bytes .../public_sys-resources/icon-note.gif | Bin 0 -> 394 bytes .../public_sys-resources/icon-notice.gif | Bin 0 -> 406 bytes .../public_sys-resources/icon-tip.gif | Bin 0 -> 253 bytes .../public_sys-resources/icon-warning.gif | Bin 0 -> 580 bytes .../quick-start/start-overview.md | 27 +- .../quick-start/start-with-js.md | 214 ++-- zh-cn/application-dev/quick-start/start.md | 6 +- .../use-wizard-to-create-project.md | 69 +- zh-cn/application-dev/ui/Readme-CN.md | 32 +- ...2.png => zh-cn_image_0000001166426358.png} | Bin .../figures/zh-cn_image_0000001166426374.png | Bin .../figures/zh-cn_image_0000001166586348.png | Bin .../figures/zh-cn_image_0000001166744904.gif | Bin .../figures/zh-cn_image_0000001166904852.png | Bin .../figures/zh-cn_image_0000001212066259.png | Bin 0 -> 43265 bytes .../figures/zh-cn_image_0000001212066279.png | Bin ...n.gif => zh-cn_image_0000001212146221.gif} | Bin .../figures/zh-cn_image_0000001212146243.png | Bin .../ui/public_sys-resources/icon-caution.gif | Bin 0 -> 580 bytes .../ui/public_sys-resources/icon-danger.gif | Bin 0 -> 580 bytes .../ui/public_sys-resources/icon-note.gif | Bin 0 -> 394 bytes .../ui/public_sys-resources/icon-notice.gif | Bin 0 -> 406 bytes .../ui/public_sys-resources/icon-tip.gif | Bin 0 -> 253 bytes .../ui/public_sys-resources/icon-warning.gif | Bin 0 -> 580 bytes .../ui/ui-js-building-ui-animation.md | 45 +- .../ui/ui-js-building-ui-component.md | 42 +- .../ui/ui-js-building-ui-event.md | 20 +- .../ui/ui-js-building-ui-interactions.md | 19 +- .../ui/ui-js-building-ui-layout-comment.md | 11 +- ...s-building-ui-layout-external-container.md | 13 +- .../ui/ui-js-building-ui-layout-image.md | 9 +- .../ui/ui-js-building-ui-layout-intro.md | 27 +- .../ui/ui-js-building-ui-layout-text.md | 6 +- .../ui/ui-js-building-ui-layout.md | 13 +- .../ui/ui-js-building-ui-routes.md | 34 +- zh-cn/application-dev/ui/ui-js-building-ui.md | 15 +- .../ui/ui-js-custom-components.md | 169 ++- zh-cn/application-dev/ui/ui-js-overview.md | 39 +- zh-cn/application-dev/ui/ui-js.md | 8 +- 98 files changed, 2293 insertions(+), 4841 deletions(-) create mode 100644 zh-cn/application-dev/Readme-CN.md create mode 100644 zh-cn/application-dev/connectivity/public_sys-resources/icon-caution.gif create mode 100644 zh-cn/application-dev/connectivity/public_sys-resources/icon-danger.gif create mode 100644 zh-cn/application-dev/connectivity/public_sys-resources/icon-note.gif create mode 100644 zh-cn/application-dev/connectivity/public_sys-resources/icon-notice.gif create mode 100644 zh-cn/application-dev/connectivity/public_sys-resources/icon-tip.gif create mode 100644 zh-cn/application-dev/connectivity/public_sys-resources/icon-warning.gif delete mode 100644 zh-cn/application-dev/js-reference/component/js-components-svg-0.md create mode 100644 zh-cn/application-dev/js-reference/component/js-svg.md rename "zh-cn/application-dev/media/figures/\351\237\263\351\242\221\346\222\255\346\224\276\347\212\266\346\200\201\346\234\272.png" => zh-cn/application-dev/media/figures/zh-cn_image_0000001182608857.png (100%) mode change 100755 => 100644 create mode 100644 zh-cn/application-dev/media/public_sys-resources/icon-caution.gif create mode 100644 zh-cn/application-dev/media/public_sys-resources/icon-danger.gif create mode 100644 zh-cn/application-dev/media/public_sys-resources/icon-note.gif create mode 100644 zh-cn/application-dev/media/public_sys-resources/icon-notice.gif create mode 100644 zh-cn/application-dev/media/public_sys-resources/icon-tip.gif create mode 100644 zh-cn/application-dev/media/public_sys-resources/icon-warning.gif delete mode 100644 zh-cn/application-dev/quick-start/figures/1-0.png delete mode 100644 zh-cn/application-dev/quick-start/figures/page-ability-lifecycle-callbacks.png delete mode 100644 zh-cn/application-dev/quick-start/figures/page-ability-lifecycle.png rename zh-cn/application-dev/quick-start/figures/{zh-cn_image_0000001123021842.png => zh-cn_image_0000001166582138.png} (100%) rename zh-cn/application-dev/quick-start/figures/{zh-cn_image_0000001123024482.png => zh-cn_image_0000001166740700.png} (100%) create mode 100644 zh-cn/application-dev/quick-start/figures/zh-cn_image_0000001166744640.png rename zh-cn/application-dev/quick-start/figures/{3.png => zh-cn_image_0000001166904552.png} (100%) mode change 100755 => 100644 rename zh-cn/application-dev/quick-start/figures/{2.png => zh-cn_image_0000001166904582.png} (100%) mode change 100755 => 100644 rename zh-cn/application-dev/quick-start/figures/{zh-cn_image_0000001123021962.png => zh-cn_image_0000001212062065.png} (100%) rename zh-cn/application-dev/quick-start/figures/{1.png => zh-cn_image_0000001212066021.png} (100%) mode change 100755 => 100644 rename zh-cn/application-dev/quick-start/figures/{zh-cn_image_0000001122862128.png => zh-cn_image_0000001212142015.png} (100%) create mode 100644 zh-cn/application-dev/quick-start/public_sys-resources/icon-caution.gif create mode 100644 zh-cn/application-dev/quick-start/public_sys-resources/icon-danger.gif create mode 100644 zh-cn/application-dev/quick-start/public_sys-resources/icon-note.gif create mode 100644 zh-cn/application-dev/quick-start/public_sys-resources/icon-notice.gif create mode 100644 zh-cn/application-dev/quick-start/public_sys-resources/icon-tip.gif create mode 100644 zh-cn/application-dev/quick-start/public_sys-resources/icon-warning.gif rename zh-cn/application-dev/ui/figures/{zh-cn_image_0000001077953992.png => zh-cn_image_0000001166426358.png} (100%) rename "zh-cn/application-dev/ui/figures/\351\241\265\351\235\242\345\270\203\345\261\200\345\210\206\350\247\243.png" => zh-cn/application-dev/ui/figures/zh-cn_image_0000001166426374.png (100%) mode change 100755 => 100644 rename "zh-cn/application-dev/ui/figures/\345\233\276\347\211\2073.png" => zh-cn/application-dev/ui/figures/zh-cn_image_0000001166586348.png (100%) mode change 100755 => 100644 rename "zh-cn/application-dev/ui/figures/\350\277\236\347\273\255\345\212\250\347\224\273\346\225\210\346\236\234\345\233\276.gif" => zh-cn/application-dev/ui/figures/zh-cn_image_0000001166744904.gif (100%) mode change 100755 => 100644 rename "zh-cn/application-dev/ui/figures/\351\241\265\351\235\242\350\267\257\347\224\261\346\225\210\346\236\234.png" => zh-cn/application-dev/ui/figures/zh-cn_image_0000001166904852.png (100%) mode change 100755 => 100644 create mode 100644 zh-cn/application-dev/ui/figures/zh-cn_image_0000001212066259.png rename "zh-cn/application-dev/ui/figures/\351\235\231\346\200\201\345\212\250\347\224\273\346\225\210\346\236\234\345\233\276.png" => zh-cn/application-dev/ui/figures/zh-cn_image_0000001212066279.png (100%) mode change 100755 => 100644 rename zh-cn/application-dev/ui/figures/{zan.gif => zh-cn_image_0000001212146221.gif} (100%) mode change 100755 => 100644 rename "zh-cn/application-dev/ui/figures/\350\207\252\345\256\232\344\271\211\347\273\204\344\273\266\347\232\204\346\225\210\346\236\234.png" => zh-cn/application-dev/ui/figures/zh-cn_image_0000001212146243.png (100%) mode change 100755 => 100644 create mode 100644 zh-cn/application-dev/ui/public_sys-resources/icon-caution.gif create mode 100644 zh-cn/application-dev/ui/public_sys-resources/icon-danger.gif create mode 100644 zh-cn/application-dev/ui/public_sys-resources/icon-note.gif create mode 100644 zh-cn/application-dev/ui/public_sys-resources/icon-notice.gif create mode 100644 zh-cn/application-dev/ui/public_sys-resources/icon-tip.gif create mode 100644 zh-cn/application-dev/ui/public_sys-resources/icon-warning.gif diff --git a/zh-cn/application-dev/Readme-CN.md b/zh-cn/application-dev/Readme-CN.md new file mode 100644 index 00000000000..0301f1ec275 --- /dev/null +++ b/zh-cn/application-dev/Readme-CN.md @@ -0,0 +1,193 @@ +# 应用开发 + +- [应用开发导读](application-dev-guide.md) +- DevEco Studio(OpenHarmony)使用指南 + - [概述](quick-start/deveco-studio-overview.md) + - [版本变更说明](quick-start/deveco-studio-release-notes.md) + - [配置OpenHarmony SDK](quick-start/configuring-openharmony-sdk.md) + - 创建OpenHarmony工程 + - [使用工程向导创建新工程](quick-start/use-wizard-to-create-project.md) + - [通过导入Sample方式创建新工程](quick-start/import-sample-to-create-project.md) + - [配置OpenHarmony应用签名信息](quick-start/configuring-openharmony-app-signature.md) + - [安装运行OpenHarmony应用](quick-start/installing-openharmony-app.md) +- [包结构说明](quick-start/package-structure.md) +- 快速入门 + - [开发准备](quick-start/start-overview.md) + - [使用JS语言开发](quick-start/start-with-js.md) +- JS UI框架 + - [JS UI框架概述](ui/ui-js-overview.md) + - 构建用户界面 + - [组件介绍](ui/ui-js-building-ui-component.md) + - 构建布局 + - [布局说明](ui/ui-js-building-ui-layout-intro.md) + - [添加标题行和文本区域](ui/ui-js-building-ui-layout-text.md) + - [添加图片区域](ui/ui-js-building-ui-layout-image.md) + - [添加留言区域](ui/ui-js-building-ui-layout-comment.md) + - [添加容器](ui/ui-js-building-ui-layout-external-container.md) + - [添加交互](ui/ui-js-building-ui-interactions.md) + - [动画](ui/ui-js-building-ui-animation.md) + - [事件](ui/ui-js-building-ui-event.md) + - [页面路由](ui/ui-js-building-ui-routes.md) + - [自定义组件](ui/ui-js-custom-components.md) +- 音频 + - [音频开发概述](media/audio-overview.md) + - [音频播放开发指导](media/audio-playback.md) + - [音频管理开发指导](media/audio-management.md) + - [音频录制开发指导](media/audio-recorder.md) +- IPC与RPC通信 + - [IPC与RPC通信概述](connectivity/ipc-rpc-overview.md) + - [IPC与RPC通信开发指导](connectivity/ipc-rpc-development-guideline.md) + - [远端状态订阅开发实例](connectivity/subscribe-remote-state.md) +- JS 开发参考 + - 框架说明 + - [文件组织](js-reference/js-framework-file.md) + - [js标签配置](js-reference/js-framework-js-tag.md) + - [app.js](js-reference/js-framework-js-file.md) + - 语法 + - [HML语法参考](js-reference/js-framework-syntax-hml.md) + - [CSS语法参考](js-reference/js-framework-syntax-css.md) + - [JS语法参考](js-reference/js-framework-syntax-js.md) + - [生命周期](js-reference/js-framework-lifecycle.md) + - [资源限定与访问](js-reference/js-framework-resource-restriction.md) + - [多语言支持](js-reference/js-framework-multiple-languages.md) + - 组件 + - 通用 + - [通用属性](js-reference/component/js-components-common-attributes.md) + - [通用样式](js-reference/component/js-components-common-styles.md) + - [通用事件](js-reference/component/js-components-common-events.md) + - [通用方法](js-reference/component/js-components-common-methods.md) + - [动画样式](js-reference/component/js-components-common-animation.md) + - [渐变样式](js-reference/component/js-components-common-gradient.md) + - [转场样式](js-reference/component/js-components-common-transition.md) + - [媒体查询](js-reference/component/js-components-common-mediaquery.md) + - [自定义字体样式](js-reference/component/js-components-common-customizing-font.md) + - [原子布局](js-reference/component/js-components-common-atomic-layout.md) + - 容器组件 + - [badge](js-reference/component/js-components-container-badge.md) + - [dialog](js-reference/component/js-components-container-dialog.md) + - [div](js-reference/component/js-components-container-div.md) + - [form](js-reference/component/js-components-container-form.md) + - [list](js-reference/component/js-components-container-list.md) + - [list-item](js-reference/component/js-components-container-list-item.md) + - [list-item-group](js-reference/component/js-components-container-list-item-group.md) + - [panel](js-reference/component/js-components-container-panel.md) + - [popup](js-reference/component/js-components-container-popup.md) + - [refresh](js-reference/component/js-components-container-refresh.md) + - [stack](js-reference/component/js-components-container-stack.md) + - [stepper](js-reference/component/js-components-container-stepper.md) + - [stepper-item](js-reference/component/js-components-container-stepper-item.md) + - [swiper](js-reference/component/js-components-container-swiper.md) + - [tabs](js-reference/component/js-components-container-tabs.md) + - [tab-bar](js-reference/component/js-components-container-tab-bar.md) + - [tab-content](js-reference/component/js-components-container-tab-content.md) + - 基础组件 + - [button](js-reference/component/js-components-basic-button.md) + - [chart](js-reference/component/js-components-basic-chart.md) + - [divider](js-reference/component/js-components-basic-divider.md) + - [image](js-reference/component/js-components-basic-image.md) + - [image-animator](js-reference/component/js-components-basic-image-animator.md) + - [input](js-reference/component/js-components-basic-input.md) + - [label](js-reference/component/js-components-basic-label.md) + - [marquee](js-reference/component/js-components-basic-marquee.md) + - [menu](js-reference/component/js-components-basic-menu.md) + - [option](js-reference/component/js-components-basic-option.md) + - [picker](js-reference/component/js-components-basic-picker.md) + - [picker-view](js-reference/component/js-components-basic-picker-view.md) + - [piece](js-reference/component/js-components-basic-piece.md) + - [progress](js-reference/component/js-components-basic-progress.md) + - [qrcode](js-reference/component/js-components-basic-qrcode.md) + - [rating](js-reference/component/js-components-basic-rating.md) + - [richtext](js-reference/component/js-components-basic-richtext.md) + - [search](js-reference/component/js-components-basic-search.md) + - [select](js-reference/component/js-components-basic-select.md) + - [slider](js-reference/component/js-components-basic-slider.md) + - [span](js-reference/component/js-components-basic-span.md) + - [switch](js-reference/component/js-components-basic-switch.md) + - [text](js-reference/component/js-components-basic-text.md) + - [textarea](js-reference/component/js-components-basic-textarea.md) + - [toolbar](js-reference/component/js-components-basic-toolbar.md) + - [toolbar-item](js-reference/component/js-components-basic-toolbar-item.md) + - [toggle](js-reference/component/js-components-basic-toggle.md) + - 媒体组件 + - [video](js-reference/component/js-components-media-video.md) + - 画布组件 + - [canvas组件](js-reference/component/js-components-canvas-canvas.md) + - [CanvasRenderingContext2D对象](js-reference/component/js-components-canvas-canvasrenderingcontext2d.md) + - [Image对象](js-reference/component/js-components-canvas-image.md) + - [CanvasGradient对象](js-reference/component/js-components-canvas-canvasgradient.md) + - [ImageData对象](js-reference/component/js-components-canvas-imagedata.md) + - [Path2D对象](js-reference/component/js-components-canvas-path2d.md) + - [ImageBitmap对象](js-reference/component/js-components-canvas-imagebitmap.md) + - [OffscreenCanvas对象](js-reference/component/js-components-canvas-offscreencanvas.md) + - [OffscreenCanvasRenderingContext2D对象](js-reference/component/js-components-canvas-offscreencanvasrenderingcontext2d.md) + - 栅格组件 + - [基本概念](js-reference/component/js-components-grid-basic-concepts.md) + - [grid-container](js-reference/component/js-components-grid-container.md) + - [grid-row](js-reference/component/js-components-grid-row.md) + - [grid-col](js-reference/component/js-components-grid-col.md) + - svg组件 + - [通用属性](js-reference/component/js-components-svg-common-attributes.md) + - [svg](js-reference/component/js-components-svg.md) + - [rect](js-reference/component/js-components-svg-rect.md) + - [circle](js-reference/component/js-components-svg-circle.md) + - [ellipse](js-reference/component/js-components-svg-ellipse.md) + - [path](js-reference/component/js-components-svg-path.md) + - [line](js-reference/component/js-components-svg-line.md) + - [polyline](js-reference/component/js-components-svg-polyline.md) + - [polygon](js-reference/component/js-components-svg-polygon.md) + - [text](js-reference/component/js-components-svg-text.md) + - [tspan](js-reference/component/js-components-svg-tspan.md) + - [textPath](js-reference/component/js-components-svg-textpath.md) + - [animate](js-reference/component/js-components-svg-animate.md) + - [animateMotion](js-reference/component/js-components-svg-animate-motion.md) + - [animateTransform](js-reference/component/js-components-svg-animate-transform.md) + - 自定义组件 + - [基本用法](js-reference/component/js-components-custom-basic-usage.md) + - [自定义事件](js-reference/component/js-components-custom-events.md) + - [Props](js-reference/component/js-components-custom-props.md) + - [事件参数](js-reference/component/js-components-custom-event-parameter.md) + - [slot插槽](js-reference/component/js-components-custom-slot.md) + - [生命周期定义](js-reference/component/js-components-custom-lifecycle.md) + - 接口 + - 基本功能 + - [应用上下文](js-reference/apis/js-apis-system-app.md) + - [日志打印](js-reference/apis/js-apis-basic-features-logs.md) + - [页面路由](js-reference/apis/js-apis-system-router.md) + - [弹窗](js-reference/apis/js-apis-system-prompt.md) + - [应用配置](js-reference/apis/js-apis-system-configuration.md) + - [定时器](js-reference/apis/js-apis-system-timer.md) + - [动画](js-reference/apis/js-apis-animator.md) + - [应用打点](js-reference/apis/js-apis-hiappevent.md) + - [性能打点](js-reference/apis/js-apis-bytrace.md) + - [分布式帐号管理](js-reference/apis/js-apis-distributedaccount.md) + - 媒体 + - [音频管理](js-reference/apis/js-apis-audio.md) + - [音频播放](js-reference/apis/js-apis-media.md) + - 数据管理 + - [文件管理](js-reference/apis/js-apis-fileio.md) + - [单版本分布式数据库](js-reference/apis/js-apis-data-singlekvstore.md) + - [创建和获取分布式数据库](js-reference/apis/js-apis-data-kvmanager.md) + - [KVManager配置信息](js-reference/apis/js-apis-data-kvmanager-config.md) + - [分布式数据库操作描述](js-reference/apis/js-apis-data-kvstore.md) + - [数据类型描述](js-reference/apis/js-apis-data-type.md) + - [轻量级存储](js-reference/apis/js-apis-data-storage.md) + - 设备管理 + - [设备信息](js-reference/apis/js-apis-deviceinfo.md) + - [系统属性](js-reference/apis/js-apis-systemparameter.md) + - [系统恢复](js-reference/apis/js-apis-update.md) + - [显示设备属性](js-reference/apis/js-apis-display.md) + - [电池和充电属性](js-reference/apis/js-apis-batteryinfo.md) + - [设置系统屏幕亮度](js-reference/apis/js-apis-brightness.md) + - [系统电源管理](js-reference/apis/js-apis-power.md) + - [Runninglock锁](js-reference/apis/js-apis-runninglock.md) + - [传感器](js-reference/apis/js-apis-sensor.md) + - [振动](js-reference/apis/js-apis-vibrate.md) + - [国际化(I18n)](js-reference/apis/js-apis-i18n.md) + - [国际化(Intl)](js-reference/apis/js-apis-intl.md) + - [资源管理](js-reference/apis/js-apis-resourcemanage.md) + - [时间设置](js-reference/apis/js-apis-systemtime.md) + - [升级](js-reference/apis/js-apis-libupdateclient.md) + - [获取进程相关的信息](js-reference/apis/js-apis-process.md) + - [字符串编解码](js-reference/apis/js-apis-util.md) + - [启动一个worker](js-reference/apis/js-apis-worker.md) + - [URL字符串解析](js-reference/apis/js-apis-url.md) diff --git a/zh-cn/application-dev/application-dev-guide.md b/zh-cn/application-dev/application-dev-guide.md index 7cd523be39e..fdbb963b5b3 100644 --- a/zh-cn/application-dev/application-dev-guide.md +++ b/zh-cn/application-dev/application-dev-guide.md @@ -1,10 +1,10 @@ -# 应用开发导读 +# 应用开发导读 应用开发文档用于指导开发者通过OpenHarmony提供的接口完成应用开发。当前应用开发文档提供了在标准系统上开发应用的JS接口。 -在这部分中,开发者可以通过“[入门](https://gitee.com/openharmony/docs/blob/5b6b26c33680dd1162a4df35c896e5ddefcb55b3/zh-cn/application-dev/quick-start/Readme-CN.md)”来了解应用开发的基本方法。完整的接口清单和参考使用指导可参见“[JS开发参考](https://gitee.com/openharmony/docs/blob/5b6b26c33680dd1162a4df35c896e5ddefcb55b3/zh-cn/application-dev/js-reference/Readme-CN.md)”。 +在这部分中,开发者可以通过“[入门](quick-start/Readme-CN.md)”来了解应用开发的基本方法。完整的接口清单和参考使用指导可参见“[JS开发参考](js-reference/Readme-CN.md)”。 -除此之外,为方便开发者对常用功能进行深入理解,还提供了[UI](https://gitee.com/openharmony/docs/blob/5b6b26c33680dd1162a4df35c896e5ddefcb55b3/zh-cn/application-dev/ui/Readme-CN.md)、[媒体](https://gitee.com/openharmony/docs/blob/5b6b26c33680dd1162a4df35c896e5ddefcb55b3/zh-cn/application-dev/media/Readme-CN.md)、[网络与连接](https://gitee.com/openharmony/docs/blob/5b6b26c33680dd1162a4df35c896e5ddefcb55b3/zh-cn/application-dev/connectivity/Readme-CN.md)三个模块的开发指南。 +除此之外,为方便开发者对常用功能进行深入理解,还提供了[UI](ui/Readme-CN.md)、[媒体](media/Readme-CN.md)、[网络与连接](connectivity/Readme-CN.md)三个模块的开发指南。 如果需要了解各子系统的原理和基本信息,可以参考“docs/zh-cn/readme”目录中各子系统readme的介绍。 diff --git a/zh-cn/application-dev/connectivity/Readme-CN.md b/zh-cn/application-dev/connectivity/Readme-CN.md index 846651b2554..f14d2382ace 100755 --- a/zh-cn/application-dev/connectivity/Readme-CN.md +++ b/zh-cn/application-dev/connectivity/Readme-CN.md @@ -1,7 +1,6 @@ # 网络与连接 -- [IPC与RPC通信](ipc-rpc.md) - - [IPC与RPC通信概述](ipc-rpc-overview.md) - - [IPC与RPC通信开发指导](ipc-rpc-development-guideline.md) - - [远端状态订阅开发实例](subscribe-remote-state.md) - +- IPC与RPC通信 + - [IPC与RPC通信概述](ipc-rpc-overview.md) + - [IPC与RPC通信开发指导](ipc-rpc-development-guideline.md) + - [远端状态订阅开发实例](subscribe-remote-state.md) diff --git a/zh-cn/application-dev/connectivity/ipc-rpc-development-guideline.md b/zh-cn/application-dev/connectivity/ipc-rpc-development-guideline.md index 548d6af3859..b65b2d580b6 100755 --- a/zh-cn/application-dev/connectivity/ipc-rpc-development-guideline.md +++ b/zh-cn/application-dev/connectivity/ipc-rpc-development-guideline.md @@ -1,165 +1,133 @@ -# IPC与RPC通信开发指导 +# IPC与RPC通信开发指导 -- [场景介绍](#section18502174174019) -- [接口说明](#section1633115419401) -- [开发步骤](#section4207112818418) +- [场景介绍](#场景介绍) +- [接口说明](#接口说明) +- [开发步骤](#开发步骤) -## 场景介绍 +## 场景介绍 IPC/RPC的主要工作是让运行在不同进程的Proxy和Stub互相通信,包括Proxy和Stub运行在不同设备的情况。 -## 接口说明 - -**表 1** Native侧IPC接口 - - - - - - - - - - - - - - - - - - - - -

类/接口

-

方法

-

功能说明

-

IRemoteBroker

-

sptr<IRemoteObject> AsObject()

-

返回通信对象。派生类需要实现,Stub端返回RemoteObject对象本身,Proxy端返回代理对象。

-

IRemoteStub

-

virtual int OnRemoteRequest(uint32_t code, MessageParcel &data, MessageParcel &reply, MessageOption &option)

-

请求处理方法,派生类需要重写,处理Proxy的请求并返回结果。

-

IRemoteProxy

-
  

业务Proxy类派生自IRemoteProxy类。

-
- -## 开发步骤 -**Native侧开发步骤** +## 接口说明 -1. 定义IPC接口ITestAbility +**表1** Native侧IPC接口 - SA接口继承IPC基类接口IRemoteBroker,接口里定义描述符、业务函数和消息码,其中业务函数在Proxy端和Stub端都需要实现。 +| 类/接口 | 方法 | 功能说明 | +| -------- | -------- | -------- | +| IRemoteBroker | sptr<IRemoteObject> AsObject() | 返回通信对象。派生类需要实现,Stub端返回RemoteObject对象本身,Proxy端返回代理对象。 | +| IRemoteStub | virtual int OnRemoteRequest(uint32_t code, MessageParcel &data, MessageParcel &reply, MessageOption &option) | 请求处理方法,派生类需要重写,处理Proxy的请求并返回结果。 | +| IRemoteProxy | | 业务Proxy类派生自IRemoteProxy类。 | - ``` - class ITestAbility : public IRemoteBroker { - public: - // DECLARE_INTERFACE_DESCRIPTOR是必须的, 入参需使用std::u16string; - DECLARE_INTERFACE_DESCRIPTOR(u"test.ITestAbility"); - int TRANS_ID_PING_ABILITY = 1; // 定义消息码 - virtual int TestPingAbility(const std::u16string &dummy) = 0; // 定义业务函数 - }; - ``` -2. 定义和实现服务端TestAbilityStub +## 开发步骤 - 该类是和IPC框架相关的实现,需要继承 IRemoteStub。Stub端作为接收请求的一端,需重写OnRemoteRequest方法用于接收客户端调用。 +**Native侧开发步骤** - ``` - class TestAbilityStub : public IRemoteStub { - public: - virtual int OnRemoteRequest(uint32_t code, MessageParcel &data, MessageParcel &reply, MessageOption &option) override; - int TestPingAbility(const std::u16string &dummy) override; +1. 定义IPC接口ITestAbility + SA接口继承IPC基类接口IRemoteBroker,接口里定义描述符、业务函数和消息码,其中业务函数在Proxy端和Stub端都需要实现。 + + ``` + class ITestAbility : public IRemoteBroker { + public: + // DECLARE_INTERFACE_DESCRIPTOR是必须的,入参需使用std::u16string; + DECLARE_INTERFACE_DESCRIPTOR(u"test.ITestAbility"); + int TRANS_ID_PING_ABILITY = 1; // 定义消息码 + virtual int TestPingAbility(const std::u16string &dummy) = 0; // 定义业务函数 + }; + ``` + +2. 定义和实现服务端TestAbilityStub + 该类是和IPC框架相关的实现,需要继承 IRemoteStub<ITestAbility>。Stub端作为接收请求的一端,需重写OnRemoteRequest方法用于接收客户端调用。 + + ``` + class TestAbilityStub : public IRemoteStub { + public: + virtual int OnRemoteRequest(uint32_t code, MessageParcel &data, MessageParcel &reply, MessageOption &option) override; + int TestPingAbility(const std::u16string &dummy) override; }; - - int TestServiceStub::OnRemoteRequest(uint32_t code, - MessageParcel &data, MessageParcel &reply, MessageOption &option) - { - switch (code) { - case TRANS_ID_PING_ABILITY: { - std::u16string dummy = data.ReadString16(); - int result = TestPingAbility(dummy); - reply.WriteInt32(result); - return 0; - } - default: - return IPCObjectStub::OnRemoteRequest(code, data, reply, option); - } - } - ``` - -3. 定义服务端业务函数具体实现类TestAbility - - ``` - class TestAbility : public TestAbilityStub { - public: - int TestPingAbility(const std::u16string &dummy); - } - - int TestAbility::TestPingAbility(const std::u16string &dummy) { - return 0; - } - ``` - -4. 定义和实现客户端TestAbilityProxy - - 该类是Proxy端实现,继承IRemoteProxy,调用SendRequest接口向Stub端发送请求,对外暴露服务端提供的能力。 - - ``` - class TestAbilityProxy : public IRemoteProxy { - public: - explicit TestAbilityProxy(const sptr &impl); - int TestPingService(const std::u16string &dummy) override; - private: - static inline BrokerDelegator delegator_; // 方便后续使用iface_cast宏 + + int TestServiceStub::OnRemoteRequest(uint32_t code, + MessageParcel &data, MessageParcel &reply, MessageOption &option) + { + switch (code) { + case TRANS_ID_PING_ABILITY: { + std::u16string dummy = data.ReadString16(); + int result = TestPingAbility(dummy); + reply.WriteInt32(result); + return 0; + } + default: + return IPCObjectStub::OnRemoteRequest(code, data, reply, option); + } + } + ``` + +3. 定义服务端业务函数具体实现类TestAbility + ``` + class TestAbility : public TestAbilityStub { + public: + int TestPingAbility(const std::u16string &dummy); + } + + int TestAbility::TestPingAbility(const std::u16string &dummy) { + return 0; + } + ``` + +4. 定义和实现客户端 TestAbilityProxy + 该类是Proxy端实现,继承IRemoteProxy<ITestAbility>,调用SendRequest接口向Stub端发送请求,对外暴露服务端提供的能力。 + + ``` + class TestAbilityProxy : public IRemoteProxy { + public: + explicit TestAbilityProxy(const sptr &impl); + int TestPingService(const std::u16string &dummy) override; + private: + static inline BrokerDelegator delegator_; // 方便后续使用iface_cast宏 + } + + TestAbilityProxy::TestAbilityProxy(const sptr &impl) + : IRemoteProxy(impl) + { + } + + int TestAbilityProxy::TestPingService(const std::u16string &dummy){ + MessageOption option; + MessageParcel dataParcel, replyParcel; + dataParcel.WriteString16(dummy); + int error = Remote()->SendRequest(TRANS_ID_PING_ABILITY, dataParcel, replyParcel, option); + int result = (error == ERR_NONE) ? replyParcel.ReadInt32() : -1; + return result; } - - TestAbilityProxy::TestAbilityProxy(const sptr &impl) - : IRemoteProxy(impl) - { - } - - int TestAbilityProxy::TestPingService(const std::u16string &dummy) { - MessageOption option; - MessageParcel dataParcel, replyParcel; - dataParcel.WriteString16(dummy); - int error = Remote()->SendRequest(TRANS_ID_PING_ABILITY, dataParcel, replyParcel, option); - int result = (error == ERR_NONE) ? replyParcel.ReadInt32() : -1; - return result; - } - ``` - -5. SA注册与启动 - - SA需要将自己的TestAbilityStub实例通过AddSystemAbility接口注册到SystemAbilityManager,设备内与分布式的注册参数不同。 - - ``` - // 注册到本设备内 - auto samgr = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager(); - samgr->AddSystemAbility(said, new TestAbility()); - - // 在组网场景下,会被同步到其他设备上 - auto samgr = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager(); - ISystemAbilityManager::SAExtraProp saExtra; - saExtra.isDistributed = true; // 设置为分布式SA - int result = samgr->AddSystemAbility(said, new TestAbility(), saExtra); - ``` - -6. SA获取与调用 - - 通过SystemAbilityManager的GetSystemAbility方法可获取到对应SA的代理IRemoteObject,然后构造TestAbilityProxy即可。 - - ``` - // 获取本设备内注册的SA的proxy - sptr samgr = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager(); - sptr remoteObject = samgr->GetSystemAbility(said); - sptr testAbility = iface_cast(remoteObject); // 使用iface_cast宏转换成具体类型 - - // 获取其他设备注册的SA的Proxy - sptr samgr = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager(); - sptr remoteObject = samgr->GetSystemAbility(sdid, deviceId); // deviceId是指定设备的标识符 - sptr proxy(new TestAbilityProxy(remoteObject)); // 直接构造具体Proxy - ``` - - + ``` + +5. SA 注册与启动 + SA 需要将自己的 TestAbilityStub实例通过 AddSystemAbility接口注册到 SystemAbilityManager,设备内与分布式的注册参数不同。 + + ``` + // 注册到本设备内 + auto samgr = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager(); + samgr->AddSystemAbility(said, new TestAbility()); + + // 在组网场景下,会被同步到其他设备上 + auto samgr = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager(); + ISystemAbilityManager::SAExtraProp saExtra; + saExtra.isDistributed = true; // 设置为分布式SA + int result = samgr->AddSystemAbility(said, new TestAbility(), saExtra); + ``` + +6. SA 获取与调用 + 通过SystemAbilityManager的GetSystemAbility方法可获取到对应SA的代理IRemoteObject,然后构造TestAbilityProxy即可。 + + ``` + // 获取本设备内注册的SA的proxy + sptr samgr = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager(); + sptr remoteObject = samgr->GetSystemAbility(said); + sptr testAbility = iface_cast(remoteObject); // 使用iface_cast宏转换成具体类型 + + // 获取其他设备注册的SA的Proxy + sptr samgr = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager(); + sptr remoteObject = samgr->GetSystemAbility(sdid, deviceId); // deviceId是指定设备的标识符 + sptr proxy(new TestAbilityProxy(remoteObject)); // 直接构造具体Proxy + ``` diff --git a/zh-cn/application-dev/connectivity/ipc-rpc-overview.md b/zh-cn/application-dev/connectivity/ipc-rpc-overview.md index 64a94f239d2..009802f3407 100755 --- a/zh-cn/application-dev/connectivity/ipc-rpc-overview.md +++ b/zh-cn/application-dev/connectivity/ipc-rpc-overview.md @@ -1,20 +1,21 @@ -# IPC与RPC通信概述 +# IPC与RPC通信概述 -- [基本概念](#section175012297491) -- [约束与限制](#section2029921310472) -- [相关模块](#section1189019299446) +- [基本概念](#基本概念) +- [约束与限制](#约束与限制) +- [相关模块](#相关模块) -## 基本概念 +## 基本概念 IPC(Inter-Process Communication)与RPC(Remote Procedure Call)机制用于实现跨进程通信,不同的是前者使用Binder驱动,用于设备内的跨进程通信,而后者使用软总线驱动,用于跨设备跨进程通信。IPC和RPC通常采用客户端-服务器(Client-Server)模型,服务请求方(Client)可获取提供服务提供方(Server)的代理 (Proxy),并通过此代理读写数据来实现进程间的数据通信。通常,Server会先注册系统能力(System Ability)到系统能力管理者(System Ability Manager,缩写SAMgr)中,SAMgr负责管理这些SA并向Client提供相关的接口。Client要和某个具体的SA通信,必须先从SAMgr中获取该SA的代理,然后使用代理和SA通信。下文使用Proxy表示服务请求方,Stub表示服务提供方。 -## 约束与限制 + +## 约束与限制 目前暂不支持的场景: 跨设备RPC -## 相关模块 -分布式任务调度子系统 +## 相关模块 +分布式任务调度子系统 diff --git a/zh-cn/application-dev/connectivity/ipc-rpc.md b/zh-cn/application-dev/connectivity/ipc-rpc.md index eab1edb4797..b28f4d1c71d 100644 --- a/zh-cn/application-dev/connectivity/ipc-rpc.md +++ b/zh-cn/application-dev/connectivity/ipc-rpc.md @@ -1,9 +1,8 @@ -# IPC与RPC通信 +# IPC与RPC通信 -- **[IPC与RPC通信概述](ipc-rpc-overview.md)** -- **[IPC与RPC通信开发指导](ipc-rpc-development-guideline.md)** - -- **[远端状态订阅开发实例](subscribe-remote-state.md)** +- **[IPC与RPC通信概述](ipc-rpc-overview.md)** +- **[IPC与RPC通信开发指导](ipc-rpc-development-guideline.md)** +- **[远端状态订阅开发实例](subscribe-remote-state.md)** \ No newline at end of file diff --git a/zh-cn/application-dev/connectivity/public_sys-resources/icon-caution.gif b/zh-cn/application-dev/connectivity/public_sys-resources/icon-caution.gif new file mode 100644 index 0000000000000000000000000000000000000000..6e90d7cfc2193e39e10bb58c38d01a23f045d571 GIT binary patch literal 580 zcmV-K0=xZ3Nk%w1VIu$?0Hp~4{QBgqmQ+MG9K51r{QB&)np^||1PlfQ%(86!{`~yv zv{XhUWKt}AZaiE{EOcHp{O-j3`t;<+eEiycJT4p@77X;(jQsMfB$R?oG%6hQ z+MMLZbQBH@)Vg&1^3?qHb(5!%>3r0+`eq=&V&E}0Dypi0000000000 z00000A^8LW000R9EC2ui03!e$000L5z=Uu}ED8YtqjJd<+B}(9bIOb$3-31_h|V>=0A{ z1Hh0#H30>fNT})^fRU_83uewx9oRr{f{Sx1Ml`t)EQ zGkHZ67&~y{W5Jpq4H_WfuLxp*3<7O}GEl;1ESe36fLNs=B0&LQM1Buf(R)qg(BRd`t1OPjI1m_q4 literal 0 HcmV?d00001 diff --git a/zh-cn/application-dev/connectivity/public_sys-resources/icon-danger.gif b/zh-cn/application-dev/connectivity/public_sys-resources/icon-danger.gif new file mode 100644 index 0000000000000000000000000000000000000000..6e90d7cfc2193e39e10bb58c38d01a23f045d571 GIT binary patch literal 580 zcmV-K0=xZ3Nk%w1VIu$?0Hp~4{QBgqmQ+MG9K51r{QB&)np^||1PlfQ%(86!{`~yv zv{XhUWKt}AZaiE{EOcHp{O-j3`t;<+eEiycJT4p@77X;(jQsMfB$R?oG%6hQ z+MMLZbQBH@)Vg&1^3?qHb(5!%>3r0+`eq=&V&E}0Dypi0000000000 z00000A^8LW000R9EC2ui03!e$000L5z=Uu}ED8YtqjJd<+B}(9bIOb$3-31_h|V>=0A{ z1Hh0#H30>fNT})^fRU_83uewx9oRr{f{Sx1Ml`t)EQ zGkHZ67&~y{W5Jpq4H_WfuLxp*3<7O}GEl;1ESe36fLNs=B0&LQM1Buf(R)qg(BRd`t1OPjI1m_q4 literal 0 HcmV?d00001 diff --git a/zh-cn/application-dev/connectivity/public_sys-resources/icon-note.gif b/zh-cn/application-dev/connectivity/public_sys-resources/icon-note.gif new file mode 100644 index 0000000000000000000000000000000000000000..6314297e45c1de184204098efd4814d6dc8b1cda GIT binary patch literal 394 zcmZ?wbhEHblx7fPSjxcg=ii?@_wH=jwxy=7CMGH-B`L+l$wfv=#>UF#$gv|VY%C^b zCQFtrnKN(Bo_%|sJbO}7RAORe!otL&qo<>yq_Sq+8Xqqo5h0P3w3Lvb5E(g{p01vl zxR@)KuDH0l^z`+-dH3eaw=XqSH7aTIx{kzVBN;X&hha0dQSgWuiw0NWUvMRmkD|> literal 0 HcmV?d00001 diff --git a/zh-cn/application-dev/connectivity/public_sys-resources/icon-notice.gif b/zh-cn/application-dev/connectivity/public_sys-resources/icon-notice.gif new file mode 100644 index 0000000000000000000000000000000000000000..86024f61b691400bea99e5b1f506d9d9aef36e27 GIT binary patch literal 406 zcmV;H0crk6Nk%w1VIu$@0J8u9|NsB@_xJDb@8;&_*4Ea}&d#;9wWXz{jEszHYim+c zQaU<1At50E0000000000A^8Le000gEEC2ui03!e%000R7038S%NU)&51O^i-Tu6`s z0)`MFE@;3YqD6xSC^kTNu_J>91{PH8XfZ(p1pp2-SU@u3#{mEUC}_}tg3+I#{z}{Ok@D_ZUDg- zt0stin4;pC8M{WLSlRH*1pzqEw1}3oOskyNN?j;7HD{BBZ*OEcv4HK!6Bk6beR+04 z&8}k>SkTusVTDmkyOz#5fCA$JTPGJVQvr3uZ?QzzPQFvD0rGf_PdrcF`pMs}p^BcF zKtKTd`0wipR%nKN&Wj+V}pX;WC3SdJV!a_8Qi zE7z`U*|Y^H0^}fB$R?oG%6hQ z+MMLZbQBH@)Vg&1^3?qHb(5!%>3r0+`eq=&V&E}0Dypi0000000000 z00000A^8LW000R9EC2ui03!e$000L5z=Uu}ED8YtqjJd<+B}(9bIOb$3-31_h|V>=0A{ z1Hh0#H30>fNT})^fRU_83uewx9oRr{f{Sx1Ml`t)EQ zGkHZ67&~y{W5Jpq4H_WfuLxp*3<7O}GEl;1ESe36fLNs=B0&LQM1Buf(R)qg(BRd`t1OPjI1m_q4 literal 0 HcmV?d00001 diff --git a/zh-cn/application-dev/connectivity/subscribe-remote-state.md b/zh-cn/application-dev/connectivity/subscribe-remote-state.md index dd8ff7a0c26..05ac640b376 100755 --- a/zh-cn/application-dev/connectivity/subscribe-remote-state.md +++ b/zh-cn/application-dev/connectivity/subscribe-remote-state.md @@ -1,28 +1,34 @@ -# 远端状态订阅开发实例 +# 远端状态订阅开发实例 + +IPC/RPC 提供对远端 Stub对象状态的订阅机制, 在远端 Stub对象死亡时,可触发死亡通知告诉本地 Proxy对象。这种状态通知订阅并不会自动附加在每个本地 Proxy对象上,需要调用特定接口完成,当不再需要订阅时也需要调用特定接口取消。使用这种订阅机制的用户,需要实现死亡通知接口DeathRecipient并实现onRemoteDied方法,清理资源,该方法会在 远端 Stub对象所在进程死亡,或所在设备离开组网时被回调。值得注意的是,调用这些接口有一定的顺序。首先,必然需要 Proxy订阅 Stub死亡通知,若在订阅期间未发生 Stub死亡,则可在不再需要时取消订阅;若在订阅期间发生 Stub死亡,则会自动触发 Proxy自定义的后续操作,也无需再手动取消订阅。 + + +RPC目前不提供匿名 Stub对象的死亡通知,即只有向 SAMgr注册过的服务才能被订阅死亡通知。 IPC则支持匿名对象的死亡通知。 -IPC/RPC提供对远端Stub对象状态的订阅机制, 在远端Stub对象死亡时,可触发死亡通知告诉本地Proxy对象。这种状态通知订阅并不会自动附加在每个本地Proxy对象上,需要调用特定接口完成,当不再需要订阅时也需要调用特定接口取消。使用这种订阅机制的用户,需要实现死亡通知接口DeathRecipient并实现onRemoteDied方法,清理资源,该方法会在远端Stub对象所在进程死亡,或所在设备离开组网时被回调。值得注意的是,调用这些接口有一定的顺序。首先,必然需要Proxy订阅Stub死亡通知,若在订阅期间未发生Stub死亡,则可在不再需要时取消订阅;若在订阅期间发生Stub死亡,则会自动触发Proxy自定义的后续操作,也无需再手动取消订阅。 -RPC目前不提供匿名Stub对象的死亡通知,即只有向SAMgr注册过的服务才能被订阅死亡通知。IPC则支持匿名对象的死亡通知。 **Native侧接口** + 依次为添加对远端Stub对象状态订阅的接口,取消订阅的接口,及感知到远端Stub对象死亡而进行本地操作的接口: + ``` bool AddDeathRecipient(const sptr &recipient); bool RemoveDeathRecipient(const sptr &recipient); void OnRemoteDied(const wptr &object); ``` + 参考代码 + ``` class TestDeathRecipient : public IRemoteObject::DeathRecipient { public: virtual void OnRemoteDied(const wptr& remoteObject); } -sptr deathRecipient (new TestDeathRecipient()); // 构造一个死亡通知对象 +sptr deathRecipient (new TestDeathRecipient());// 构造一个死亡通知对象 bool result = proxy->AddDeathRecipient(deathRecipient); // 注册死亡通知 result = proxy->RemoveDeathRecipient(deathRecipient); // 移除死亡通知 ``` - diff --git a/zh-cn/application-dev/js-reference/Readme-CN.md b/zh-cn/application-dev/js-reference/Readme-CN.md index a8f7f743211..f6c0c2e1be1 100755 --- a/zh-cn/application-dev/js-reference/Readme-CN.md +++ b/zh-cn/application-dev/js-reference/Readme-CN.md @@ -1,10 +1,10 @@ # JS开发参考 -- [框架说明](js-framework.md) +- 框架说明 - [文件组织](js-framework-file.md) - [js标签配置](js-framework-js-tag.md) - [app.js](js-framework-js-file.md) - - [语法](js-framework-syntax.md) + - 语法 - [HML语法参考](js-framework-syntax-hml.md) - [CSS语法参考](js-framework-syntax-css.md) - [JS语法参考](js-framework-syntax-js.md) @@ -14,7 +14,7 @@ - [多语言支持](js-framework-multiple-languages.md) - [组件](component/Readme-CN.md) - - [通用](component/js-components-common.md) + - 通用 - [通用属性](component/js-components-common-attributes.md) - [通用样式](component/js-components-common-styles.md) - [通用事件](component/js-components-common-events.md) @@ -26,7 +26,7 @@ - [自定义字体样式](component/js-components-common-customizing-font.md) - [原子布局](component/js-components-common-atomic-layout.md) - - [容器组件](component/js-components-container.md) + - 容器组件 - [badge](component/js-components-container-badge.md) - [dialog](component/js-components-container-dialog.md) - [div](component/js-components-container-div.md) @@ -45,7 +45,7 @@ - [tab-bar](component/js-components-container-tab-bar.md) - [tab-content](component/js-components-container-tab-content.md) - - [基础组件](component/js-components-basic.md) + - 基础组件 - [button](component/js-components-basic-button.md) - [chart](component/js-components-basic-chart.md) - [divider](component/js-components-basic-divider.md) @@ -74,10 +74,10 @@ - [toolbar-item](component/js-components-basic-toolbar-item.md) - [toggle](component/js-components-basic-toggle.md) - - [媒体组件](component/js-components-media.md) + - 媒体组件 - [video](component/js-components-media-video.md) - - [画布组件](component/js-components-canvas.md) + - 画布组件 - [canvas组件](component/js-components-canvas-canvas.md) - [CanvasRenderingContext2D对象](component/js-components-canvas-canvasrenderingcontext2d.md) - [Image对象](component/js-components-canvas-image.md) @@ -88,15 +88,15 @@ - [OffscreenCanvas对象](component/js-components-canvas-offscreencanvas.md) - [OffscreenCanvasRenderingContext2D对象](component/js-components-canvas-offscreencanvasrenderingcontext2d.md) - - [栅格组件](component/js-components-grid.md) + - 栅格组件 - [基本概念](component/js-components-grid-basic-concepts.md) - [grid-container](component/js-components-grid-container.md) - [grid-row](component/js-components-grid-row.md) - [grid-col](component/js-components-grid-col.md) - - [svg组件](component/js-components-svg.md) + - svg组件 - [通用属性](component/js-components-svg-common-attributes.md) - - [svg](component/js-components-svg-0.md) + - [svg](component/js-components-svg.md) - [rect](component/js-components-svg-rect.md) - [circle](component/js-components-svg-circle.md) - [ellipse](component/js-components-svg-ellipse.md) @@ -111,7 +111,7 @@ - [animateMotion](component/js-components-svg-animate-motion.md) - [animateTransform](component/js-components-svg-animate-transform.md) -- [自定义组件](component/js-components-custom.md) +- 自定义组件 - [基本用法](component/js-components-custom-basic-usage.md) - [自定义事件](component/js-components-custom-events.md) - [Props](component/js-components-custom-props.md) @@ -130,7 +130,7 @@ - [Notification模块](apis/js-apis-notification.md) - [Context模块](apis/js-apis-Context.md) - - [基本功能](apis/js-apis-basic-features.md) + - 基本功能 - [应用上下文](apis/js-apis-system-app.md) - [日志打印](apis/js-apis-basic-features-logs.md) - [页面路由](apis/js-apis-system-router.md) @@ -141,8 +141,8 @@ - [应用打点](apis/js-apis-hiappevent.md) - [性能打点](apis/js-apis-bytrace.md) - [分布式帐号管理](apis/js-apis-distributedaccount.md) - - - [媒体](apis/js-apis-multmedia.md) + + - 媒体 - [音频管理](apis/js-apis-audio.md) - [音频播放](apis/js-apis-media.md) @@ -152,7 +152,7 @@ - [SIM卡管理](apis/js-apis-sim.md) - [网络搜索](apis/js-apis-radio.md) - - [数据管理](apis/js-apis-data.md) + - 数据管理 - [文件管理](apis/js-apis-fileio.md) - [单版本分布式数据库](apis/js-apis-data-singlekvstore.md) - [创建和获取分布式数据库](apis/js-apis-data-kvmanager.md) @@ -160,8 +160,8 @@ - [分布式数据库操作描述](apis/js-apis-data-kvstore.md) - [数据类型描述](apis/js-apis-data-type.md) - [轻量级存储](apis/js-apis-data-storage.md) - - - [设备管理](apis/js-apis-device-mgmt.md) + + - 设备管理 - [设备信息](apis/js-apis-deviceinfo.md) - [系统属性](apis/js-apis-systemparameter.md) - [系统恢复](apis/js-apis-update.md) diff --git a/zh-cn/application-dev/js-reference/apis/js-apis-call.md b/zh-cn/application-dev/js-reference/apis/js-apis-call.md index 5ce29415fd0..784b99569ae 100755 --- a/zh-cn/application-dev/js-reference/apis/js-apis-call.md +++ b/zh-cn/application-dev/js-reference/apis/js-apis-call.md @@ -1,38 +1,40 @@ -# 拨打电话 - -- [导入模块](#section111401036143) -- [call.dial](#section1961259194312) -- [call.dial](#section387281814438) -- [call.dial](#section37173354913) -- [call.hasCall](#section19558123217015) -- [call.hasCall](#section12874319303) -- [call.getCallState](#section5882223124910) -- [call.getCallState](#section198597561794) -- [call.isEmergencyPhoneNumber7+](#section8560112174319) -- [call.isEmergencyPhoneNumber7+](#section9565131204319) -- [call.isEmergencyPhoneNumber7+](#section5569131234312) -- [call.formatPhoneNumber7+](#section1532018310579) -- [call.formatPhoneNumber7+](#section1832553165720) -- [call.formatPhoneNumber7+](#section1933033195716) -- [call.formatPhoneNumberToE1647+](#section10285180112418) -- [call.formatPhoneNumberToE1647+](#section142931509247) -- [DialOptions](#section12262183471518) -- [CallState](#section345181318300) -- [EmergencyNumberOptions7+](#section03689893518) -- [NumberFormatOptions7+](#section23348305716) +# 拨打电话 + +- [导入模块](#导入模块) +- [call.dial](#call.dial-callback1) +- [call.dial](#call.dial-callback2) +- [call.dial](#call.dial-promise) +- [call.hasCall](#call.hasCall-callback) +- [call.hasCall](#call.hasCall-promise) +- [call.getCallState](#call.getCallState-callback]) +- [call.getCallState](#call.getCallState-promise) +- [call.isEmergencyPhoneNumber7+](#call.isEmergencyPhoneNumber-callback1) +- [call.isEmergencyPhoneNumber7+](#call.isEmergencyPhoneNumber-callback2) +- [call.isEmergencyPhoneNumber7+](#call.isEmergencyPhoneNumber-promise) +- [call.formatPhoneNumber7+](#call.formatPhoneNumber-callback1) +- [call.formatPhoneNumber7+](#call.formatPhoneNumber-callback2) +- [call.formatPhoneNumber7+](#call.formatPhoneNumber-promise) +- [call.formatPhoneNumberToE1647+](#call.formatPhoneNumberToE164-callback) +- [call.formatPhoneNumberToE1647+](#call.formatPhoneNumberToE164-promise) +- [DialOptions](#DialOptions) +- [CallState](#CallState) +- [EmergencyNumberOptions7+](#EmergencyNumberOptions) +- [NumberFormatOptions7+](#NumberFormatOptions) >**说明:** > ->标记7+的表示从API Version 7开始支持,未标记的表示从API Version 6开始支持。 +>- 从 API Version 6 开始支持。 +> +>- 标记7+的接口从API Version 7开始支持。 -## 导入模块 +## 导入模块 ``` import call from '@ohos.telephony.call'; ``` -## call.dial +## call.dial dial\(phoneNumber: string, callback: AsyncCallback\): void @@ -40,41 +42,13 @@ dial\(phoneNumber: string, callback: AsyncCallback\): void 需要权限:ohos.permission.PLACE\_CALL权限,该权限为系统权限。 -- 参数 - - - - - - - - - - - - - - - - - - - -

参数名

-

类型

-

必填

-

说明

-

phoneNumber

-

string

-

-

电话号码。

-

callback

-

AsyncCallback<boolean>

-

-

回调函数:

-
  • true:成功。
  • false:失败。
-
- +- 参数 + + | 参数 | 类型 | 必填 | 说明 | + | -------- | -------- | -------- | -------- | + | phoneNumber | string | 是 |电话号码。| + | callback |AsyncCallback<boolean>|是|回调函数:
- true:成功。
- false:失败。| + - 示例 ``` @@ -84,7 +58,7 @@ dial\(phoneNumber: string, callback: AsyncCallback\): void ``` -## call.dial +## call.dial dial\(phoneNumber: string, options: DialOptions, callback: AsyncCallback\): void @@ -92,49 +66,14 @@ dial\(phoneNumber: string, options: DialOptions, callback: AsyncCallback - - - - - - - - - - - - - - - - - - - - - - -

参数名

-

类型

-

必填

-

说明

-

phoneNumber

-

string

-

-

电话号码。

-

options

-

DialOptions

-

-

通话参数,参考DialOptions

-

callback

-

AsyncCallback<boolean>

-

-

回调函数:

-
  • true:成功。
  • false:失败。
-
+- 参数 + + | 参数 | 类型 | 必填 | 说明 | + | ----------- | ---------------------------- | ---- | ------------------------------------------------- | + | phoneNumber | string | 是 | 电话号码。 | + | options | DialOptions | 是 | 通话参数,参考[DialOptions](#DialOptions)。 | + | callback | AsyncCallback<boolean> | 是 | 回调函数:
- true:成功。
- false:失败。 | + - 示例 @@ -147,7 +86,7 @@ dial\(phoneNumber: string, options: DialOptions, callback: AsyncCallback +## call.dial dial\(phoneNumber: string, options?: DialOptions\): Promise @@ -157,55 +96,16 @@ dial\(phoneNumber: string, options?: DialOptions\): Promise - 参数 - - - - - - - - - - - - - - - - - - - -

参数名

-

类型

-

必填

-

说明

-

phoneNumber

-

string

-

-

电话号码。

-

options

-

DialOptions

-

-

通话参数,参考DialOptions

-
- -- 返回值 - - - - - - - - - - -

类型

-

说明

-

Promise<boolean>

-

以Promise形式返回拨打电话的结果。

-
+ | 参数 | 类型 | 必填 | 说明 | + | ----------- | ----------- | ---- | ------------------------------------------- | + | phoneNumber | string | 是 | 电话号码。 | + | options | DialOptions | 是 | 通话参数,参考[DialOptions](#DialOptions)。 | + +- 返回值 + + | 类型 | 说明 | + | ---------------------- | --------------------------------- | + | Promise<boolean> | 以Promise形式返回拨打电话的结果。 | - 示例 @@ -220,37 +120,17 @@ dial\(phoneNumber: string, options?: DialOptions\): Promise }); ``` -## call.hasCall +## call.hasCall hasCall\(callback: AsyncCallback\): void 判断是否存在通话,使用callback方式作为异步方法。 -- 参数 - - - - - - - - - - - - - - -

参数名

-

类型

-

必填

-

说明

-

callback

-

AsyncCallback<boolean>

-

-

回调函数:

-
  • true:当前存在通话。
  • false:当前不存在通话。
-
+- 参数 + + | 参数 | 类型 | 必填 | 说明 | + | -------- | ---------------------------- | ---- | ------------------------------------------------------------ | + | callback | AsyncCallback<boolean> | 是 | 回调函数:
- true:当前存在通话。
- false:当前不存在通话。 | - 示例 @@ -261,28 +141,17 @@ hasCall\(callback: AsyncCallback\): void ``` -## call.hasCall +## call.hasCall hasCall\(\): Promise 判断是否存在通话,使用Promise方式作为异步方法。 -- 返回值 - - - - - - - - - - -

类型

-

说明

-

Promise<boolean>

-

以Promise形式异步返回判断是否存在通话。

-
+- 返回值 + + | 类型 | 说明 | + | ---------------------- | --------------------------------------- | + | Promise<boolean> | 以Promise形式异步返回判断是否存在通话。 | - 示例 @@ -296,36 +165,17 @@ hasCall\(\): Promise ``` -## call.getCallState +## call.getCallState getCallState\(callback: AsyncCallback\): void 获取通话状态,使用callback方式作为异步方法。 -- 参数 - - - - - - - - - - - - - - -

参数名

-

类型

-

必填

-

说明

-

callback

-

AsyncCallback<CallState>

-

-

回调函数,异步返回获取到的通话状态。

-
+- 参数 + + | 参数 | 类型 | 必填 | 说明 | + | -------- | -------------------------------------------- | ---- | ------------------------------------ | + | callback | AsyncCallback<[CallState](#CallState)> | 是 | 回调函数:异步返回获取到的通话状态。 | - 示例 @@ -336,28 +186,17 @@ getCallState\(callback: AsyncCallback\): void ``` -## call.getCallState +## call.getCallState getCallState\(\): Promise 获取通话状态,使用Promise方式作为异步方法。 -- 返回值 - - - - - - - - - - -

类型

-

说明

-

Promise<CallState>

-

以Promise形式异步返回获取通话状态的结果。

-
+- 返回值 + + | 类型 | 说明 | + | -------------------------------------- | ----------------------------------------- | + | Promise<[CallState](#CallState)> | 以Promise形式异步返回获取通话状态的结果。 | - 示例 @@ -370,46 +209,18 @@ getCallState\(\): Promise }); ``` -## call.isEmergencyPhoneNumber7+ +## call.isEmergencyPhoneNumber7+ isEmergencyPhoneNumber\(phoneNumber: string, callback: AsyncCallback\): void 判断是否是紧急电话号码,使用callback方式作为异步方法。 -- 参数 - - - - - - - - - - - - - - - - - - - -

参数名

-

类型

-

必填

-

说明

-

phoneNumber

-

string

-

-

电话号码。

-

callback

-

AsyncCallback<boolean>

-

-

回调函数,返回判断是否是紧急电话号码的结果:

-
  • true:是紧急电话号码。
  • false:不是紧急电话号码。
-
+- 参数 + + | 参数 | 类型 | 必填 | 说明 | + | ----------- | ---------------------------- | ---- | ------------------------------------------------------------ | + | phoneNumber | string | 是 | 电话号码。 | + | callback | AsyncCallback<boolean> | 是 | 回调函数,返回判断是否是紧急电话号码的结果:
- true:是紧急电话号码。
- false:不是紧急电话号码。 | - 示例 @@ -420,7 +231,7 @@ isEmergencyPhoneNumber\(phoneNumber: string, callback: AsyncCallback\) ``` -## call.isEmergencyPhoneNumber7+ +## call.isEmergencyPhoneNumber7+ isEmergencyPhoneNumber\(phoneNumber: string, options: EmergencyNumberOptions, callback: AsyncCallback\): void @@ -428,48 +239,11 @@ isEmergencyPhoneNumber\(phoneNumber: string, options: EmergencyNumberOptions, ca - 参数 - - - - - - - - - - - - - - - - - - - - - - - - -

参数名

-

类型

-

必填

-

说明

-

phoneNumber

-

string

-

-

电话号码。

-

options

-

EmergencyNumberOptions

-

-

手机参数,参考EmergencyNumberOptions

-

callback

-

AsyncCallback<boolean>

-

-

回调函数,返回判断是否是紧急电话号码的结果:

-
  • true:是紧急电话号码。
  • false:不是紧急电话号码。
-
+ | 参数 | 类型 | 必填 | 说明 | + | ----------- | ---------------------------- | ---- | ------------------------------------------------------------ | + | phoneNumber | string | 是 | 电话号码。 | + | options | EmergencyNumberOptions | 是 | 手机参数,参考[EmergencyNumberOptions](#EmergencyNumberOptions)。 | + | callback | AsyncCallback<boolean> | 是 | 回调函数,返回判断是否是紧急电话号码的结果:
- true:是紧急电话号码。
- false:不是紧急电话号码。 | - 示例 @@ -480,7 +254,7 @@ isEmergencyPhoneNumber\(phoneNumber: string, options: EmergencyNumberOptions, ca ``` -## call.isEmergencyPhoneNumber7+ +## call.isEmergencyPhoneNumber7+ isEmergencyPhoneNumber\(phoneNumber: string, options?: EmergencyNumberOptions\): Promise @@ -488,56 +262,16 @@ isEmergencyPhoneNumber\(phoneNumber: string, options?: EmergencyNumberOptions\): - 参数 - - - - - - - - - - - - - - - - - - - -

参数名

-

类型

-

必填

-

说明

-

phoneNumber

-

string

-

-

电话号码。

-

options

-

EmergencyNumberOptions

-

-

手机参数,参考EmergencyNumberOptions

-
+ | 参数 | 类型 | 必填 | 说明 | + | ----------- | ---------------------- | ---- | ------------------------------------------------------------ | + | phoneNumber | string | 是 | 电话号码。 | + | options | EmergencyNumberOptions | 是 | 手机参数,参考[EmergencyNumberOptions](#EmergencyNumberOptions)。 | - 返回值 - - - - - - - - - - -

类型

-

说明

-

Promise<boolean>

-

以Promise形式异步返回判断是否是紧急电话号码的结果。

-
+ | 类型 | 说明 | + | ---------------------- | --------------------------------------------------- | + | Promise<boolean> | 以Promise形式异步返回判断是否是紧急电话号码的结果。 | - 示例 @@ -550,45 +284,18 @@ isEmergencyPhoneNumber\(phoneNumber: string, options?: EmergencyNumberOptions\): }); ``` -## call.formatPhoneNumber7+ +## call.formatPhoneNumber7+ formatPhoneNumber\(phoneNumber: string, callback: AsyncCallback\): void 格式化电话号码,使用callback方式作为异步方法。 -- 参数 - - - - - - - - - - - - - - - - - - - -

参数名

-

类型

-

必填

-

说明

-

phoneNumber

-

string

-

-

电话号码。

-

callback

-

AsyncCallback<string>

-

-

回调函数,返回格式化电话号码的结果。

-
+- 参数 + + | 参数 | 类型 | 必填 | 说明 | + | ----------- | --------------------------- | ---- | ------------------------------------ | + | phoneNumber | string | 是 | 电话号码。 | + | callback | AsyncCallback<string> | 是 | 回调函数,返回格式化电话号码的结果。 | - 示例 @@ -599,54 +306,19 @@ formatPhoneNumber\(phoneNumber: string, callback: AsyncCallback\): void ``` -## call.formatPhoneNumber7+ +## call.formatPhoneNumber7+ formatPhoneNumber\(phoneNumber: string, options: NumberFormatOptions, callback: AsyncCallback\): void 格式化电话号码,可设置格式化参数,使用callback方式作为异步方法。 -- 参数 - - - - - - - - - - - - - - - - - - - - - - - - -

参数名

-

类型

-

必填

-

说明

-

phoneNumber

-

string

-

-

电话号码。

-

options

-

NumberFormatOptions

-

-

格式化参数,参考NumberFormatOptions

-

callback

-

AsyncCallback<string>

-

-

回调函数,返回格式化电话号码的结果。

-
+- 参数 + + | 参数 | 类型 | 必填 | 说明 | + | ----------- | --------------------------- | ---- | ------------------------------------------------------------ | + | phoneNumber | string | 是 | 电话号码。 | + | options | NumberFormatOptions | 是 | 格式化参数,参考[NumberFormatOptions](#NumberFormatOptions)。 | + | callback | AsyncCallback<string> | 是 | 回调函数,返回格式化电话号码的结果。 | - 示例 @@ -659,62 +331,24 @@ formatPhoneNumber\(phoneNumber: string, options: NumberFormatOptions, callback: ``` -## call.formatPhoneNumber7+ +## call.formatPhoneNumber7+ formatPhoneNumber\(phoneNumber: string, options?: NumberFormatOptions\): Promise 格式化电话号码,可设置格式化参数,使用promise方式作为异步方法。 -- 参数 - - - - - - - - - - - - - - - - - - - -

参数名

-

类型

-

必填

-

说明

-

phoneNumber

-

string

-

-

电话号码。

-

options

-

NumberFormatOptions

-

-

格式化参数,参考NumberFormatOptions

-
- -- 返回值 - - - - - - - - - - -

类型

-

说明

-

Promise<string>

-

以Promise形式异步返回格式化电话号码的结果。

-
+- 参数 + + | 参数 | 类型 | 必填 | 说明 | + | ----------- | ------------------- | ---- | ------------------------------------------------------------ | + | phoneNumber | string | 是 | 电话号码。 | + | options | NumberFormatOptions | 是 | 格式化参数,参考[NumberFormatOptions](#NumberFormatOptions)。 | + +- 返回值 + + | 类型 | 说明 | + | --------------------- | ------------------------------------------- | + | Promise<string> | 以Promise形式异步返回格式化电话号码的结果。 | - 示例 @@ -729,7 +363,7 @@ formatPhoneNumber\(phoneNumber: string, options?: NumberFormatOptions\): Promise }); ``` -## call.formatPhoneNumberToE1647+ +## call.formatPhoneNumberToE1647+ formatPhoneNumberToE164\(phoneNumber: string, countryCode: string, callback: AsyncCallback\): void @@ -739,48 +373,13 @@ formatPhoneNumberToE164\(phoneNumber: string, countryCode: string, callback: Asy 支持所有国家码。 -- 参数 - - - - - - - - - - - - - - - - - - - - - - - - -

参数名

-

类型

-

必填

-

说明

-

phoneNumber

-

string

-

-

电话号码。

-

countryCode

-

string

-

-

国家码,支持所有国家码,如:中国(CN)。

-

callback

-

AsyncCallback<string>

-

-

回调函数,返回将电话号码格式化为E.164表示形式的结果。

-
+- 参数 + + | 参数 | 类型 | 必填 | 说明 | + | ----------- | --------------------------- | ---- | ----------------------------------------------------- | + | phoneNumber | string | 是 | 电话号码。 | + | countryCode | string | 是 | 国家码,支持所有国家码,如:中国(CN)。 | + | callback | AsyncCallback<string> | 是 | 回调函数,返回将电话号码格式化为E.164表示形式的结果。 | - 示例 @@ -793,7 +392,7 @@ formatPhoneNumberToE164\(phoneNumber: string, countryCode: string, callback: Asy ``` -## call.formatPhoneNumberToE1647+ +## call.formatPhoneNumberToE1647+ formatPhoneNumberToE164\(phoneNumber: string, countryCode: string\): Promise @@ -803,56 +402,18 @@ formatPhoneNumberToE164\(phoneNumber: string, countryCode: string\): Promise - - - - - - - - - - - - - - - - - -

参数名

-

类型

-

必填

-

说明

-

phoneNumber

-

string

-

-

电话号码。

-

countryCode

-

string

-

-

国家码,如:中国(CN)。

-
- -- 返回值 - - - - - - - - - - -

类型

-

说明

-

Promise<string>

-

以Promise形式异步返回将电话号码格式化为E.164表示形式的结果。

-
+- 参数 + + | 参数 | 类型 | 必填 | 说明 | + | ----------- | ------ | ---- | ---------------------------------------- | + | phoneNumber | string | 是 | 电话号码。 | + | countryCode | string | 是 | 国家码,支持所有国家码,如:中国(CN)。 | + +- 返回值 + + | 类型 | 说明 | + | --------------------- | ------------------------------------------------------------ | + | Promise<string> | 以Promise形式异步返回将电话号码格式化为E.164表示形式的结果。 | - 示例 @@ -867,130 +428,33 @@ formatPhoneNumberToE164\(phoneNumber: string, countryCode: string\): Promise +## DialOptions 拨打电话的可选参数。 +| 参数 | 类型 | 必填 | 说明 | +| -------- | -------- | -------- | -------- | +| extras | boolean | 否 |根据extras的值判断是否为视频通话,默认为语音通话。
- true:视频通话。
- fasle:语音通话。| - - - - - - - - - - - - - -

参数名

-

类型

-

必填

-

说明

-

extras

-

boolean

-

-

根据extras的值判断是否为视频通话,默认为语音通话。

-
  • true:视频通话。
  • fasle:语音通话。
-
- -## CallState +## CallState 通话状态码。 +| 变量 | 值 | 说明 | +| -------- | -------- | -------- | +| CALL_STATE_UNKNOWN | -1 | 无效状态,当获取呼叫状态失败时返回。 | +| CALL_STATE_IDLE | 0 | 表示没有正在进行的呼叫。 | +| CALL_STATE_RINGING | 1 | 表示来电正在振铃或等待。 | +| CALL_STATE_OFFHOOK | 2 | 表示至少有一个呼叫处于拨号、通话中或呼叫保持状态,并且没有新的来电振铃或等待。 | - - - - - - - - - - - - - - - - - - - - - - - - -

变量

-

-

说明

-

CALL_STATE_UNKNOWN

-

-1

-

无效状态,当获取呼叫状态失败时返回。

-

CALL_STATE_IDLE

-

0

-

表示没有正在进行的呼叫。

-

CALL_STATE_RINGING

-

1

-

表示来电正在振铃或等待。

-

CALL_STATE_OFFHOOK

-

2

-

表示至少有一个呼叫处于拨号、通话中或呼叫保持状态,并且没有新的来电振铃或等待。

-
- -## EmergencyNumberOptions7+ +## EmergencyNumberOptions7+ 判断是否是紧急电话号码的可选参数。 +| 参数 | 类型 | 必填 | 说明 | +| -------- | -------- | -------- | -------- | +| slotId | number | 否 |卡槽ID:
- 0:卡槽1。
- 1:卡槽2。| - - - - - - - - - - - - - -

参数名

-

类型

-

必填

-

说明

-

slotId

-

number

-

-

卡槽ID:

-
  • 0:卡槽1。
  • 1:卡槽2。
-
- -## NumberFormatOptions7+ +## NumberFormatOptions7+ 格式化号码的可选参数。 - - - - - - - - - - - - - - -

参数名

-

类型

-

必填

-

说明

-

countryCode

-

string

-

-

国家码,支持所有国家的国家码,如:中国(CN),默认为:CN。

-
\ No newline at end of file +| 参数 | 类型 | 必填 | 说明 | +| -------- | -------- | -------- | -------- | +| countryCode | string | 否 |国家码,支持所有国家的国家码,如:中国(CN)。默认为:CN。| diff --git a/zh-cn/application-dev/js-reference/apis/js-apis-fileio.md b/zh-cn/application-dev/js-reference/apis/js-apis-fileio.md index 67a01b0732b..ca0d2cae4de 100644 --- a/zh-cn/application-dev/js-reference/apis/js-apis-fileio.md +++ b/zh-cn/application-dev/js-reference/apis/js-apis-fileio.md @@ -57,7 +57,9 @@ >![](../../public_sys-resources/icon-note.gif) **说明:** ->从 API Version 6 开始支持。 +> +>- 从 API Version 6 开始支持。 +>- 标记7+的接口从API Version 7开始支持。 ## 导入模块 @@ -72,35 +74,8 @@ import fileio from '@ohos.fileio'; ## 使用说明 使用该功能模块对文件/目录进行操作前,需要先获取其绝对路径。 - - - - - - - - - - - - - - - - -

目录类型

-

说明

-

相关接口

-

内部存储的缓存目录

-

可读写,随时可能清除,不保证持久性。一般用作下载临时目录或缓存目录。

-

getCacheDir

-

内部存储目录

-

随应用卸载删除。

-

getFilesDir

-
- -“文件/目录绝对路径”=“应用目录路径”+“文件/目录名” - +“文件/目录绝对路径”=“应用目录路径”+“文件/目录名”。 +应用目录路径可通过[Context模块的接口getOrCreateLocalDir](js-apis-Context.md)获取。 通过上述接口获取到应用目录路径dir,文件名为“xxx.txt”,文件所在绝对路径为: ``` @@ -2129,4 +2104,3 @@ isSymbolicLink\(\): boolean let isSymbolicLink = dir.readSync().isSymbolicLink(); ``` - diff --git a/zh-cn/application-dev/js-reference/apis/js-apis-radio.md b/zh-cn/application-dev/js-reference/apis/js-apis-radio.md index c60062d5acc..2136539f9fe 100644 --- a/zh-cn/application-dev/js-reference/apis/js-apis-radio.md +++ b/zh-cn/application-dev/js-reference/apis/js-apis-radio.md @@ -1,39 +1,40 @@ -# 网络搜索 - -- [导入模块](#s56d19203690d4782bfc74069abb6bd71) -- [radio.getRadioTech](#section18401172810207) -- [radio.getRadioTech](#section686385662419) -- [radio.getNetworkState](#section2090641619263) -- [radio.getNetworkState](#section392520433402) -- [radio.getNetworkState](#section20661545182918) -- [radio.getNetworkSelectionMode](#section79561056114711) -- [radio.getNetworkSelectionMode](#section553074612507) -- [radio.getISOCountryCodeForNetwork7+](#section16183194320525) -- [radio.getISOCountryCodeForNetwork7+](#section56144132559) -- [radio.getSignalInformation](#section1153532721018) -- [radio.getSignalInformation](#section1859512161511) -- [radio.isRadioOn7+](#section5456161711228) -- [radio.isRadioOn7+](#section178817520243) -- [RadioTechnology](#section1072135204020) -- [SignalInformation](#section10701756164212) -- [NetworkType](#section519718112466) -- [NetworkState](#section1691213911470) -- [RegState](#section18174131911514) -- [NsaState](#section448018155317) -- [NetworkSelectionMode](#section14219361268) +# 网络搜索 + +- [导入模块](#导入模块) +- [radio.getRadioTech](#radio.getRadioTech-callback) +- [radio.getRadioTech](#radio.getRadioTech-promise) +- [radio.getNetworkState](#radio.getNetworkState-callback1) +- [radio.getNetworkState](#radio.getNetworkState-callback2) +- [radio.getNetworkState](#radio.getNetworkState-promise) +- [radio.getNetworkSelectionMode](#radio.getNetworkSelectionMode-callback) +- [radio.getNetworkSelectionMode](#radio.getNetworkSelectionMode-promise) +- [radio.getISOCountryCodeForNetwork7+](#radio.getISOCountryCodeForNetwork-callback) +- [radio.getISOCountryCodeForNetwork7+](#radio.getISOCountryCodeForNetwork-promise) +- [radio.getSignalInformation](#radio.getSignalInformation-callback) +- [radio.getSignalInformation](#radio.getSignalInformation-promise) +- [radio.isRadioOn7+](#radio.isRadioOn-callback) +- [radio.isRadioOn7+](#radio.isRadioOn-promise) +- [RadioTechnology](#RadioTechnology) +- [SignalInformation](#SignalInformation) +- [NetworkType](#NetworkType) +- [NetworkState](#NetworkState) +- [RegState](#RegState) +- [NsaState](#NsaState) +- [NetworkSelectionMode](#NetworkSelectionMode) >**说明:** > ->标记7+的表示从API Version 7开始支持,未标记的表示从API Version 6开始支持。 +>- 从 API Version 6 开始支持。 +>- 标记7+的接口从API Version 7开始支持。 -## 导入模块 +## 导入模块 ``` import radio from '@ohos.telephony.radio' ``` -## radio.getRadioTech +## radio.getRadioTech getRadioTech\(slotId: number, callback: AsyncCallback<\{psRadioTech: RadioTechnology, csRadioTech: RadioTechnology\}\>\): void @@ -41,41 +42,12 @@ getRadioTech\(slotId: number, callback: AsyncCallback<\{psRadioTech: RadioTechno 需要ohos.permission.GET\_NETWORK\_INFO权限。 -- 参数 - - - - - - - - - - - - - - - - - - - -

参数名

-

类型

-

必填

-

说明

-

slotId

-

number

-

-

卡槽ID。

-

0:卡槽1

-

1:卡槽2

-

callback

-

AsyncCallback<{psRadioTech: RadioTechnology, csRadioTech: RadioTechnology}>

-

-

回调函数。

-
+- 参数 + + | 参数名 | 类型 | 必填 | 说明 | + | -------- | ------------------------------------------------------------ | ---- | -------------------------------------- | + | slotId | number | 是 | 卡槽ID。
- 0:卡槽1
- 1:卡槽2 | + | callback | AsyncCallback\<{psRadioTech: [RadioTechnology](#RadioTechnology), csRadioTech:[RadioTechnology](#RadioTechnology)}\> | 是 | 回调函数。 | - 示例 @@ -87,7 +59,7 @@ getRadioTech\(slotId: number, callback: AsyncCallback<\{psRadioTech: RadioTechno ``` -## radio.getRadioTech +## radio.getRadioTech getRadioTech\(slotId: number\): Promise<\{psRadioTech: RadioTechnology, csRadioTech: RadioTechnology\}\> @@ -95,49 +67,17 @@ getRadioTech\(slotId: number\): Promise<\{psRadioTech: RadioTechnology, csRadioT 需要ohos.permission.GET\_NETWORK\_INFO权限。 -- 参数 - - - - - - - - - - - - - - -

参数名

-

类型

-

必填

-

说明

-

slotId

-

number

-

-

卡槽ID。

-

0:卡槽1

-

1:卡槽2

-
- -- 返回值 - - - - - - - - - - -

类型

-

说明

-

Promise<{psRadioTech: RadioTechnology, csRadioTech: RadioTechnology}>

-

以Promise形式返回获取当前接入的CS域和PS域技术

-
+- 参数 + + | 参数名 | 类型 | 必填 | 说明 | + | ------ | ------ | ---- | -------------------------------------- | + | slotId | number | 是 | 卡槽ID。
- 0:卡槽1
- 1:卡槽2 | + +- 返回值 + + | 类型 | 说明 | + | ------------------------------------------------------------ | ----------------------------------------------- | + | Promise<{psRadioTech: [RadioTechnology](#RadioTechnology), csRadioTech: [RadioTechnology](#RadioTechnology)}> | 以Promise形式返回获取当前接入的CS域和PS域技术。 | - 示例 @@ -152,7 +92,7 @@ getRadioTech\(slotId: number\): Promise<\{psRadioTech: RadioTechnology, csRadioT ``` -## radio.getNetworkState +## radio.getNetworkState getNetworkState\(callback: AsyncCallback\): void @@ -160,30 +100,11 @@ getNetworkState\(callback: AsyncCallback\): void 需要ohos.permission.GET\_NETWORK\_INFO权限。 -- 参数 - - - - - - - - - - - - - - -

参数名

-

类型

-

必填

-

说明

-

callback

-

AsyncCallback<NetworkState>

-

-

回调函数。

-
+- 参数 + + | 参数名 | 类型 | 必填 | 说明 | + | -------- | ---------------------------------------------- | ---- | ---------- | + | callback | AsyncCallback\<[NetworkState](#NetworkState)\> | 是 | 回调函数。 | - 示例 @@ -194,7 +115,7 @@ getNetworkState\(callback: AsyncCallback\): void ``` -## radio.getNetworkState +## radio.getNetworkState getNetworkState\(slotId: number, callback: AsyncCallback\): void @@ -202,41 +123,12 @@ getNetworkState\(slotId: number, callback: AsyncCallback\): void 需要ohos.permission.GET\_NETWORK\_INFO权限。 -- 参数 - - - - - - - - - - - - - - - - - - - -

参数名

-

类型

-

必填

-

说明

-

slotId

-

number

-

-

卡槽ID。

-

0:卡槽1

-

1:卡槽2

-

callback

-

AsyncCallback<NetworkState>

-

-

回调函数。

-
+- 参数 + + | 参数名 | 类型 | 必填 | 说明 | + | -------- | ---------------------------------------------- | ---- | -------------------------------------- | + | slotId | number | 是 | 卡槽ID。
- 0:卡槽1
- 1:卡槽2 | + | callback | AsyncCallback\<[NetworkState](#NetworkState)\> | 是 | 回调函数。 | - 示例 @@ -248,7 +140,7 @@ getNetworkState\(slotId: number, callback: AsyncCallback\): void ``` -## radio.getNetworkState +## radio.getNetworkState getNetworkState\(slotId?: number\): Promise @@ -256,49 +148,17 @@ getNetworkState\(slotId?: number\): Promise 需要ohos.permission.GET\_NETWORK\_INFO权限。 -- 参数 - - - - - - - - - - - - - - -

参数名

-

类型

-

必填

-

说明

-

slotId

-

number

-

-

卡槽ID。

-

0:卡槽1

-

1:卡槽2

-
- -- 返回值 - - - - - - - - - - -

类型

-

说明

-

Promise<NetworkState>

-

以Promise形式返回网络状态。

-
+- 参数 + + | 参数名 | 类型 | 必填 | 说明 | + | ------ | ------ | ---- | -------------------------------------- | + | slotId | number | 否 | 卡槽ID。
- 0:卡槽1
- 1:卡槽2 | + +- 返回值 + + | 类型 | 说明 | + | ---------------------------------------- | --------------------------- | + | Promise\<[NetworkState](#NetworkState)\> | 以Promise形式返回网络状态。 | - 示例 @@ -313,47 +173,18 @@ getNetworkState\(slotId?: number\): Promise ``` -## radio.getNetworkSelectionMode +## radio.getNetworkSelectionMode getNetworkSelectionMode\(slotId: number, callback: AsyncCallback\): void 获取当前选网模式,使用callback方式作为异步方法。 -- 参数 - - - - - - - - - - - - - - - - - - - -

参数名

-

类型

-

必填

-

说明

-

slotId

-

number

-

-

卡槽ID。

-

0:卡槽1

-

1:卡槽2

-

callback

-

AsyncCallback<NetworkSelectionMode>

-

-

回调函数。

-
+- 参数 + + | 参数名 | 类型 | 必填 | 说明 | + | -------- | ------------------------------------------------------------ | ---- | -------------------------------------- | + | slotId | number | 是 | 卡槽ID。
- 0:卡槽1
- 1:卡槽2 | + | callback | AsyncCallback\<[NetworkSelectionMode](#NetworkSelectionMode)\> | 是 | 回调函数。 | - 示例 @@ -365,55 +196,23 @@ getNetworkSelectionMode\(slotId: number, callback: AsyncCallback +## radio.getNetworkSelectionMode getNetworkSelectionMode\(slotId: number\): Promise 获取当前选网模式,使用Promise方式作为异步方法。 -- 参数 - - - - - - - - - - - - - - -

参数名

-

类型

-

必填

-

说明

-

slotId

-

number

-

-

卡槽ID。

-

0:卡槽1

-

1:卡槽2

-
- -- 返回值 - - - - - - - - - - -

类型

-

说明

-

Promise<NetworkSelectionMode>

-

以Promise形式返回当前选网模式。

-
+- 参数 + + | 参数名 | 类型 | 必填 | 说明 | + | ------ | ------ | ---- | -------------------------------------- | + | slotId | number | 是 | 卡槽ID。
- 0:卡槽1
- 1:卡槽2 | + +- 返回值 + + | 类型 | 说明 | + | -------------------------------------------------------- | ------------------------------- | + | Promise\<[NetworkSelectionMode](#NetworkSelectionMode)\> | 以Promise形式返回当前选网模式。 | - 示例 @@ -428,47 +227,18 @@ getNetworkSelectionMode\(slotId: number\): Promise ``` -## radio.getISOCountryCodeForNetwork7+ +## radio.getISOCountryCodeForNetwork7+ getISOCountryCodeForNetwork\(slotId: number, callback: AsyncCallback\): void 获取注册网络所在国家的ISO国家码,使用callback方式作为异步方法。 -- 参数 - - - - - - - - - - - - - - - - - - - -

参数名

-

类型

-

必填

-

说明

-

slotId

-

number

-

-

卡槽ID。

-

0:卡槽1

-

1:卡槽2

-

callback

-

AsyncCallback<string>

-

-

回调函数。返回国家码,例如:CN(中国)。

-
+- 参数 + + | 参数名 | 类型 | 必填 | 说明 | + | -------- | ----------------------- | ---- | ---------------------------------------- | + | slotId | number | 是 | 卡槽ID。
- 0:卡槽1
- 1:卡槽2 | + | callback | AsyncCallback\ | 是 | 回调函数。返回国家码,例如:CN(中国)。 | - 示例 @@ -480,55 +250,23 @@ getISOCountryCodeForNetwork\(slotId: number, callback: AsyncCallback\): ``` -## radio.getISOCountryCodeForNetwork7+ +## radio.getISOCountryCodeForNetwork7+ getISOCountryCodeForNetwork\(slotId: number\): Promise 获取注册网络所在国家的ISO国家码,使用Promise方式作为异步方法。 -- 参数 - - - - - - - - - - - - - - -

参数名

-

类型

-

必填

-

说明

-

slotId

-

number

-

-

卡槽ID。

-

0:卡槽1

-

1:卡槽2

-
- -- 返回值 - - - - - - - - - - -

类型

-

说明

-

Promise<string>

-

以Promise形式返回注册网络所在国家的ISO国家码,例如CN(中国)。

-
+- 参数 + + | 参数名 | 类型 | 必填 | 说明 | + | ------ | ------ | ---- | -------------------------------------- | + | slotId | number | 是 | 卡槽ID。
- 0:卡槽1
- 1:卡槽2 | + +- 返回值 + + | 类型 | 说明 | + | ----------------- | ------------------------------------------------------------ | + | Promise\ | 以Promise形式返回注册网络所在国家的ISO国家码,例如CN(中国)。 | - 示例 @@ -543,47 +281,18 @@ getISOCountryCodeForNetwork\(slotId: number\): Promise ``` -## radio.getSignalInformation +## radio.getSignalInformation getSignalInformation\(slotId: number, callback: AsyncCallback\>\): void 获取指定SIM卡槽对应的注册网络信号强度信息列表,使用callback方式作为异步方法。 -- 参数 - - - - - - - - - - - - - - - - - - - -

参数名

-

类型

-

必填

-

说明

-

slotId

-

number

-

-

卡槽ID。

-

0:卡槽1

-

1:卡槽2

-

callback

-

AsyncCallback<Array<SignalInformation>>

-

-

回调函数,返回SignalInformation对象的数组。

-
+- 参数 + + | 参数名 | 类型 | 必填 | 说明 | + | -------- | ------------------------------------------------------------ | ---- | ------------------------------------------------------------ | + | slotId | number | 是 | 卡槽ID。
- 0:卡槽1
- 1:卡槽2 | + | callback | AsyncCallback\\> | 是 | 回调函数,返回[SignalInformation](#SignalInformation)对象的数组。 | - 示例 @@ -595,55 +304,23 @@ getSignalInformation\(slotId: number, callback: AsyncCallback +## radio.getSignalInformation getSignalInformation\(slotId: number\): Promise\> 获取指定SIM卡槽对应的注册网络信号强度信息列表,使用Promise方式作为异步方法。 -- 参数 - - - - - - - - - - - - - - -

参数名

-

类型

-

必填

-

说明

-

slotId

-

number

-

-

卡槽ID。

-

0:卡槽1

-

1:卡槽2

-
- -- 返回值 - - - - - - - - - - -

类型

-

说明

-

Promise<Array<SignalInformation>>

-

以Promise形式返回网络信号强度SignalInformation对象的数组。

-
+- 参数 + + | 参数名 | 类型 | 必填 | 说明 | + | ------ | ------ | ---- | -------------------------------------- | + | slotId | number | 是 | 卡槽ID。
- 0:卡槽1
- 1:卡槽2 | + +- 返回值 + + | 类型 | 说明 | + | ----------------------------------------------------------- | ------------------------------------------------------------ | + | Promise\\> | 以Promise形式返回网络信号强度[SignalInformation](#SignalInformation)对象的数组。 | - 示例 @@ -658,7 +335,7 @@ getSignalInformation\(slotId: number\): Promise\> ``` -## radio.isRadioOn7+ +## radio.isRadioOn7+ isRadioOn\(callback: AsyncCallback\): void @@ -666,32 +343,11 @@ isRadioOn\(callback: AsyncCallback\): void 需要ohos.permission.GET\_NETWORK\_INFO权限。 -- 参数 - - - - - - - - - - - - - - -

参数名

-

类型

-

必填

-

说明

-

callback

-

AsyncCallback<boolean>

-

-

回调函数。

-

true:Radio打开

-

false:Radio关闭

-
+- 参数 + + | 参数名 | 类型 | 必填 | 说明 | + | -------- | ------------------------ | ---- | ------------------------------------------------------- | + | callback | AsyncCallback\ | 是 | 回调函数。
- true:Radio打开
- false:Radio关闭 | - 示例 @@ -702,7 +358,7 @@ isRadioOn\(callback: AsyncCallback\): void ``` -## radio.isRadioOn7+ +## radio.isRadioOn7+ isRadioOn\(\): Promise @@ -710,24 +366,11 @@ isRadioOn\(\): Promise 需要ohos.permission.GET\_NETWORK\_INFO权限。 -- 返回值 - - - - - - - - - - -

类型

-

说明

-

Promise<boolean>

-

以Promise形式返回判断Radio是否打开的结果。

-

true:Radio打开

-

false:Radio关闭

-
+- 返回值 + + | 类型 | 说明 | + | ------------------ | ------------------------------------------------------------ | + | Promise\ | 以Promise形式返回判断Radio是否打开的结果。
- true:Radio打开
- false:Radio关闭 | - 示例 @@ -741,419 +384,99 @@ isRadioOn\(\): Promise ``` -## RadioTechnology +## RadioTechnology 无线接入技术。 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

变量

-

-

说明

-

RADIO_TECHNOLOGY_UNKNOWN

-

0

-

未知无线接入技术(RAT)。

-

RADIO_TECHNOLOGY_GSM

-

1

-

无线接入技术GSM(Global System For Mobile Communication)。

-

RADIO_TECHNOLOGY_1XRTT

-

2

-

无线接入技术1XRTT(Single-Carrier Radio Transmission Technology)。

-

RADIO_TECHNOLOGY_WCDMA

-

3

-

无线接入技术WCDMA(Wideband Code Division Multiple Access)。

-

RADIO_TECHNOLOGY_HSPA

-

4

-

无线接入技术HSPA(High Speed Packet Access)。

-

RADIO_TECHNOLOGY_HSPAP

-

5

-

无线接入技术HSPAP(High Speed packet access (HSPA+) )。

-

RADIO_TECHNOLOGY_TD_SCDMA

-

6

-

无线接入技术TDSCDMA(TimeDivision-Synchronous Code Division Multiple Access)。

-

RADIO_TECHNOLOGY_EVDO

-

7

-

无线接入技术EVDO(Evolution、Data Only)。

-

RADIO_TECHNOLOGY_EHRPD

-

8

-

无线接入技术EHRPD(Evolved High Rate Package Data)。

-

RADIO_TECHNOLOGY_LTE

-

9

-

无线接入技术LTE(Long Term Evolution)。

-

RADIO_TECHNOLOGY_LTE_CA

-

10

-

无线接入技术LTE_CA(Long Term Evolution_Carrier Aggregation)。

-

RADIO_TECHNOLOGY_IWLAN

-

11

-

无线接入技术IWLAN(Industrial Wireless LAN)。

-

RADIO_TECHNOLOGY_NR

-

12

-

无线接入技术NR(New Radio)。

-
- -## SignalInformation +| 变量 | 值 | 说明 | +| ------------------------- | ---- | ------------------------------------------------------------ | +| RADIO_TECHNOLOGY_UNKNOWN | 0 | 未知无线接入技术(RAT)。 | +| RADIO_TECHNOLOGY_GSM | 1 | 无线接入技术GSM(Global System For Mobile Communication)。 | +| RADIO_TECHNOLOGY_1XRTT | 2 | 无线接入技术1XRTT(Single-Carrier Radio Transmission Technology)。 | +| RADIO_TECHNOLOGY_WCDMA | 3 | 无线接入技术WCDMA(Wideband Code Division Multiple Access)。 | +| RADIO_TECHNOLOGY_HSPA | 4 | 无线接入技术HSPA(High Speed Packet Access)。 | +| RADIO_TECHNOLOGY_HSPAP | 5 | 无线接入技术HSPAP(High Speed packet access (HSPA+) )。 | +| RADIO_TECHNOLOGY_TD_SCDMA | 6 | 无线接入技术TDSCDMA(TimeDivision-Synchronous Code Division Multiple Access)。 | +| RADIO_TECHNOLOGY_EVDO | 7 | 无线接入技术EVDO(Evolution、Data Only)。 | +| RADIO_TECHNOLOGY_EHRPD | 8 | 无线接入技术EHRPD(Evolved High Rate Package Data)。 | +| RADIO_TECHNOLOGY_LTE | 9 | 无线接入技术LTE(Long Term Evolution)。 | +| RADIO_TECHNOLOGY_LTE_CA | 10 | 无线接入技术LTE_CA(Long Term Evolution_Carrier Aggregation)。 | +| RADIO_TECHNOLOGY_IWLAN | 11 | 无线接入技术IWLAN(Industrial Wireless LAN)。 | +| RADIO_TECHNOLOGY_NR | 12 | 无线接入技术NR(New Radio)。 | + + +## SignalInformation 网络信号强度信息对象。 - - - - - - - - - - - - - - - -

属性名

-

类型

-

说明

-

signalType

-

NetworkType

-

网络信号强度类型。

-

signalLevel

-

number

-

网络信号强度等级。

-
- -## NetworkType +| 属性名 | 类型 | 说明 | +| ----------- | --------------------------- | ------------------ | +| signalType | [NetworkType](#NetworkType) | 网络信号强度类型。 | +| signalLevel | number | 网络信号强度等级。 | + + +## NetworkType 网络类型。 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

变量

-

-

说明

-

NETWORK_TYPE_UNKNOWN

-

0

-

未知网络类型。

-

NETWORK_TYPE_GSM

-

1

-

网络类型为GSM(Global System For Mobile Communication)。

-

NETWORK_TYPE_CDMA

-

2

-

网络类型为CDMA(Code Division Multiple Access)。

-

NETWORK_TYPE_WCDMA

-

3

-

网络类型为WCDMA(Wideband Code Division Multiple Access)。

-

NETWORK_TYPE_TDSCDMA

-

4

-

网络类型为TDSCDMA(TimeDivision-Synchronous Code Division Multiple Access)。

-

NETWORK_TYPE_LTE

-

5

-

网络类型为LTE(Long Term Evolution)。

-

NETWORK_TYPE_NR

-

6

-

网络类型为5G NR(New Radio)。

-
- - -## NetworkState +| 变量 | 值 | 说明 | +| -------------------- | ---- | ------------------------------------------------------------ | +| NETWORK_TYPE_UNKNOWN | 0 | 未知网络类型。 | +| NETWORK_TYPE_GSM | 1 | 网络类型为GSM(Global System For Mobile Communication)。 | +| NETWORK_TYPE_CDMA | 2 | 网络类型为CDMA(Code Division Multiple Access)。 | +| NETWORK_TYPE_WCDMA | 3 | 网络类型为WCDMA(Wideband Code Division Multiple Access)。 | +| NETWORK_TYPE_TDSCDMA | 4 | 网络类型为TDSCDMA(TimeDivision-Synchronous Code Division Multiple Access)。 | +| NETWORK_TYPE_LTE | 5 | 网络类型为LTE(Long Term Evolution)。 | +| NETWORK_TYPE_NR | 6 | 网络类型为5G NR(New Radio)。 | + +## NetworkState 网络注册状态。 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

变量

-

类型

-

说明

-

longOperatorName

-

string

-

注册网络的长运营商名称。

-

shortOperatorName

-

string

-

注册网络的短运营商名称。

-

plmnNumeric

-

string

-

注册网络的PLMN码。

-

isRoaming

-

boolean

-

是否处于漫游状态。

-

regState

-

RegState

-

设备的网络注册状态。

-

nsaState

-

NsaState

-

设备的NSA网络注册状态。

-

isCaActive

-

boolean

-

CA的状态。

-

isEmergency

-

boolean

-

此设备是否只允许拨打紧急呼叫。

-
- -## RegState +| 变量 | 类型 | 说明 | +| ----------------- | --------------------- | ------------------------------ | +| longOperatorName | string | 注册网络的长运营商名称。 | +| shortOperatorName | string | 注册网络的短运营商名称。 | +| plmnNumeric | string | 注册网络的PLMN码。 | +| isRoaming | boolean | 是否处于漫游状态。 | +| regState | [RegState](#RegState) | 设备的网络注册状态。 | +| nsaState | [NsaState](#NsaState) | 设备的NSA网络注册状态。 | +| isCaActive | boolean | CA的状态。 | +| isEmergency | boolean | 此设备是否只允许拨打紧急呼叫。 | + + +## RegState 网络注册状态。 - - - - - - - - - - - - - - - - - - - - - - - -

变量

-

-

说明

-

REG_STATE_NO_SERVICE

-

0

-

设备不能使用任何服务。

-

REG_STATE_IN_SERVICE

-

1

-

设备可以正常使用业务。

-

REG_STATE_EMERGENCY_CALL_ONLY

-

2

-

设备只能使用紧急呼叫业务。

-

REG_STATE_POWER_OFF

-

3

-

蜂窝无线电已关闭。

-
- -## NsaState +| 变量 | 值 | 说明 | +| ----------------------------- | ---- | -------------------------- | +| REG_STATE_NO_SERVICE | 0 | 设备不能使用任何服务。 | +| REG_STATE_IN_SERVICE | 1 | 设备可以正常使用业务。 | +| REG_STATE_EMERGENCY_CALL_ONLY | 2 | 设备只能使用紧急呼叫业务。 | +| REG_STATE_POWER_OFF | 3 | 蜂窝无线电已关闭。 | + + +## NsaState 非独立组网状态。 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

变量

-

-

说明

-

NSA_STATE_NOT_SUPPORT

-

1

-

设备在不支持NSA的LTE小区下处于空闲状态或连接状态。

-

NSA_STATE_NO_DETECT

-

2

-

在支持NSA但不支持NR覆盖检测的LTE小区下,设备处于空闲状态。

-

NSA_STATE_CONNECTED_DETECT

-

3

-

设备在LTE小区下连接到LTE网络支持NSA和NR覆盖检测。

-

NSA_STATE_IDLE_DETECT

-

4

-

支持NSA和NR覆盖检测的LTE小区下设备处于空闲状态。

-

NSA_STATE_DUAL_CONNECTED

-

5

-

设备在支持NSA的LTE小区下连接到LTE + NR网络。

-

NSA_STATE_SA_ATTACHED

-

6

-

设备在5GC附着时在NG-RAN小区下空闲或连接到NG-RAN小区。

-
- -## NetworkSelectionMode +| 变量 | 值 | 说明 | +| -------------------------- | ---- | ---------------------------------------------------------- | +| NSA_STATE_NOT_SUPPORT | 1 | 设备在不支持NSA的LTE小区下处于空闲状态或连接状态。 | +| NSA_STATE_NO_DETECT | 2 | 在支持NSA但不支持NR覆盖检测的LTE小区下,设备处于空闲状态。 | +| NSA_STATE_CONNECTED_DETECT | 3 | 设备在LTE小区下连接到LTE网络支持NSA和NR覆盖检测。 | +| NSA_STATE_IDLE_DETECT | 4 | 支持NSA和NR覆盖检测的LTE小区下设备处于空闲状态。 | +| NSA_STATE_DUAL_CONNECTED | 5 | 设备在支持NSA的LTE小区下连接到LTE + NR网络。 | +| NSA_STATE_SA_ATTACHED | 6 | 设备在5GC附着时在NG-RAN小区下空闲或连接到NG-RAN小区。 | + + +## NetworkSelectionMode 选网模式。 - - - - - - - - - - - - - - - - - - - - -

变量

-

-

说明

-

NETWORK_SELECTION_UNKNOWN

-

0

-

未知选网模式。

-

NETWORK_SELECTION_AUTOMATIC

-

1

-

自动选网模式。

-

NETWORK_SELECTION_MANUAL

-

2

-

手动选网模式。

-
\ No newline at end of file +| 变量 | 值 | 说明 | +| --------------------------- | ---- | -------------- | +| NETWORK_SELECTION_UNKNOWN | 0 | 未知选网模式。 | +| NETWORK_SELECTION_AUTOMATIC | 1 | 自动选网模式。 | +| NETWORK_SELECTION_MANUAL | 2 | 手动选网模式。 | \ No newline at end of file diff --git a/zh-cn/application-dev/js-reference/apis/js-apis-sim.md b/zh-cn/application-dev/js-reference/apis/js-apis-sim.md index 1daf3a6529e..94b83aa123a 100755 --- a/zh-cn/application-dev/js-reference/apis/js-apis-sim.md +++ b/zh-cn/application-dev/js-reference/apis/js-apis-sim.md @@ -1,33 +1,34 @@ -# SIM卡管理 - -- [导入模块](#s56d19203690d4782bfc74069abb6bd71) -- [sim.getSimIccId](#section18529027065) -- [sim.getSimIccId](#section9200164911401) -- [sim.getDefaultVoiceSlotId7+](#section3313193864611) -- [sim.getDefaultVoiceSlotId7+](#section19013665018) -- [sim.getISOCountryCodeForSim](#section1429719645712) -- [sim.getISOCountryCodeForSim](#section1087375135713) -- [sim.getSimOperatorNumeric](#section1245831911019) -- [sim.getSimOperatorNumeric](#section450711512119) -- [sim.getSimSpn](#section18826326532) -- [sim.getSimSpn](#section1862714201148) -- [sim.getSimState](#section19837481195) -- [sim.getSimState](#section1763675061914) -- [sim.getSimGid1](#section18536193963119) -- [sim.getSimGid1](#section14446155983211) -- [SimState](#section17389192625218) +# SIM卡管理 + +- [导入模块](#导入模块) +- [sim.getSimIccId](#sim.getSimIccId-callback) +- [sim.getSimIccId](#sim.getSimIccId-promise) +- [sim.getDefaultVoiceSlotId7+](#sim.getDefaultVoiceSlotId-callback) +- [sim.getDefaultVoiceSlotId7+](#sim.getDefaultVoiceSlotId-promise) +- [sim.getISOCountryCodeForSim](#sim.getISOCountryCodeForSim-callback) +- [sim.getISOCountryCodeForSim](#sim.getISOCountryCodeForSim-promise) +- [sim.getSimOperatorNumeric](#sim.getSimOperatorNumeric-callback) +- [sim.getSimOperatorNumeric](#sim.getSimOperatorNumeric-promise) +- [sim.getSimSpn](#sim.getSimSpn-callback) +- [sim.getSimSpn](#sim.getSimSpn-promise) +- [sim.getSimState](#sim.getSimState-callback) +- [sim.getSimState](#sim.getSimState-promise) +- [sim.getSimGid1](#sim.getSimGid1-callback) +- [sim.getSimGid1](#sim.getSimGid1-promise) +- [SimState](#SimState) >**说明:** > ->标记7+的表示从API Version 7开始支持,未标记的表示从API Version 6开始支持。 +>- 从 API Version 6 开始支持。 +>- 标记7+的接口从API Version 7开始支持。 -## 导入模块 +## 导入模块 ``` import sim from '@ohos.telephony.sim'; ``` -## sim.getSimIccId +## sim.getSimIccId getSimIccId\(slotId: number, callback: AsyncCallback\): void @@ -37,39 +38,10 @@ getSimIccId\(slotId: number, callback: AsyncCallback\): void - 参数 - - - - - - - - - - - - - - - - - - -

参数名

-

类型

-

必填

-

说明

-

slotId

-

number

-

-

卡槽ID。

-

0:卡槽1

-

1:卡槽2

-

callback

-

AsyncCallback<string>

-

-

回调函数。

-
+ | 参数名 | 类型 | 必填 | 说明 | + | -------- | --------------------------- | ---- | -------------------------------------- | + | slotId | number | 是 | 卡槽ID。
- 0:卡槽1
- 1:卡槽2 | + | callback | AsyncCallback<string> | 是 | 回调函数。 | - 示例 @@ -81,7 +53,7 @@ getSimIccId\(slotId: number, callback: AsyncCallback\): void ``` -## sim.getSimIccId +## sim.getSimIccId getSimIccId\(slotId: number\): Promise @@ -89,49 +61,17 @@ getSimIccId\(slotId: number\): Promise 需要ohos.permission.GET\_TELEPHONY\_STATE权限,该权限为系统权限。 -- 参数 +- 参数 - - - - - - - - - - - - - -

参数名

-

类型

-

必填

-

说明

-

slotId

-

number

-

-

卡槽ID。

-

0:卡槽1

-

1:卡槽2

-
+ | 参数名 | 类型 | 必填 | 说明 | + | ------ | ------ | ---- | -------------------------------------- | + | slotId | number | 是 | 卡槽ID。
- 0:卡槽1
- 1:卡槽2 | - 返回值 - - - - - - - - - -

类型

-

说明

-

Promise<string>

-

以Promise形式返回指定卡槽的ICCID。

-
+ | 类型 | 说明 | + | --------------------- | ---------------------------------- | + | Promise<string> | 以Promise形式返回指定卡槽的ICCID。 | - 示例 @@ -144,36 +84,17 @@ getSimIccId\(slotId: number\): Promise }); ``` -## sim.getDefaultVoiceSlotId7+ +## sim.getDefaultVoiceSlotId7+ -getDefaultVoiceSlotId\(callback: AsyncCallback\): void7+ +getDefaultVoiceSlotId\(callback: AsyncCallback\): void 获取默认语音业务的卡槽ID,使用callback方式作为异步方法。 -- 参数 +- 参数 - - - - - - - - - - - - - -

参数名

-

类型

-

必填

-

说明

-

callback

-

AsyncCallback<number>

-

-

回调函数。

-
+ | 参数名 | 类型 | 必填 | 说明 | + | -------- | --------------------------- | ---- | ---------- | + | callback | AsyncCallback<number> | 是 | 回调函数。 | - 示例 @@ -184,28 +105,17 @@ getDefaultVoiceSlotId\(callback: AsyncCallback\): void7+ ``` -## sim.getDefaultVoiceSlotId7+ +## sim.getDefaultVoiceSlotId7+ -getDefaultVoiceSlotId\(\): Promise7+ +getDefaultVoiceSlotId\(\): Promise 获取默认语音业务的卡槽ID,使用Promise方式作为异步方法。 -- 返回值 - - - - - - - - - - -

类型

-

说明

-

Promise<number>

-

以Promise形式返回默认语音业务的卡槽ID。

-
+- 返回值 + + | 类型 | 说明 | + | ----------------- | --------------------------------------- | + | Promise\ | 以Promise形式返回默认语音业务的卡槽ID。 | - 示例 @@ -218,47 +128,18 @@ getDefaultVoiceSlotId\(\): Promise7+ }); ``` -## sim.getISOCountryCodeForSim +## sim.getISOCountryCodeForSim getISOCountryCodeForSim\(slotId: number, callback: AsyncCallback\): void 获取指定卡槽SIM卡的ISO国家码,使用callback方式作为异步方法。 -- 参数 +- 参数 - - - - - - - - - - - - - - - - - - -

参数名

-

类型

-

必填

-

说明

-

slotId

-

number

-

-

卡槽ID。

-

0:卡槽1

-

1:卡槽2

-

callback

-

AsyncCallback<string>

-

-

回调函数。返回国家码,例如:CN(中国)。

-
+ | 参数名 | 类型 | 必填 | 说明 | + | -------- | ----------------------- | ---- | ---------------------------------------- | + | slotId | number | 是 | 卡槽ID。
- 0:卡槽1
- 1:卡槽2 | + | callback | AsyncCallback\ | 是 | 回调函数。返回国家码,例如:CN(中国)。 | - 示例 @@ -269,55 +150,23 @@ getISOCountryCodeForSim\(slotId: number, callback: AsyncCallback\): voi ``` -## sim.getISOCountryCodeForSim +## sim.getISOCountryCodeForSim getISOCountryCodeForSim\(slotId: number\): Promise 获取指定卡槽SIM卡的ISO国家码,使用Promise方式作为异步方法。 -- 参数 +- 参数 - - - - - - - - - - - - - -

参数名

-

类型

-

必填

-

说明

-

slotId

-

number

-

-

卡槽ID。

-

0:卡槽1

-

1:卡槽2

-
- -- 返回值 - - - - - - - - - - -

类型

-

说明

-

Promise<string>

-

以Promise形式返回获取指定卡槽SIM卡的ISO国家码,例如:CN(中国)。

-
+ | 参数名 | 类型 | 必填 | 说明 | + | ------ | ------ | ---- | -------------------------------------- | + | slotId | number | 是 | 卡槽ID。
- 0:卡槽1
- 1:卡槽2 | + +- 返回值 + + | 类型 | 说明 | + | ----------------- | ------------------------------------------------------------ | + | Promise\ | 以Promise形式返回获取指定卡槽SIM卡的ISO国家码,例如:CN(中国)。 | - 示例 @@ -331,47 +180,18 @@ getISOCountryCodeForSim\(slotId: number\): Promise ``` -## sim.getSimOperatorNumeric +## sim.getSimOperatorNumeric getSimOperatorNumeric\(slotId: number, callback: AsyncCallback\): void 获取指定卡槽SIM卡的归属PLMN(Public Land Mobile Network)号,使用callback方式作为异步方法。 -- 参数 +- 参数 - - - - - - - - - - - - - - - - - - -

参数名

-

类型

-

必填

-

说明

-

slotId

-

number

-

-

卡槽ID。

-

0:卡槽1

-

1:卡槽2

-

callback

-

AsyncCallback<string>

-

-

回调函数。

-
+ | 参数名 | 类型 | 必填 | 说明 | + | -------- | ----------------------- | ---- | -------------------------------------- | + | slotId | number | 是 | 卡槽ID。
- 0:卡槽1
- 1:卡槽2 | + | callback | AsyncCallback\ | 是 | 回调函数。 | - 示例 @@ -382,55 +202,23 @@ getSimOperatorNumeric\(slotId: number, callback: AsyncCallback\): void ``` -## sim.getSimOperatorNumeric +## sim.getSimOperatorNumeric getSimOperatorNumeric\(slotId: number\): Promise 获取指定卡槽SIM卡的归属PLMN(Public Land Mobile Network)号,使用Promise方式作为异步方法。 -- 参数 +- 参数 + + | 参数名 | 类型 | 必填 | 说明 | + | ------ | ------ | ---- | -------------------------------------- | + | slotId | number | 是 | 卡槽ID。
- 0:卡槽1
- 1:卡槽2 | + +- 返回值 - - - - - - - - - - - - - -

参数名

-

类型

-

必填

-

说明

-

slotId

-

number

-

-

卡槽ID。

-

0:卡槽1

-

1:卡槽2

-
- -- 返回值 - - - - - - - - - - -

类型

-

说明

-

Promise<string>

-

以Promise形式返回获取指定卡槽SIM卡的归属PLMN号。

-
+ | 类型 | 说明 | + | ----------------- | ------------------------------------------------ | + | Promise\ | 以Promise形式返回获取指定卡槽SIM卡的归属PLMN号。 | - 示例 @@ -444,47 +232,18 @@ getSimOperatorNumeric\(slotId: number\): Promise ``` -## sim.getSimSpn +## sim.getSimSpn getSimSpn\(slotId: number, callback: AsyncCallback\): void 获取指定卡槽SIM卡的服务提供商名称(Service Provider Name,SPN),使用callback方式作为异步方法。 -- 参数 +- 参数 - - - - - - - - - - - - - - - - - - -

参数名

-

类型

-

必填

-

说明

-

slotId

-

number

-

-

卡槽ID。

-

0:卡槽1

-

1:卡槽2

-

callback

-

AsyncCallback<string>

-

-

回调函数。

-
+ | 参数名 | 类型 | 必填 | 说明 | + | -------- | ----------------------- | ---- | -------------------------------------- | + | slotId | number | 是 | 卡槽ID。
- 0:卡槽1
- 1:卡槽2 | + | callback | AsyncCallback\ | 是 | 回调函数。 | - 示例 @@ -495,7 +254,7 @@ getSimSpn\(slotId: number, callback: AsyncCallback\): void ``` -## sim.getSimSpn +## sim.getSimSpn getSimSpn\(slotId: number\): Promise @@ -503,49 +262,15 @@ getSimSpn\(slotId: number\): Promise - 参数 - - - - - - - - - - - - - - -

参数名

-

类型

-

必填

-

说明

-

slotId

-

number

-

-

卡槽ID。

-

0:卡槽1

-

1:卡槽2

-
+ | 参数名 | 类型 | 必填 | 说明 | + | ------ | ------ | ---- | -------------------------------------- | + | slotId | number | 是 | 卡槽ID。
- 0:卡槽1
- 1:卡槽2 | - 返回值 - - - - - - - - - - -

类型

-

说明

-

Promise<string>

-

以Promise形式返回获取指定卡槽SIM卡的SPN。

-
+ | 类型 | 说明 | + | ----------------- | ----------------------------------------- | + | Promise\ | 以Promise形式返回获取指定卡槽SIM卡的SPN。 | - 示例 @@ -559,47 +284,18 @@ getSimSpn\(slotId: number\): Promise ``` -## sim.getSimState +## sim.getSimState getSimState\(slotId: number, callback: AsyncCallback\): void 获取指定卡槽的SIM卡状态,使用callback方式作为异步方法。 -- 参数 +- 参数 - - - - - - - - - - - - - - - - - - -

参数名

-

类型

-

必填

-

说明

-

slotId

-

number

-

-

卡槽ID。

-

0:卡槽1

-

1:卡槽2

-

callback

-

AsyncCallback<SimState>

-

-

回调函数。参考SimState

-
+ | 参数名 | 类型 | 必填 | 说明 | + | -------- | -------------------------------------- | ---- | ----------------------------------------- | + | slotId | number | 是 | 卡槽ID。
- 0:卡槽1
- 1:卡槽2 | + | callback | AsyncCallback\<[SimState](#SimState)\> | 是 | 回调函数。参考[SimState](#SimState)。 | - 示例 @@ -610,56 +306,23 @@ getSimState\(slotId: number, callback: AsyncCallback\): void ``` -## sim.getSimState +## sim.getSimState getSimState\(slotId: number\): Promise 获取指定卡槽的SIM卡状态,使用Promise方式作为异步方法。 -- 参数 +- 参数 - - - - - - - - - - - - - -

参数名

-

类型

-

必填

-

说明

-

slotId

-

number

-

-

卡槽ID。

-

0:卡槽1

-

1:卡槽2

-
+ | 参数名 | 类型 | 必填 | 说明 | + | ------ | ------ | ---- | -------------------------------------- | + | slotId | number | 是 | 卡槽ID。
- 0:卡槽1
- 1:卡槽2 | - 返回值 - - - - - - - - - - -

类型

-

说明

-

Promise<SimState>

-

以Promise形式返回获取指定卡槽的SIM卡状态

-
+ | 类型 | 说明 | + | -------------------------------- | ------------------------------------------ | + | Promise\<[SimState](#SimState)\> | 以Promise形式返回获取指定卡槽的SIM卡状态。 | - 示例 @@ -672,7 +335,7 @@ getSimState\(slotId: number\): Promise }); ``` -## sim.getSimGid1 +## sim.getSimGid1 getSimGid1\(slotId: number, callback: AsyncCallback\): void @@ -680,41 +343,12 @@ getSimGid1\(slotId: number, callback: AsyncCallback\): void 需要ohos.permission.GET\_TELEPHONY\_STATE权限,该权限为系统权限。 -- 参数 +- 参数 - - - - - - - - - - - - - - - - - - -

参数名

-

类型

-

必填

-

说明

-

slotId

-

number

-

-

卡槽ID。

-

0:卡槽1

-

1:卡槽2

-

callback

-

AsyncCallback<string>

-

-

回调函数。

-
+ | 参数名 | 类型 | 必填 | 说明 | + | -------- | ----------------------- | ---- | -------------------------------------- | + | slotId | number | 是 | 卡槽ID。
- 0:卡槽1
- 1:卡槽2 | + | callback | AsyncCallback\ | 是 | 回调函数。 | - 示例 @@ -725,7 +359,7 @@ getSimGid1\(slotId: number, callback: AsyncCallback\): void ``` -## sim.getSimGid1 +## sim.getSimGid1 getSimGid1\(slotId: number\): Promise @@ -733,50 +367,17 @@ getSimGid1\(slotId: number\): Promise 需要ohos.permission.GET\_TELEPHONY\_STATE权限,该权限为系统权限。 -- 参数 +- 参数 - - - - - - - - - - - - - -

参数名

-

类型

-

必填

-

说明

-

slotId

-

number

-

-

卡槽ID。

-

0:卡槽1

-

1:卡槽2

-
+ | 参数名 | 类型 | 必填 | 说明 | + | ------ | ------ | ---- | -------------------------------------- | + | slotId | number | 是 | 卡槽ID。
- 0:卡槽1
- 1:卡槽2 | - 返回值 - - - - - - - - - - -

类型

-

说明

-

Promise<string>

-

以Promise形式返回获取指定卡槽SIM卡的GID1(Group Identifier Level 1)

-
+ | 类型 | 说明 | + | ----------------- | ------------------------------------------------------------ | + | Promise\ | 以Promise形式返回获取指定卡槽SIM卡的GID1(Group Identifier Level 1)。 | - 示例 @@ -790,47 +391,15 @@ getSimGid1\(slotId: number\): Promise ``` -## SimState +## SimState SIM卡状态。 - - - - - - - - - - - - - - - - - - - - - - - - - -

变量

-

说明

-

SIM_STATE_UNKNOWN

-

SIM卡状态未知,即无法获取准确的状态。

-

SIM_STATE_NOT_PRESENT

-

表示SIM卡处于not present状态,即卡槽中没有插入SIM卡。

-

SIM_STATE_LOCKED

-

表示SIM卡处于locked状态,即SIM卡被PIN、PUK或网络锁锁定。

-

SIM_STATE_NOT_READY

-

表示SIM卡处于not ready状态,即SIM卡在位但无法正常工作。

-

SIM_STATE_READY

-

表示SIM卡处于ready状态,即SIM卡在位且工作正常。

-

SIM_STATE_LOADED

-

表示SIM卡处于loaded状态,即SIM卡在位且所有卡文件加载完毕。

-
\ No newline at end of file +| 变量 | 说明 | +| --------------------- | ---------------------------------------------------------- | +| SIM_STATE_UNKNOWN | SIM卡状态未知,即无法获取准确的状态。 | +| SIM_STATE_NOT_PRESENT | 表示SIM卡处于not present状态,即卡槽中没有插入SIM卡。 | +| SIM_STATE_LOCKED | 表示SIM卡处于locked状态,即SIM卡被PIN、PUK或网络锁锁定。 | +| SIM_STATE_NOT_READY | 表示SIM卡处于not ready状态,即SIM卡在位但无法正常工作。 | +| SIM_STATE_READY | 表示SIM卡处于ready状态,即SIM卡在位且工作正常。 | +| SIM_STATE_LOADED | 表示SIM卡处于loaded状态,即SIM卡在位且所有卡文件加载完毕。 | \ No newline at end of file diff --git a/zh-cn/application-dev/js-reference/apis/js-apis-sms.md b/zh-cn/application-dev/js-reference/apis/js-apis-sms.md index 5f399841c01..f2f20864b71 100755 --- a/zh-cn/application-dev/js-reference/apis/js-apis-sms.md +++ b/zh-cn/application-dev/js-reference/apis/js-apis-sms.md @@ -1,33 +1,35 @@ -# 短信服务 - -- [导入模块](#section111401036143) -- [sms.createMessage](#section3831173019331) -- [sms.createMessage](#section9796242123511) -- [sms.sendMessage](#section128401423810) -- [sms.getDefaultSmsSlotId7+](#section46193383478) -- [sms.getDefaultSmsSlotId7+](#section19981626114817) -- [sms.setSmscAddr7+](#section155849574485) -- [sms.setSmscAddr7+](#section7801426144910) -- [sms.getSmscAddr7+](#section347174613494) -- [sms.getSmscAddr7+](#section1178428175016) -- [ShortMessage](#section345181318300) -- [ShortMessageClass](#section141712166453) -- [SendMessageOptions](#section12262183471518) -- [ISendShortMessageCallback](#section16646146115317) -- [IDeliveryShortMessageCallback](#section12183749531) -- [SendSmsResult](#section13290132311575) +# 短信服务 + +- [导入模块](#导入模块) +- [sms.createMessage](#sms.createMessage-callback) +- [sms.createMessage](#sms.createMessage-promise) +- [sms.sendMessage](#sms.sendMessage) +- [sms.getDefaultSmsSlotId7+](#sms.getDefaultSmsSlotId-callback) +- [sms.getDefaultSmsSlotId7+](#sms.getDefaultSmsSlotId-promise) +- [sms.setSmscAddr7+](#sms.setSmscAddr-callback) +- [sms.setSmscAddr7+](#sms.setSmscAddr-promise) +- [sms.getSmscAddr7+](#sms.getSmscAddr-callback) +- [sms.getSmscAddr7+](#sms.getSmscAddr-promise) +- [ShortMessage](#ShortMessage) +- [ShortMessageClass](#ShortMessageClass) +- [SendMessageOptions](#SendMessageOptions) +- [ISendShortMessageCallback](#ISendShortMessageCallback) +- [IDeliveryShortMessageCallback](#IDeliveryShortMessageCallback) +- [SendSmsResult](#SendSmsResult) >**说明:** > ->标记7+的表示从API Version 7开始支持,未标记的表示从API Version 6开始支持。 +>- 从 API Version 6 开始支持。 +> +>- 标记7+的接口从API Version 7开始支持。 -## 导入模块 +## 导入模块 ``` import sms from '@ohos.telephony.sms'; ``` -## sms.createMessage +## sms.createMessage createMessage\(pdu: Array, specification: string, callback: AsyncCallback\): void @@ -35,48 +37,11 @@ createMessage\(pdu: Array, specification: string, callback: AsyncCallba - 参数 - - - - - - - - - - - - - - - - - - - - - - - - -

参数名

-

类型

-

必填

-

说明

-

pdu

-

Array<number>

-

-

协议数据单元,从收到的信息中获取。

-

specification

-

string

-

-

短信协议类型。

-
  • 3gpp表示GSM/UMTS/LTE SMS
  • 3gpp2表示CDMA SMS
-

callback

-

AsyncCallback<ShortMessage>

-

-

回调函数。

-
+ | 参数名 | 类型 | 必填 | 说明 | + | ------------- | -------------------------------------------------- | ---- | ------------------------------------------------------------ | + | pdu | Array<number> | 是 | 协议数据单元,从收到的信息中获取。 | + | specification | string | 是 | 短信协议类型。
- 3gpp表示GSM/UMTS/LTE SMS
- 3gpp2表示CDMA SMS | + | callback | AsyncCallback<[ShortMessage](#ShortMessage)> | 是 | 回调函数。 | - 示例 @@ -89,63 +54,24 @@ createMessage\(pdu: Array, specification: string, callback: AsyncCallba ``` -## sms.createMessage +## sms.createMessage createMessage\(pdu: Array, specification: string\): Promise 根据协议数据单元(PDU)和指定的短信协议创建短信实例,使用Promise方式作为异步方法。 -- 参数 - - - - - - - - - - - - - - - - - - - -

参数名

-

类型

-

必填

-

说明

-

pdu

-

Array<number>

-

-

协议数据单元,从收到的信息中获取。

-

specification

-

string

-

-

短信协议类型。

-
  • 3gpp表示GSM/UMTS/LTE SMS
  • 3gpp2表示CDMA SMS
-
- -- 返回值 - - - - - - - - - - -

类型

-

说明

-

Promise<ShortMessage>

-

以Promise形式返回创建的短信实例。

-
+- 参数 + + | 参数名 | 类型 | 必填 | 说明 | + | ------------- | ------------------- | ---- | ------------------------------------------------------------ | + | pdu | Array<number> | 是 | 协议数据单元,从收到的信息中获取。 | + | specification | string | 是 | 短信协议类型。
- 3gpp表示GSM/UMTS/LTE SMS
- 3gpp2表示CDMA SMS | + +- 返回值 + + | 类型 | 说明 | + | -------------------------------------------- | --------------------------------- | + | Promise<[ShortMessage](#ShortMessage)> | 以Promise形式返回创建的短信实例。 | - 示例 @@ -160,90 +86,50 @@ createMessage\(pdu: Array, specification: string\): Promise - -sendMessage\(options: SendMessageOptions\): void +sendMessage(options: SendMessageOptions): void 发送短信。 -需要ohos.permission.SEND\_MESSAGES权限。 - -- 参数 - - - - - - - - - - - - - - -

参数名

-

类型

-

必填

-

说明

-

options

-

SendMessageOptions

-

-

发送短信的参数和回调,参考SendMessageOptions

-
+需要ohos.permission.SEND_MESSAGES权限。 -- 示例 +- 参数 - ``` - let sendCallback = function (err, data) { - console.log(`sendCallback: err->${JSON.stringify(err)}, data->${JSON.stringify(data)}`); - } - let deliveryCallback = function (err, data) { - console.log(`deliveryCallback: err->${JSON.stringify(err)}, data->${JSON.stringify(data)}`); - } - let slotId = 0; - let content = '短信内容'; - let destinationHost = '+861xxxxxxxxxx'; - let serviceCenter = '+861xxxxxxxxxx'; - let destinationPort = 1000; - let options = {slotId, content, destinationHost, serviceCenter, destinationPort, sendCallback, deliveryCallback}; - sms.sendMessage(options); - ``` + | 参数名 | 类型 | 必填 | 说明 | + | ------- | ----------------------------------------- | ---- | ------------------------------------------------------------ | + | options | [SendMessageOptions](#SendMessageOptions) | 是 | 发送短信的参数和回调,参考[SendMessageOptions](#SendMessageOptions)。 | +- 示例 -## sms.getDefaultSmsSlotId7+ + ``` + let sendCallback = function (err, data) { + console.log(`sendCallback: err->${JSON.stringify(err)}, data->${JSON.stringify(data)}`); + } + let deliveryCallback = function (err, data) { + console.log(`deliveryCallback: err->${JSON.stringify(err)}, data->${JSON.stringify(data)}`); + } + let slotId = 0; + let content = '短信内容'; + let destinationHost = '+861xxxxxxxxxx'; + let serviceCenter = '+861xxxxxxxxxx'; + let destinationPort = 1000; + let options = {slotId, content, destinationHost, serviceCenter, destinationPort, sendCallback, deliveryCallback}; + sms.sendMessage(options); + ``` + + +## sms.getDefaultSmsSlotId7+ getDefaultSmsSlotId\(callback: AsyncCallback\): void 获取发送短信的默认SIM卡槽ID,使用callback方式作为异步方法。 -- 参数 - - - - - - - - - - - - - - -

参数名

-

类型

-

必填

-

说明

-

callback

-

AsyncCallback<number>

-

-

回调函数。

-
  • 0:卡槽1
  • 1:卡槽2
-
+- 参数 + + | 参数名 | 类型 | 必填 | 说明 | + | -------- | --------------------------- | ---- | ---------------------------------------- | + | callback | AsyncCallback<number> | 是 | 回调函数。
- 0:卡槽1
- 1:卡槽2 | - 示例 @@ -254,29 +140,17 @@ getDefaultSmsSlotId\(callback: AsyncCallback\): void ``` -## sms.getDefaultSmsSlotId7+ +## sms.getDefaultSmsSlotId7+ getDefaultSmsSlotId\(\): Promise 获取发送短信的默认SIM卡槽ID,使用Promise方式作为异步方法。 -- 返回值 - - - - - - - - - - -

类型

-

说明

-

Promise<number>

-

以Promise形式返回发送短信的默认SIM卡:

-
  • 0:卡槽1
  • 1:卡槽2
-
+- 返回值 + + | 类型 | 说明 | + | --------------- | ------------------------------------------------------------ | + | Promise | 以Promise形式返回发送短信的默认SIM卡:
- 0:卡槽1
- 1:卡槽2 | - 示例 @@ -290,7 +164,7 @@ getDefaultSmsSlotId\(\): Promise ``` -## sms.setSmscAddr7+ +## sms.setSmscAddr7+ setSmscAddr\(slotId: number, smscAddr: string, callback: AsyncCallback\): void @@ -298,49 +172,13 @@ setSmscAddr\(slotId: number, smscAddr: string, callback: AsyncCallback\): 需要ohos.permission.SET\_TELEPHONY\_STATE权限,该权限为系统权限。 -- 参数 - - - - - - - - - - - - - - - - - - - - - - - - -

参数名

-

类型

-

必填

-

说明

-

slotId

-

number

-

-

SIM卡槽ID:

-
  • 0:卡槽1
  • 1:卡槽2
-

smscAddr

-

string

-

-

短信服务中心地址。

-

callback

-

AsyncCallback<void>

-

-

回调函数。

-
+- 参数 + + | 参数名 | 类型 | 必填 | 说明 | + | -------- | ------------------------- | ---- | ----------------------------------------- | + | slotId | number | 是 | SIM卡槽ID:
- 0:卡槽1
- 1:卡槽2 | + | smscAddr | string | 是 | 短信服务中心地址。 | + | callback | AsyncCallback<void> | 是 | 回调函数。 | - 示例 @@ -353,7 +191,7 @@ setSmscAddr\(slotId: number, smscAddr: string, callback: AsyncCallback\): ``` -## sms.setSmscAddr7+ +## sms.setSmscAddr7+ setSmscAddr\(slotId: number, smscAddr: string\): Promise @@ -361,57 +199,18 @@ setSmscAddr\(slotId: number, smscAddr: string\): Promise 需要ohos.permission.SET\_TELEPHONY\_STATE权限,该权限为系统权限。 -- 参数 - - - - - - - - - - - - - - - - - - - -

参数名

-

类型

-

必填

-

说明

-

slotId

-

number

-

-

SIM卡槽ID:

-
  • 0:卡槽1
  • 1:卡槽2
-

smscAddr

-

string

-

-

短信服务中心地址。

-
- -- 返回值 - - - - - - - - - - -

类型

-

说明

-

Promise<void>

-

以Promise形式异步返回设置结果。

-
+- 参数 + + | 参数名 | 类型 | 必填 | 说明 | + | -------- | ------ | ---- | ----------------------------------------- | + | slotId | number | 是 | SIM卡槽ID:
- 0:卡槽1
- 1:卡槽2 | + | smscAddr | string | 是 | 短信服务中心地址。 | + +- 返回值 + + | 类型 | 说明 | + | ------------------- | ------------------------------- | + | Promise<void> | 以Promise形式异步返回设置结果。 | - 示例 @@ -427,7 +226,7 @@ setSmscAddr\(slotId: number, smscAddr: string\): Promise ``` -## sms.getSmscAddr7+ +## sms.getSmscAddr7+ getSmscAddr\(slotId: number, callback: AsyncCallback\): void @@ -435,40 +234,12 @@ getSmscAddr\(slotId: number, callback: AsyncCallback\): void 需要ohos.permission.GET\_TELEPHONY\_STATE权限,该权限为系统权限。 -- 参数 - - - - - - - - - - - - - - - - - - - -

参数名

-

类型

-

必填

-

说明

-

slotId

-

number

-

-

SIM卡槽ID:

-
  • 0:卡槽1
  • 1:卡槽2
-

callback

-

AsyncCallback<string>

-

-

回调函数。

-
+- 参数 + + | 参数名 | 类型 | 必填 | 说明 | + | -------- | --------------------------- | ---- | ----------------------------------------- | + | slotId | number | 是 | SIM卡槽ID:
- 0:卡槽1
- 1:卡槽2 | + | callback | AsyncCallback<string> | 是 | 回调函数。 | - 示例 @@ -480,7 +251,7 @@ getSmscAddr\(slotId: number, callback: AsyncCallback\): void ``` -## sms.getSmscAddr7+ +## sms.getSmscAddr7+ getSmscAddr\(slotId: number\): Promise @@ -488,48 +259,17 @@ getSmscAddr\(slotId: number\): Promise 需要ohos.permission.GET\_TELEPHONY\_STATE权限,该权限为系统权限。 -- 参数 - - - - - - - - - - - - - - -

参数名

-

类型

-

必填

-

说明

-

slotId

-

number

-

-

SIM卡槽ID:

-
  • 0:卡槽1
  • 1:卡槽2
-
- -- 返回值 - - - - - - - - - - -

类型

-

说明

-

Promise<string>

-

以Promise形式返回获取短信服务中心地址的结果。

-
+- 参数 + + | 参数名 | 类型 | 必填 | 说明 | + | ------ | ------ | ---- | ----------------------------------------- | + | slotId | number | 是 | SIM卡槽ID:
- 0:卡槽1
- 1:卡槽2 | + +- 返回值 + + | 类型 | 说明 | + | --------------------- | --------------------------------------------- | + | Promise<string> | 以Promise形式返回获取短信服务中心地址的结果。 | - 示例 @@ -544,381 +284,87 @@ getSmscAddr\(slotId: number\): Promise ``` -## ShortMessage - -短信实例 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

变量

-

类型

-

说明

-

emailAddress

-

string

-

电子邮件地址。

-

emailMessageBody

-

string

-

电子邮件正文。

-

hasReplyPath

-

boolean

-

收到的短信是否包含“TP-Reply-Path”,默认为false。

-
  • “TP-Reply-Path”:移动电话根据发送SMS消息的短消息中心进行回复。
-

isEmailMessage

-

boolean

-

收到的短信是否为电子邮件。

-

isReplaceMessage

-

boolean

-

收到的短信是否为“替换短信”,默认为false。

-
  • “替换短信”有关详细信息,参见 “3GPP TS 23.040 9.2.3.9”。
-

isSmsStatusReportMessage

-

boolean

-

当前消息是否为“短信状态报告”,默认为false。

-
  • “短信状态报告”是一种特定格式的短信,被用来从Service Center到Mobile Station传送状态报告。
-

messageClass

-

ShortMessageClass

-

短信类型。

-

pdu

-

Array<number>

-

SMS消息中的协议数据单元 (PDU)。

-

protocolId

-

number

-

发送短信时使用的协议标识。

-

scAddress

-

string

-

短消息服务中心(SMSC)地址。

-

scTimestamp

-

number

-

SMSC时间戳。

-

status

-

number

-

SMS-STATUS-REPORT消息中的短信状态指示短信服务中心(SMSC)发送的短信状态。

-

userRawData

-

Array<number>

-

除数据头外的用户数据。

-

visibleMessageBody

-

string

-

短信正文。

-

visibleRawAddress

-

string

-

发送者地址。

-
- -## ShortMessageClass +## ShortMessage + +短信实例。 + +| 变量 | 类型 | 说明 | +| ------------------------ | --------------------------------------- | ------------------------------------------------------------ | +| emailAddress | string | 电子邮件地址。 | +| emailMessageBody | string | 电子邮件正文。 | +| hasReplyPath | boolean | 收到的短信是否包含“TP-Reply-Path”,默认为false。
“TP-Reply-Path”:移动电话根据发送SMS消息的短消息中心进行回复。 | +| isEmailMessage | boolean | 收到的短信是否为电子邮件。 | +| isReplaceMessage | boolean | 收到的短信是否为“替换短信”,默认为false。
“替换短信”有关详细信息,参见 “3GPP TS 23.040 9.2.3.9”。 | +| isSmsStatusReportMessage | boolean | 当前消息是否为“短信状态报告”,默认为false。
“短信状态报告”是一种特定格式的短信,被用来从Service Center到Mobile Station传送状态报告。 | +| messageClass | [ShortMessageClass](#ShortMessageClass) | 短信类型。 | +| pdu | Array<number> | SMS消息中的协议数据单元 (PDU)。 | +|protocolId|number|发送短信时使用的协议标识。| +|scAddress|string|短消息服务中心(SMSC)地址。| +|scTimestamp|number|SMSC时间戳。| +|status|number|SMS-STATUS-REPORT消息中的短信状态指示短信服务中心(SMSC)发送的短信状态。| +|userRawData|Array<number>|除数据头外的用户数据。| +|visibleMessageBody|string|短信正文。| +|visibleRawAddress|string|发送者地址。| + + +## ShortMessageClass 短信类型。 - - - - - - - - - - - - - - - - - - - - - - - - - - - -

变量

-

-

说明

-

UNKNOWN

-

0

-

未知类型。

-

INSTANT_MESSAGE

-

1

-

即时消息,收到后立即显示。

-

OPTIONAL_MESSAGE

-

2

-

存储在设备或SIM卡上的短信。

-

SIM_MESSAGE

-

3

-

包含SIM卡信息的短信,需要存储在SIM卡中。

-

FORWARD_MESSAGE

-

4

-

要转发到另一台设备的短信。

-
- -## SendMessageOptions +| 变量 | 值 | 说明 | +| ---------------- | ---- | ---------------------------------------- | +| UNKNOWN | 0 | 未知类型。 | +| INSTANT_MESSAGE | 1 | 即时消息,收到后立即显示。 | +| OPTIONAL_MESSAGE | 2 | 存储在设备或SIM卡上的短信。 | +| SIM_MESSAGE | 3 | 包含SIM卡信息的短信,需要存储在SIM卡中。 | +| FORWARD_MESSAGE | 4 | 要转发到另一台设备的短信。 | + + +## SendMessageOptions 发送短信的参数和回调。 根据SendMessageOptions中的可选参数content的值判断短信类型。 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

参数名

-

类型

-

必填

-

说明

-

slotId

-

number

-

-

用于发送短信的SIM卡槽ID:

-
  • 0:卡槽1
  • 1:卡槽2
-

destinationHost

-

string

-

-

短信的发送地址。

-

content

-

string | Array<number>

-

-

如果内容是字符串,则这是一条文本短信。

-

如果内容是字节数组,则这是一条数据短信。

-

serviceCenter

-

string

-

-

短信中心地址。默认使用SIM卡中的短信中心地址。

-

destinationPort

-

number

-

-

如果发送数据消息,destinationPort 是必需的。否则是可选的。

-

sendCallback

-

AsyncCallback

-

<ISendShortMessageCallback>

-

-

短信发送结果回调,返回短信发送的结果,参考ISendShortMessageCallback

-

deliveryCallback

-

AsyncCallback

-

<IDeliveryShortMessageCallback>

-

-

短信送达结果回调,返回短信递送报告,参考IDeliveryShortMessageCallback

-
- -## ISendShortMessageCallback +| 参数名 | 类型 | 必填 | 说明 | +| ---------------- | ------------------------------------------------------------ | ---- | ------------------------------------------------------------ | +| slotId | number | 是 | 用于发送短信的SIM卡槽ID:
- 0:卡槽1
- 1:卡槽2 | +| destinationHost | string | 是 | 短信的发送地址。 | +| content | string \| Array<number> | 是 | 如果内容是字符串,则这是一条文本短信。如果内容是字节数组,则这是一条数据短信。 | +| serviceCenter | string | 否 | 短信中心地址。默认使用SIM卡中的短信中心地址。 | +| destinationPort | number | 否 | 如果发送数据消息,destinationPort 是必需的。否则是可选的。 | +| sendCallback | AsyncCallback<[ISendShortMessageCallback](#ISendShortMessageCallback)> | 否 | 短信发送结果回调,返回短信发送的结果,参考[ISendShortMessageCallback](#ISendShortMessageCallback)。 | +| deliveryCallback | AsyncCallback<[IDeliveryShortMessageCallback](#IDeliveryShortMessageCallback)> | 否 | 短信送达结果回调,返回短信递送报告,参考[IDeliveryShortMessageCallback](#IDeliveryShortMessageCallback)。 | + + +## ISendShortMessageCallback 回调实例。返回短信发送结果、存储已发送短信的URI和是否为长短信的最后一部分。 - - - - - - - - - - - - - - - - - - - - - - - -

参数名

-

类型

-

必填

-

说明

-

isLastPart

-

boolean

-

-

指定这是否是长短信的最后一部分。true表示这是长短信的最后一部分,false表示不是。默认为false。

-

result

-

SendSmsResult

-

-

短信发送结果。

-

url

-

string

-

-

存储发送短信的URI。

-
- -## IDeliveryShortMessageCallback +| 参数名 | 类型 | 必填 | 说明 | +| ---------- | ------------------------------- | ---- | ------------------------------------------------------------ | +| isLastPart | boolean | 否 | 指定这是否是长短信的最后一部分。true表示这是长短信的最后一部分,false表示不是。默认为false。 | +| result | [SendSmsResult](#SendSmsResult) | 是 | 短信发送结果。 | +| url | string | 是 | 存储发送短信的URI。 | + + +## IDeliveryShortMessageCallback 回调实例。返回短信送达报告。 - - - - - - - - - - - - - -

参数名

-

类型

-

必填

-

说明

-

pdu

-

Array<number>

-

-

短信送达报告。

-
- -## SendSmsResult +| 参数名 | 类型 | 必填 | 说明 | +| ------ | ------------------- | ---- | -------------- | +| pdu | Array<number> | 是 | 短信送达报告。 | + + +## SendSmsResult 短信发送结果。 - - - - - - - - - - - - - - - - - - - - - - - -

参数名

-

-

说明

-

SEND_SMS_SUCCESS

-

0

-

发送短信成功。

-

SEND_SMS_FAILURE_UNKNOWN

-

1

-

发送短信失败,原因未知。

-

SEND_SMS_FAILURE_RADIO_OFF

-

2

-

发送短信失败,原因为调制解调器关机。

-

SEND_SMS_FAILURE_SERVICE_UNAVAILABLE

-

3

-

发送短信失败,原因为网络不可用、不支持发送或接收短信。

-
+| 参数名 | 值 | 说明 | +| ------------------------------------ | ---- | ------------------------------------------------------ | +| SEND_SMS_SUCCESS | 0 | 发送短信成功。 | +| SEND_SMS_FAILURE_UNKNOWN | 1 | 发送短信失败,原因未知。 | +| SEND_SMS_FAILURE_RADIO_OFF | 2 | 发送短信失败,原因为调制解调器关机。 | +| SEND_SMS_FAILURE_SERVICE_UNAVAILABLE | 3 | 发送短信失败,原因为网络不可用、不支持发送或接收短信。 | + diff --git a/zh-cn/application-dev/js-reference/component/Readme-CN.md b/zh-cn/application-dev/js-reference/component/Readme-CN.md index 303e5ae59ab..006e4f6126f 100644 --- a/zh-cn/application-dev/js-reference/component/Readme-CN.md +++ b/zh-cn/application-dev/js-reference/component/Readme-CN.md @@ -80,9 +80,9 @@ - [grid-row](js-components-grid-row.md) - [grid-col](js-components-grid-col.md) -- [svg组件](js-components-svg.md) +- [svg组件](js-svg.md) - [通用属性](js-components-svg-common-attributes.md) - - [svg](js-components-svg-0.md) + - [svg](js-components-svg.md) - [rect](js-components-svg-rect.md) - [circle](js-components-svg-circle.md) - [ellipse](js-components-svg-ellipse.md) diff --git a/zh-cn/application-dev/js-reference/component/js-components-svg-0.md b/zh-cn/application-dev/js-reference/component/js-components-svg-0.md deleted file mode 100644 index f80eadf13c5..00000000000 --- a/zh-cn/application-dev/js-reference/component/js-components-svg-0.md +++ /dev/null @@ -1,128 +0,0 @@ -# svg - -- [权限列表](#zh-cn_topic_0000001173164705_section11257113618419) -- [子组件](#zh-cn_topic_0000001173164705_section9288143101012) -- [属性](#zh-cn_topic_0000001173164705_section2907183951110) -- [示例](#zh-cn_topic_0000001173164705_section360556124815) - -基础容器,主要作为svg的根节点使用,也可以在svg中嵌套使用。 - ->![](../../public_sys-resources/icon-note.gif) **说明:** ->从API Version 7 开始支持。 ->约束条件:svg父组件或者svg组件需要定义宽高值,否则不进行绘制。 - -## 权限列表 - -无 - -## 子组件 - -支持svg、rect、circle、ellipse、path、line、polygon、polyline、text、animate、animateTransform。 - -## 属性 - -支持所列的Svg组件通用属性和以下表格的属性,设置的通用属性会传递给子组件。 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

名称

-

类型

-

默认值

-

必填

-

描述

-

id

-

string

-

-

-

-

组件的唯一标识。

-

width

-

<length>|<percentage>

-

-

-

-

设置组件的宽度

-

height

-

<length>|<percentage>

-

-

-

-

设置组件的高度

-

x

-

<length>|<percentage>

-

-

-

-

设置当前svg的x轴坐标,根svg节点无效

-

y

-

<length>|<percentage>

-
  

-

设置当前svg的y轴坐标,根svg节点无效

-

viewBox

-

string

-

-

-

-

设置当前svg的视口。支持的格式为<number number number number>,4个参数分别表示min-x, min-y, width and height,viewBox的宽高和svg的宽高不一致,会以中心对齐进行缩放。

-
- -## 示例 - -``` - -
- - - - - - - - - - - - -
-``` - -![](figures/zh-cn_image_0000001173164789.png) - diff --git a/zh-cn/application-dev/js-reference/component/js-components-svg.md b/zh-cn/application-dev/js-reference/component/js-components-svg.md index 301c0c79800..f80eadf13c5 100644 --- a/zh-cn/application-dev/js-reference/component/js-components-svg.md +++ b/zh-cn/application-dev/js-reference/component/js-components-svg.md @@ -1,33 +1,128 @@ -# svg组件 - -- **[通用属性](js-components-svg-common-attributes.md)** - -- **[svg](js-components-svg-0.md)** - -- **[rect](js-components-svg-rect.md)** - -- **[circle](js-components-svg-circle.md)** - -- **[ellipse](js-components-svg-ellipse.md)** - -- **[path](js-components-svg-path.md)** - -- **[line](js-components-svg-line.md)** - -- **[polyline](js-components-svg-polyline.md)** - -- **[polygon](js-components-svg-polygon.md)** - -- **[text](js-components-svg-text.md)** - -- **[tspan](js-components-svg-tspan.md)** - -- **[textPath](js-components-svg-textpath.md)** - -- **[animate](js-components-svg-animate.md)** - -- **[animateMotion](js-components-svg-animate-motion.md)** - -- **[animateTransform](js-components-svg-animate-transform.md)** - +# svg + +- [权限列表](#zh-cn_topic_0000001173164705_section11257113618419) +- [子组件](#zh-cn_topic_0000001173164705_section9288143101012) +- [属性](#zh-cn_topic_0000001173164705_section2907183951110) +- [示例](#zh-cn_topic_0000001173164705_section360556124815) + +基础容器,主要作为svg的根节点使用,也可以在svg中嵌套使用。 + +>![](../../public_sys-resources/icon-note.gif) **说明:** +>从API Version 7 开始支持。 +>约束条件:svg父组件或者svg组件需要定义宽高值,否则不进行绘制。 + +## 权限列表 + +无 + +## 子组件 + +支持svg、rect、circle、ellipse、path、line、polygon、polyline、text、animate、animateTransform。 + +## 属性 + +支持所列的Svg组件通用属性和以下表格的属性,设置的通用属性会传递给子组件。 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

名称

+

类型

+

默认值

+

必填

+

描述

+

id

+

string

+

-

+

+

组件的唯一标识。

+

width

+

<length>|<percentage>

+

-

+

+

设置组件的宽度

+

height

+

<length>|<percentage>

+

-

+

+

设置组件的高度

+

x

+

<length>|<percentage>

+

-

+

+

设置当前svg的x轴坐标,根svg节点无效

+

y

+

<length>|<percentage>

+
  

+

设置当前svg的y轴坐标,根svg节点无效

+

viewBox

+

string

+

-

+

+

设置当前svg的视口。支持的格式为<number number number number>,4个参数分别表示min-x, min-y, width and height,viewBox的宽高和svg的宽高不一致,会以中心对齐进行缩放。

+
+ +## 示例 + +``` + +
+ + + + + + + + + + + + +
+``` + +![](figures/zh-cn_image_0000001173164789.png) diff --git a/zh-cn/application-dev/js-reference/component/js-svg.md b/zh-cn/application-dev/js-reference/component/js-svg.md new file mode 100644 index 00000000000..c5803b40ab1 --- /dev/null +++ b/zh-cn/application-dev/js-reference/component/js-svg.md @@ -0,0 +1,33 @@ +# svg组件 + +- **[通用属性](js-components-svg-common-attributes.md)** + +- **[svg](js-components-svg.md)** + +- **[rect](js-components-svg-rect.md)** + +- **[circle](js-components-svg-circle.md)** + +- **[ellipse](js-components-svg-ellipse.md)** + +- **[path](js-components-svg-path.md)** + +- **[line](js-components-svg-line.md)** + +- **[polyline](js-components-svg-polyline.md)** + +- **[polygon](js-components-svg-polygon.md)** + +- **[text](js-components-svg-text.md)** + +- **[tspan](js-components-svg-tspan.md)** + +- **[textPath](js-components-svg-textpath.md)** + +- **[animate](js-components-svg-animate.md)** + +- **[animateMotion](js-components-svg-animate-motion.md)** + +- **[animateTransform](js-components-svg-animate-transform.md)** + + diff --git a/zh-cn/application-dev/media/Readme-CN.md b/zh-cn/application-dev/media/Readme-CN.md index 455153bc1f5..f4c1c506f20 100755 --- a/zh-cn/application-dev/media/Readme-CN.md +++ b/zh-cn/application-dev/media/Readme-CN.md @@ -1,8 +1,8 @@ # 媒体 -- [音频](audio.md) - - [音频开发概述](audio-overview.md) - - [音频播放开发指导](audio-playback.md) - - [音频管理开发指导](audio-management.md) - - [音频录制开发指导](audio-recorder.md) +- 音频 + - [音频开发概述](audio-overview.md) + - [音频播放开发指导](audio-playback.md) + - [音频管理开发指导](audio-management.md) + - [音频录制开发指导](audio-recorder.md) diff --git a/zh-cn/application-dev/media/audio-management.md b/zh-cn/application-dev/media/audio-management.md index 266eb37ed4f..32846506db5 100644 --- a/zh-cn/application-dev/media/audio-management.md +++ b/zh-cn/application-dev/media/audio-management.md @@ -1,277 +1,98 @@ -# 音频管理开发指导 +# 音频管理开发指导 -- [场景介绍](#section1269212236329) -- [接口说明](#section5122103123215) -- [开发步骤](#section1772415410138) +- [场景介绍](#场景介绍) +- [接口说明](#接口说明) +- [开发步骤](#开发步骤) -## 场景介绍 +## 场景介绍 音频管理的主要工作是音量调节与音量查询,以及输入/输出设备查询。 -## 接口说明 - -**表 1** audio的相关接口 - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

接口名

-

描述

-

getAudioManager(): AudioManager

-

获得音频管理器。

-

AudioManager

-

音频管理器。具体参考表 音频管理相关的interface AudioManager。

-

AudioDeviceDescriptor

-

描述音频设备。

-

AudioVolumeType

-

表示音频流类型的枚举。

-

DeviceFlag

-

表示可获取的设备种类的枚举。

-

DeviceRole

-

表示设备角色的枚举。

-

DeviceType

-

表示设备类型的枚举。

-
- -**表 2** 音频管理相关的interface **AudioManager** - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

接口名

-

描述

-

setVolume(audioType: AudioVolumeType,volume: number,callback: AsyncCallback<void>): void

-

改变某个流的音量。

-

setVolume(audioType: AudioVolumeType,volume: number): Promise<void>

-

改变某个流的音量。

-

getVolume(audioType: AudioVolumeType, callback: AsyncCallback<number>): void

-

获得某个流的音量。

-

getVolume(audioType: AudioVolumeType): Promise<number>

-

获得某个流的音量。

-

getMinVolume(audioType: AudioVolumeType, callback: AsyncCallback<number>): void

-

获得某个流的最小音量。

-

getMinVolume(audioType: AudioVolumeType): Promise<number>

-

获得某个流的最小音量。

-

getMaxVolume(audioType: AudioVolumeType, callback: AsyncCallback<number>): void

-

获得某个流的最大音量。

-

getMaxVolume(audioType: AudioVolumeType): Promise<number>

-

获得某个流的最大音量。

-

getDevices(deviceFlag: DeviceFlag, callback: AsyncCallback<AudioDeviceDescriptors>): void

-

获得设备列表。

-

getDevices(deviceFlag: DeviceFlag): Promise<AudioDeviceDescriptors>

-

获得设备列表。

-
- -**表 3** 表示音频设备的interface AudioDeviceDescriptor - - - - - - - - - - - - - -

属性

-

描述

-

deviceRole: DeviceRole

-

设备角色。

-

deviceType: DeviceType

-

设备类型。

-
- -**表 4** 表示音频流类型的枚举AudioVolumeType - - - - - - - - - - - - - -

枚举值

-

描述

-

MEDIA = 1

-

媒体声音。

-

RINGTONE = 2

-

铃声。

-
- -**表 5** 表示可获取的设备种类的枚举DeviceFlag - - - - - - - - - - - - - - - - -

枚举值

-

描述

-

OUTPUT_DEVICES_FLAG = 1

-

输出设备。

-

INPUT_DEVICES_FLAG = 2

-

输入设备。

-

ALL_DEVICES_FLAG = 3

-

所有设备。

-
- -**表 6** 表示设备角色的枚举DeviceRole - - - - - - - - - - - - - -

枚举值

-

描述

-

INPUT_DEVICE = 1

-

输入设备。

-

OUTPUT_DEVICE = 2

-

输出设备。

-
- -**表 7** 表示设备类型的枚举DeviceType - - - - - - - - - - - - - - - - - - - - - - - - - -

枚举值

-

描述

-

INVALID = 0

-

无效。

-

SPEAKER = 1

-

扬声器。

-

WIRED_HEADSET = 2

-

有线耳机。

-

BLUETOOTH_SCO = 3

-

蓝牙设备。

-

BLUETOOTH_A2DP = 4

-

支持A2DP的蓝牙设备。

-

MIC = 5

-

麦克风。

-
- -## 开发步骤 - -1. 获取音频控制器。 - - ``` - const audioManager = audio.getAudioManager(); - ``` - -2. 改变媒体流的声音。 - - ``` - audioManager.getVolume(audio.AudioVolumeType.MEDIA, (err, value) => { - if (err) { - console.error(`failed to get volume ${err.message}`); - return; - } - console.log(`Media getVolume ${value}`); - }); - ``` - +## 接口说明 + +**表1** audio的相关接口 + +| 接口名 | 描述 | +| -------- | -------- | +| getAudioManager(): AudioManager | 获得音频管理器。 | +| AudioManager | 音频管理器。具体参考表 音频管理相关的interface AudioManager。 | +| AudioDeviceDescriptor | 描述音频设备。 | +| AudioVolumeType | 表示音频流类型的枚举。 | +| DeviceFlag | 表示可获取的设备种类的枚举。 | +| DeviceRole | 表示设备角色的枚举。 | +| DeviceType | 表示设备类型的枚举。 | + +**表2** 音频管理相关的interface **AudioManager** + +| 接口名 | 描述 | +| -------- | -------- | +| setVolume(audioType: AudioVolumeType,volume: number,callback: AsyncCallback<void>): void | 改变某个流的音量。 | +| setVolume(audioType: AudioVolumeType,volume: number): Promise<void> | 改变某个流的音量。 | +| getVolume(audioType: AudioVolumeType, callback: AsyncCallback<number>): void | 获得某个流的音量。 | +| getVolume(audioType: AudioVolumeType): Promise<number> | 获得某个流的音量。 | +| getMinVolume(audioType: AudioVolumeType, callback: AsyncCallback<number>): void | 获得某个流的最小音量。 | +| getMinVolume(audioType: AudioVolumeType): Promise<number> | 获得某个流的最小音量。 | +| getMaxVolume(audioType: AudioVolumeType, callback: AsyncCallback<number>): void | 获得某个流的最大音量。 | +| getMaxVolume(audioType: AudioVolumeType): Promise<number> | 获得某个流的最大音量。 | +| getDevices(deviceFlag: DeviceFlag, callback: AsyncCallback<AudioDeviceDescriptors>): void | 获得设备列表。 | +| getDevices(deviceFlag: DeviceFlag): Promise<AudioDeviceDescriptors> | 获得设备列表。 | + +**表3** 表示音频设备的interface **AudioDeviceDescriptor** + +| 属性 | 描述 | +| -------- | -------- | +| deviceRole: DeviceRole | 设备角色。 | +| deviceType: DeviceType | 设备类型。 | + +**表4** 表示音频流类型的枚举**AudioVolumeType** + +| 枚举值 | 描述 | +| -------- | -------- | +| MEDIA = 1 | 媒体声音。 | +| RINGTONE = 2 | 铃声。 | + +**表5** 表示可获取的设备种类的枚举**DeviceFlag** + +| 枚举值 | 描述 | +| -------- | -------- | +| OUTPUT_DEVICES_FLAG = 1 | 输出设备。 | +| INPUT_DEVICES_FLAG = 2 | 输入设备。 | +| ALL_DEVICES_FLAG = 3 | 所有设备。 | + +**表6** 表示设备角色的枚举**DeviceRole** + +| 枚举值 | 描述 | +| -------- | -------- | +| INPUT_DEVICE = 1 | 输入设备。 | +| OUTPUT_DEVICE = 2 | 输出设备。 | + +**表7** 表示设备类型的枚举**DeviceType** + +| 枚举值 | 描述 | +| -------- | -------- | +| INVALID = 0 | 无效。 | +| SPEAKER = 1 | 扬声器。 | +| WIRED_HEADSET = 2 | 有线耳机。 | +| BLUETOOTH_SCO = 3 | 蓝牙设备。 | +| BLUETOOTH_A2DP = 4 | 支持A2DP的蓝牙设备。 | +| MIC = 5 | 麦克风。 | + + +## 开发步骤 + +1. 获取音频控制器。 + ``` + const audioManager = audio.getAudioManager(); + ``` + +2. 改变媒体流的声音。 + ``` + audioManager.getVolume(audio.AudioVolumeType.MEDIA, (err, value) => { + if (err) { + console.error(`failed to get volume ${err.message}`); + return; + } + console.log(`Media getVolume ${value}`); + }); + ``` diff --git a/zh-cn/application-dev/media/audio-overview.md b/zh-cn/application-dev/media/audio-overview.md index a7fd8459312..0ed6864c602 100644 --- a/zh-cn/application-dev/media/audio-overview.md +++ b/zh-cn/application-dev/media/audio-overview.md @@ -1,32 +1,23 @@ -# 音频开发概述 +# 音频开发概述 -- [基本概念](#section296512102281) +- [基本概念](#基本概念) OpenHarmony音频模块支持音频业务的开发,提供音频相关的功能,主要包括音频播放、音量管理等。 ->![](../public_sys-resources/icon-note.gif) **说明:** ->由于权限问题,此部分功能在标准系统暂不可用。 -## 基本概念 +## 基本概念 -- **采样** +- **采样**
+ 采样是指将连续时域上的模拟信号按照一定的时间间隔采样,获取到离散时域上离散信号的过程。 - 采样是指将连续时域上的模拟信号按照一定的时间间隔采样,获取到离散时域上离散信号的过程。 +- **采样率**
+ 采样率为每秒从连续信号中提取并组成离散信号的采样次数,单位用赫兹(Hz)来表示。通常人耳能听到频率范围大约在20Hz~20kHz之间的声音。常用的音频采样频率有:8kHz、11.025kHz、22.05kHz、16kHz、37.8kHz、44.1kHz、48kHz、96kHz、192kHz等。 -- **采样率** - - 采样率为每秒从连续信号中提取并组成离散信号的采样次数,单位用赫兹(Hz)来表示。通常人耳能听到频率范围大约在20Hz~20kHz之间的声音。常用的音频采样频率有:8kHz、11.025kHz、22.05kHz、16kHz、37.8kHz、44.1kHz、48kHz、96kHz、192kHz等。 - -- **声道** - - 声道是指声音在录制或播放时在不同空间位置采集或回放的相互独立的音频信号,所以声道数也就是声音录制时的音源数量或回放时相应的扬声器数量。 - -- **音频帧** - - 音频数据是流式的,本身没有明确的一帧帧的概念,在实际的应用中,为了音频算法处理/传输的方便,一般约定俗成取2.5ms\~60ms为单位的数据量为一帧音频。这个时间被称之为“采样时间”,其长度没有特别的标准,它是根据编解码器和具体应用的需求来决定的。 - -- **PCM** - - PCM(Pulse Code Modulation),即脉冲编码调制,是一种将模拟信号数字化的方法,是将时间连续、取值连续的模拟信号转换成时间离散、抽样值离散的数字信号的过程。 +- **声道**
+ 声道是指声音在录制或播放时在不同空间位置采集或回放的相互独立的音频信号,所以声道数也就是声音录制时的音源数量或回放时相应的扬声器数量。 +- **音频帧**
+ 音频数据是流式的,本身没有明确的一帧帧的概念,在实际的应用中,为了音频算法处理/传输的方便,一般约定俗成取2.5ms~60ms为单位的数据量为一帧音频。这个时间被称之为“采样时间”,其长度没有特别的标准,它是根据编解码器和具体应用的需求来决定的。 +- **PCM**
+ PCM(Pulse Code Modulation),即脉冲编码调制,是一种将模拟信号数字化的方法,是将时间连续、取值连续的模拟信号转换成时间离散、抽样值离散的数字信号的过程。 diff --git a/zh-cn/application-dev/media/audio-playback.md b/zh-cn/application-dev/media/audio-playback.md index 26fc1ceccda..d6a6b72cee3 100644 --- a/zh-cn/application-dev/media/audio-playback.md +++ b/zh-cn/application-dev/media/audio-playback.md @@ -1,240 +1,131 @@ -# 音频播放开发指导 +# 音频播放开发指导 -- [场景介绍](#section910413166166) -- [接口说明](#section1225204317126) +- [场景介绍](#场景介绍) +- [接口说明](#接口说明) -## 场景介绍 +## 场景介绍 音频播放的主要工作是将音频数据转码为可听见的音频模拟信号并通过输出设备进行播放,同时对播放任务进行管理。 -**图 1** 音频播放状态机 -![](figures/音频播放状态机.png "音频播放状态机") - -## 接口说明 - -**表 1** media - - - - - - - - - - - - - -

接口名

-

描述

-

media.createAudioPlayer()

-

创建AudioPlayer实例。

-

AudioPlayer

-

提供音频播放相关功能,具体见表 音频播放相关的interface AudioPlayer。

-
- -**表 2** 音频播放相关的interface **AudioPlayer** - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

接口名

-

描述

-

release()

-

释放音频资源。

-

play()

-

开始播放音频源。

-

pause()

-

暂停播放。

-

stop()

-

停止播放。

-

reset()7+

-

重置播放音频源。

-

setVolume(vol: number)

-

改变音频播放音量

-

seek(timeMs: number)

-

改变播放位置。

-

src:string

-

音频播放的媒体URI。

-

state:AudioState

-

播放的状态属性。

-

currentTime:number

-

音频的当前播放位置。

-

duration:number

-

音频播放的时长。

-

loop:boolean

-

音频的循环播放属性。

-

on('play', function callback)

-

订阅音频播放开始事件。

-

on('pause', function callback)

-

订阅音频播放暂停事件。

-

on('stop', function callback)

-

订阅音频播放停止事件。

-

on('reset', function callback)

-

订阅音频播放重置事件。

-

on('finish',function callback)

-

订阅音频播放结束事件。

-

on('error', function callback)

-

订阅音频播放错误事件。

-

on('dataload', function callback)

-

订阅音频播放加载数据事件。

-

on('volumeChange', function callback)

-

订阅音频播放音量变化事件。

-

on('timeUpdate', function callback)

-

订阅音频播放进度改变事件。

-
- -1. 创建音频播放器。 - - ``` - import media from '@ohos.multimedia.media'; - var player = media.createAudioPlayer(); - ``` - -2. 设置消息订阅事件。 - - ``` - player.on('play', (err, action) => { +**图1** 音频播放状态机 +![zh-cn_image_0000001182608857](figures/zh-cn_image_0000001182608857.png) + + +## 接口说明 + +**表1** media + +| 接口名 | 描述 | +| -------- | -------- | +| media.createAudioPlayer() | 创建AudioPlayer实例。 | +| AudioPlayer | 提供音频播放相关功能,具体见表 音频播放相关的interface AudioPlayer。 | + +**表2** 音频播放相关的interface **AudioPlayer** + +| 接口名 | 描述 | +| -------- | -------- | +| release() | 释放音频资源。 | +| play() | 开始播放音频源。 | +| pause() | 暂停播放。 | +| stop() | 停止播放。 | +| reset()7+ | 重置播放音频源。 | +| setVolume(vol: number) | 改变音频播放音量 | +| seek(timeMs: number) | 改变播放位置。 | +| src:string | 音频播放的媒体URI。 | +| state:AudioState | 播放的状态属性。 | +| currentTime:number | 音频的当前播放位置。 | +| duration:number | 音频播放的时长。 | +| loop:boolean | 音频的循环播放属性。 | +| on('play', function callback) | 订阅音频播放开始事件。 | +| on('pause', function callback) | 订阅音频播放暂停事件。 | +| on('stop', function callback) | 订阅音频播放停止事件。 | +| on('reset', function callback) | 订阅音频播放重置事件。 | +| on('finish',function callback) | 订阅音频播放结束事件。 | +| on('error', function callback) | 订阅音频播放错误事件。 | +| on('dataload', function callback) | 订阅音频播放加载数据事件。 | +| on('volumeChange', function callback) | 订阅音频播放音量变化事件。 | +| on('timeUpdate', function callback) | 订阅音频播放进度改变事件。 | + + +1. 创建音频播放器。 + ``` + import media from '@ohos.multimedia.media'; + var player = media.createAudioPlayer(); + ``` + +2. 设置消息订阅事件。 + ``` + player.on('play', (err, action) => { + if (err) { + console.error('Error returned in the play() callback.'); + return; + } + console.info('Current player duration: '+ player.duration); + console.info('Current player time: ' + player.currentTime); + console.info('Current player status: '+player.state); + console.info('Pause MP3'); + player.pause(); + }); + player.on('pause', (err, action) => { if (err) { - console.error('Error returned in the play() callback.'); + console.error('Error returned in the pause() callback.'); return; } - console.info('Current player duration: '+ player.duration); + console.info('Current player status: ' + player.state); console.info('Current player time: ' + player.currentTime); - console.info('Current player status: '+player.state); - console.info('Pause MP3'); - player.pause(); - }); - player.on('pause', (err, action) => { - if (err) { - console.error('Error returned in the pause() callback.'); - return; - } - console.info('Current player status: ' + player.state); - console.info('Current player time: ' + player.currentTime); - player.seek(30000); // Seek for 30 seconds. - }); - player.on('stop', (err, action) => { + player.seek(30000); // Seek for 30 seconds. + }); + player.on('stop', (err, action) => { + if (err) { + console.error('Error returned in the stop() callback.'); + return; + } + console.info('stop callback invoked. State:' + player.state); + player.reset(); + }); + player.on('dataLoad', (err, action) => { + if (err) { + console.error('Error returned in the dataLoad() callback.'); + return; + } + console.info('dataLoad callback invoked. Current time: ' + player.currentTime); + console.info('Duration of the source:' + player.duration); + player.play(); + }); + player.on('reset', (err, action) => { + if (err) { + console.error('Error returned in the reset() callback.'); + return; + } + console.info('reset callback invoked.'); + player.release(); + }); + player.on('finish', (err, action) => { if (err) { - console.error('Error returned in the stop() callback.'); - return; + console.error('Error returned in the finish() callback.'); + return; } - console.info('stop callback invoked. State:' + player.state); - player.reset(); - }); - player.on('dataLoad', (err, action) => { - if (err) { - console.error('Error returned in the dataLoad() callback.'); - return; - } - console.info('dataLoad callback invoked. Current time: ' + player.currentTime); - console.info('Duration of the source:' + player.duration); - player.play(); - }); - player.on('reset', (err, action) => { - if (err) { - console.error('Error returned in the reset() callback.'); - return; + console.info('finish callback invoked.'); + }); + player.on('timeUpdate', (seekTime, action) => { + console.info('Seek time: ' + seekTime); + console.info('Current player time: ' + player.currentTime); + var newTime = player.currentTime; + if(newTime == 30000) { + console.info('Seek succeeded. New time: ' + newTime); + } else { + console.error('Seek failed: ', + newTime); } - console.info('reset callback invoked.'); - player.release(); - }); - player.on('finish', (err, action) => { - if (err) { - console.error('Error returned in the finish() callback.'); - return; - } - console.info('finish callback invoked.'); - }); - player.on('timeUpdate', (seekTime, action) => { - console.info('Seek time: ' + seekTime); - console.info('Current player time: ' + player.currentTime); - var newTime = player.currentTime; - if(newTime == 30000) { - console.info('Seek succeeded. New time: ' + newTime); - } else { - console.error('Seek failed: ', + newTime); - } - player.stop(); - }); - player.on('error', (err) => { - console.error('Player error: ${err.message}'); - }); - ``` - -3. 启动播放。 - - ``` - var audioSourceMp3 = 'file://test.mp3'; - player.src = audioSourceMp3; - player.loop = true; - ``` - - + player.stop(); + }); + player.on('error', (err) => { + console.error('Player error: ${err.message}'); + }); + ``` + +3. 启动播放。 + ``` + var audioSourceMp3 = 'file://test.mp3'; + player.src = audioSourceMp3; + player.loop = true; + ``` diff --git a/zh-cn/application-dev/media/audio-recorder.md b/zh-cn/application-dev/media/audio-recorder.md index c5262d67f16..4f08a8fae8a 100644 --- a/zh-cn/application-dev/media/audio-recorder.md +++ b/zh-cn/application-dev/media/audio-recorder.md @@ -1,267 +1,120 @@ -# 音频录制开发指导 +# 音频录制开发指导 -- [场景介绍](#section910413166166) -- [接口说明](#section1225204317126) +- [场景介绍](#场景介绍) +- [接口说明](#接口说明) -## 场景介绍 +## 场景介绍 音频录制的主要工作是将音频信号记录并保存下来,同时提供包括采样率、声道数、码率、编码格式、封装格式、文件路径等设置功能。 -## 接口说明 - -**表 1** media - - - - - - - - - - - - - - - - -

接口名

-

描述

-

media.createAudioRecorder()

-

创建AudioRecorder实例。

-

AudioRecorder

-

提供音频录制相关功能。

-

AudioRecorderConfig

-

提供音频录制相关参数设置。

-
- -**表 2** 音频录制相关的interface AudioRecorder - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

接口名

-

描述

-

prepare(config: AudioRecorderConfig): void

-

准备音频录制并设置参数。

-

start(): void

-

开始音频录制。

-

pause(): void

-

暂停音频录制。(暂不支持)

-

resume(): void

-

恢复音频录制。(暂不支持)

-

stop(): void

-

停止音频录制。

-

release(): void

-

释放音频录制资源。

-

reset(): void

-

重置音频录制。

-

on('prepare', function callback)

-

订阅音频录制准备事件。

-

on('start', function callback)

-

订阅音频录制开始事件。

-

on('pause', function callback)

-

订阅音频录制暂停事件。

-

on('resume', function callback)

-

订阅音频录制恢复事件。

-

on('stop',function callback)

-

订阅音频录制结束事件。

-

on('release', function callback)

-

订阅音频录制释放资源事件。

-

on('reset', function callback)

-

订阅音频录制重置事件。

-

on('error', function callback)

-

订阅音频录制错误事件。

-
- -**表 3** 音频录制的相关参数的interface AudioRecorderConfig - - - - - - - - - - - - - - - - - - - - - - - - - -

接口名

-

描述

-

audioEncoder?: AudioEncoder

-

音频编码格式,默认值是AAC_LC。

-

audioEncodeBitRate?: number

-

音频编码的比特率,默认值为48000。

-

audioSampleRate?: number

-

音频编码的采样率,默认值为48000。

-

numberOfChannels?:number

-

音频的声道数,默认值为2。

-

format?: AudioOutputFormat

-

音频的输出格式,默认值是MPEG_4。

-

uri: string

-

音频的输出路径。(file://path 或者 file://fd)

-
- -**表 4** AudioEncoder的相关参数的interface AudioEncoder - - - - - - - - - - -

接口名

-

描述

-

AAC_LC = 3

-

表示AAC_LC编码格式。

-
- -**表 5** 音频输出格式的相关参数的interface AudioOutputFormat - - - - - - - - - - - - - -

接口名

-

描述

-

MPEG_4 = 2

-

表示MPEG_4编码格式。

-

AAC_ADTS= 6

-

表示AAC_ADTS编码格式。

-
- -1. 创建音频录制器。 - - ``` - import media from '@ohos.multimedia.media'; - var recorder = media.createAudioRecorder(); - ``` - -2. 准备音频录制参数。 - - ``` - let audioRecorderConfig = { - audioEncoder : AAC_LC , - audioEncodeBitRate : 22050, - audioSampleRate : 22050, - numberOfChannels : 2, - format : AAC_ADTS, - uri : 'file:///data/accounts/account_0/appdata/appdata/recorder/test.m4a', - } - recorder.prepare(audioRecorderConfig); - ``` - -3. 设置消息订阅事件。 - - ``` - recorder.on('prepare', () => { - console.info('setCallback prepare() case callback is called'); - recorder.start(); - }); - recorder.on('start', () => { - console.info('setCallback start() case callback is called'); - setTimeout(function(){ - recorder.pause(); - }, 10000); // 开始录音10秒后,暂停录音。 - }); - recorder.on('pause', () => { - console.info('setCallback pause() case callback is called'); - setTimeout(function(){ - recorder.resume(); - }, 10000); // 暂停录音10秒后,恢复录音。 - }); - recorder.on('resume', () => { - console.info('setCallback resume() case callback is called'); - setTimeout(function(){ - recorder.stop(); - }, 10000); // 恢复录音10秒后,停止录音。 - }); - recorder.on('stop', () => { - console.info('setCallback stop() case callback is called'); - recorder.release(); - }); - recorder.on('release', () => { - console.info('setCallback release() case callback is called'); - }); - recorder.on('error', (err) => { - console.info(`case error called,errCode is ${err.code}`); - console.info(`case error called,errMessage is ${err.message}`); - recorder.reset(); - }); - ``` - +## 接口说明 + +**表1** media + +| 接口名 | 描述 | +| -------- | -------- | +| media.createAudioRecorder() | 创建AudioRecorder实例。 | +| AudioRecorder | 提供音频录制相关功能。 | +| AudioRecorderConfig | 提供音频录制相关参数设置。 | + +**表2** 音频录制相关的interface **AudioRecorder** + +| 接口名 | 描述 | +| -------- | -------- | +| prepare(config: AudioRecorderConfig): void | 准备音频录制并设置参数。 | +| start(): void | 开始音频录制。 | +| pause(): void | 暂停音频录制。(暂不支持) | +| resume(): void | 恢复音频录制。(暂不支持) | +| stop(): void | 停止音频录制。 | +| release(): void | 释放音频录制资源。 | +| reset(): void | 重置音频录制。 | +| on('prepare', function callback) | 订阅音频录制准备事件。 | +| on('start', function callback) | 订阅音频录制开始事件。 | +| on('pause', function callback) | 订阅音频录制暂停事件。 | +| on('resume', function callback) | 订阅音频录制恢复事件。 | +| on('stop',function callback) | 订阅音频录制结束事件。 | +| on('release', function callback) | 订阅音频录制释放资源事件。 | +| on('reset', function callback) | 订阅音频录制重置事件。 | +| on('error', function callback) | 订阅音频录制错误事件。 | + +**表3** 音频录制的相关参数的interface **AudioRecorderConfig** + +| 接口名 | 描述 | +| -------- | -------- | +| audioEncoder?: AudioEncoder | 音频编码格式,默认值是AAC_LC。 | +| audioEncodeBitRate?: number | 音频编码的比特率,默认值为48000。 | +| audioSampleRate?: number | 音频编码的采样率,默认值为48000。 | +| numberOfChannels?:number | 音频的声道数,默认值为2。 | +| format?: AudioOutputFormat | 音频的输出格式,默认值是MPEG_4。 | +| uri: string | 音频的输出路径。(file://path 或者 file://fd) | + +**表4** AudioEncoder的相关参数的interface **AudioEncoder** + +| 接口名 | 描述 | +| -------- | -------- | +| AAC_LC = 3 | 表示AAC_LC编码格式。 | + +**表5** 音频输出格式的相关参数的interface **AudioOutputFormat** + +| 接口名 | 描述 | +| -------- | -------- | +| MPEG_4 = 2 | 表示MPEG_4编码格式。 | +| AAC_ADTS= 6 | 表示AAC_ADTS编码格式。 | + +1. 创建音频录制器。 + ``` + import media from '@ohos.multimedia.media'; + var recorder = media.createAudioRecorder(); + ``` + +2. 准备音频录制参数。 + ``` + let audioRecorderConfig = { + audioEncoder : AAC_LC , + audioEncodeBitRate : 22050, + audioSampleRate : 22050, + numberOfChannels : 2, + format : AAC_ADTS, + uri : 'file:///data/accounts/account_0/appdata/appdata/recorder/test.m4a', + } + recorder.prepare(audioRecorderConfig); + ``` + +3. 设置消息订阅事件。 + ``` + recorder.on('prepare', () => { + console.info('setCallback prepare() case callback is called'); + recorder.start(); + }); + recorder.on('start', () => { + console.info('setCallback start() case callback is called'); + setTimeout(function(){ + recorder.pause(); + }, 10000); // 开始录音10秒后,暂停录音。 + }); + recorder.on('pause', () => { + console.info('setCallback pause() case callback is called'); + setTimeout(function(){ + recorder.resume(); + }, 10000); // 暂停录音10秒后,恢复录音。 + }); + recorder.on('resume', () => { + console.info('setCallback resume() case callback is called'); + setTimeout(function(){ + recorder.stop(); + }, 10000); // 恢复录音10秒后,停止录音。 + }); + recorder.on('stop', () => { + console.info('setCallback stop() case callback is called'); + recorder.release(); + }); + recorder.on('release', () => { + console.info('setCallback release() case callback is called'); + }); + recorder.on('error', (err) => { + console.info(`case error called,errCode is ${err.code}`); + console.info(`case error called,errMessage is ${err.message}`); + recorder.reset(); + }); + ``` diff --git a/zh-cn/application-dev/media/audio.md b/zh-cn/application-dev/media/audio.md index 6a65ab2c8f6..4ac8b0a4fe3 100644 --- a/zh-cn/application-dev/media/audio.md +++ b/zh-cn/application-dev/media/audio.md @@ -1,11 +1,10 @@ -# 音频 +# 音频 -- **[音频开发概述](audio-overview.md)** -- **[音频播放开发指导](audio-playback.md)** +- **[音频开发概述](audio-overview.md)** -- **[音频管理开发指导](audio-management.md)** - -- **[音频录制开发指导](audio-recorder.md)** +- **[音频播放开发指导](audio-playback.md)** +- **[音频管理开发指导](audio-management.md)** +- **[音频录制开发指导](audio-recorder.md)** \ No newline at end of file diff --git "a/zh-cn/application-dev/media/figures/\351\237\263\351\242\221\346\222\255\346\224\276\347\212\266\346\200\201\346\234\272.png" b/zh-cn/application-dev/media/figures/zh-cn_image_0000001182608857.png old mode 100755 new mode 100644 similarity index 100% rename from "zh-cn/application-dev/media/figures/\351\237\263\351\242\221\346\222\255\346\224\276\347\212\266\346\200\201\346\234\272.png" rename to zh-cn/application-dev/media/figures/zh-cn_image_0000001182608857.png diff --git a/zh-cn/application-dev/media/public_sys-resources/icon-caution.gif b/zh-cn/application-dev/media/public_sys-resources/icon-caution.gif new file mode 100644 index 0000000000000000000000000000000000000000..6e90d7cfc2193e39e10bb58c38d01a23f045d571 GIT binary patch literal 580 zcmV-K0=xZ3Nk%w1VIu$?0Hp~4{QBgqmQ+MG9K51r{QB&)np^||1PlfQ%(86!{`~yv zv{XhUWKt}AZaiE{EOcHp{O-j3`t;<+eEiycJT4p@77X;(jQsMfB$R?oG%6hQ z+MMLZbQBH@)Vg&1^3?qHb(5!%>3r0+`eq=&V&E}0Dypi0000000000 z00000A^8LW000R9EC2ui03!e$000L5z=Uu}ED8YtqjJd<+B}(9bIOb$3-31_h|V>=0A{ z1Hh0#H30>fNT})^fRU_83uewx9oRr{f{Sx1Ml`t)EQ zGkHZ67&~y{W5Jpq4H_WfuLxp*3<7O}GEl;1ESe36fLNs=B0&LQM1Buf(R)qg(BRd`t1OPjI1m_q4 literal 0 HcmV?d00001 diff --git a/zh-cn/application-dev/media/public_sys-resources/icon-danger.gif b/zh-cn/application-dev/media/public_sys-resources/icon-danger.gif new file mode 100644 index 0000000000000000000000000000000000000000..6e90d7cfc2193e39e10bb58c38d01a23f045d571 GIT binary patch literal 580 zcmV-K0=xZ3Nk%w1VIu$?0Hp~4{QBgqmQ+MG9K51r{QB&)np^||1PlfQ%(86!{`~yv zv{XhUWKt}AZaiE{EOcHp{O-j3`t;<+eEiycJT4p@77X;(jQsMfB$R?oG%6hQ z+MMLZbQBH@)Vg&1^3?qHb(5!%>3r0+`eq=&V&E}0Dypi0000000000 z00000A^8LW000R9EC2ui03!e$000L5z=Uu}ED8YtqjJd<+B}(9bIOb$3-31_h|V>=0A{ z1Hh0#H30>fNT})^fRU_83uewx9oRr{f{Sx1Ml`t)EQ zGkHZ67&~y{W5Jpq4H_WfuLxp*3<7O}GEl;1ESe36fLNs=B0&LQM1Buf(R)qg(BRd`t1OPjI1m_q4 literal 0 HcmV?d00001 diff --git a/zh-cn/application-dev/media/public_sys-resources/icon-note.gif b/zh-cn/application-dev/media/public_sys-resources/icon-note.gif new file mode 100644 index 0000000000000000000000000000000000000000..6314297e45c1de184204098efd4814d6dc8b1cda GIT binary patch literal 394 zcmZ?wbhEHblx7fPSjxcg=ii?@_wH=jwxy=7CMGH-B`L+l$wfv=#>UF#$gv|VY%C^b zCQFtrnKN(Bo_%|sJbO}7RAORe!otL&qo<>yq_Sq+8Xqqo5h0P3w3Lvb5E(g{p01vl zxR@)KuDH0l^z`+-dH3eaw=XqSH7aTIx{kzVBN;X&hha0dQSgWuiw0NWUvMRmkD|> literal 0 HcmV?d00001 diff --git a/zh-cn/application-dev/media/public_sys-resources/icon-notice.gif b/zh-cn/application-dev/media/public_sys-resources/icon-notice.gif new file mode 100644 index 0000000000000000000000000000000000000000..86024f61b691400bea99e5b1f506d9d9aef36e27 GIT binary patch literal 406 zcmV;H0crk6Nk%w1VIu$@0J8u9|NsB@_xJDb@8;&_*4Ea}&d#;9wWXz{jEszHYim+c zQaU<1At50E0000000000A^8Le000gEEC2ui03!e%000R7038S%NU)&51O^i-Tu6`s z0)`MFE@;3YqD6xSC^kTNu_J>91{PH8XfZ(p1pp2-SU@u3#{mEUC}_}tg3+I#{z}{Ok@D_ZUDg- zt0stin4;pC8M{WLSlRH*1pzqEw1}3oOskyNN?j;7HD{BBZ*OEcv4HK!6Bk6beR+04 z&8}k>SkTusVTDmkyOz#5fCA$JTPGJVQvr3uZ?QzzPQFvD0rGf_PdrcF`pMs}p^BcF zKtKTd`0wipR%nKN&Wj+V}pX;WC3SdJV!a_8Qi zE7z`U*|Y^H0^}fB$R?oG%6hQ z+MMLZbQBH@)Vg&1^3?qHb(5!%>3r0+`eq=&V&E}0Dypi0000000000 z00000A^8LW000R9EC2ui03!e$000L5z=Uu}ED8YtqjJd<+B}(9bIOb$3-31_h|V>=0A{ z1Hh0#H30>fNT})^fRU_83uewx9oRr{f{Sx1Ml`t)EQ zGkHZ67&~y{W5Jpq4H_WfuLxp*3<7O}GEl;1ESe36fLNs=B0&LQM1Buf(R)qg(BRd`t1OPjI1m_q4 literal 0 HcmV?d00001 diff --git a/zh-cn/application-dev/quick-start/Readme-CN.md b/zh-cn/application-dev/quick-start/Readme-CN.md index dde1c376539..ee2c9cdf2ab 100755 --- a/zh-cn/application-dev/quick-start/Readme-CN.md +++ b/zh-cn/application-dev/quick-start/Readme-CN.md @@ -1,17 +1,15 @@ # 入门 -- [DevEco Studio(OpenHarmony)使用指南](deveco-studio-user-guide-for-openharmony.md) - - [概述](deveco-studio-overview.md) - - [版本变更说明](deveco-studio-release-notes.md) - - [配置OpenHarmony SDK](configuring-openharmony-sdk.md) - - [创建OpenHarmony工程](create-openharmony-project.md) - - [使用工程向导创建新工程](use-wizard-to-create-project.md) - - [通过导入Sample方式创建新工程](import-sample-to-create-project.md) - - - [配置OpenHarmony应用签名信息](configuring-openharmony-app-signature.md) - - [安装运行OpenHarmony应用](installing-openharmony-app.md) -- [包结构说明](package-structure.md) -- [快速入门](start.md) - - [开发准备](start-overview.md) - - [使用JS语言开发](start-with-js.md) - +- DevEco Studio(OpenHarmony)使用指南 + - [概述](deveco-studio-overview.md) + - [版本变更说明](deveco-studio-release-notes.md) + - [配置OpenHarmony SDK](configuring-openharmony-sdk.md) + - 创建OpenHarmony工程 + - [使用工程向导创建新工程](use-wizard-to-create-project.md) + - [通过导入Sample方式创建新工程](import-sample-to-create-project.md) + - [配置OpenHarmony应用签名信息](configuring-openharmony-app-signature.md) + - [安装运行OpenHarmony应用](installing-openharmony-app.md) +- [包结构说明](package-structure.md) +- 快速入门 + - [开发准备](start-overview.md) + - [使用JS语言开发](start-with-js.md) diff --git a/zh-cn/application-dev/quick-start/configuring-openharmony-app-signature.md b/zh-cn/application-dev/quick-start/configuring-openharmony-app-signature.md index 2b6c107342a..a5f9f281179 100644 --- a/zh-cn/application-dev/quick-start/configuring-openharmony-app-signature.md +++ b/zh-cn/application-dev/quick-start/configuring-openharmony-app-signature.md @@ -1,23 +1,26 @@ -# 配置OpenHarmony应用签名信息 +# 配置OpenHarmony应用签名信息 -- [生成密钥和证书请求文件](#section153146467405) -- [生成应用证书文件](#section136609429562) -- [生成应用Profile文件](#section2048641015325) -- [配置应用签名信息](#section10152423193310) +- [生成密钥和证书请求文件](#生成密钥和证书请求文件) +- [生成应用证书文件](#生成应用证书文件) +- [生成应用Profile文件](#生成应用profile文件) +- [配置应用签名信息](#配置应用签名信息) 使用真机设备运行和调试OpenHarmony应用前,需要对应用进行签名才能正常运行。该指导用于OpenHarmony应用的签名配置。除此章节以外,DevEco Studio的其余操作指导无差别,具体请访问[HUAWEI DevEco Studio使用指南](https://developer.harmonyos.com/cn/docs/documentation/doc-guides/tools_overview-0000001053582387)。配置应用签名信息的流程如下图所示。 -![](figures/zh-cn_image_0000001113808114.png) -## 生成密钥和证书请求文件 +![zh-cn_image_0000001113808114](figures/zh-cn_image_0000001113808114.png) + + +## 生成密钥和证书请求文件 OpenHarmony应用通过数字证书(.cer文件)和Profile文件(.p7b文件)来保证应用的完整性,需要通过DevEco Studio来生成密钥文件(.p12文件)和证书请求文件(.csr文件)。同时,也可以使用命令行工具的方式来生成密钥文件和证书请求文件。具体操作请参考[生成密钥和证书请求文件](https://developer.harmonyos.com/cn/docs/documentation/doc-guides/publish_app-0000001053223745#section9752152162813)。 -## 生成应用证书文件 -使用[生成密钥和证书请求文件](#section153146467405)中生成的证书请求文件,来生成应用签名所需的数字证书文件。生成方法如下: +## 生成应用证书文件 -进入DevEco Studio安装目录的**Sdk\\toolchains\\lib**文件夹下(该SDK目录只能是OpenHarmony SDK,配置方法可参考[配置OpenHarmony SDK](configuring-openharmony-sdk.md)),打开命令行工具,执行如下命令(如果keytool命令不能执行,请在系统环境变量中添加JDK的环境变量)。其中,只需要修改输入和输出即可快速生成证书文件,即修改**-infile**指定证书请求文件csr文件路径,**-outfile**指定输出证书文件名及路径。 +使用[生成密钥和证书请求文件](#生成密钥和证书请求文件)中生成的证书请求文件,来生成应用签名所需的数字证书文件。生成方法如下: + +进入DevEco Studio安装目录的 **Sdk\toolchains\lib**文件夹下(该SDK目录只能是OpenHarmony SDK,配置方法可参考[配置OpenHarmony SDK](../quick-start/configuring-openharmony-sdk.md)),打开命令行工具,执行如下命令(如果keytool命令不能执行,请在系统环境变量中添加JDK的环境变量)。其中,只需要修改输入和输出即可快速生成证书文件,即修改 **-infile**指定证书请求文件csr文件路径, **-outfile**指定输出证书文件名及路径。 ``` keytool -gencert -alias "OpenHarmony Application CA" -infile myApplication_ohos.csr -outfile myApplication_ohos.cer -keystore OpenHarmony.p12 -sigalg SHA384withECDSA -storepass 123456 -ext KeyUsage:"critical=digitalSignature" -validity 3650 -rfc @@ -25,21 +28,30 @@ keytool -gencert -alias "OpenHarmony Application CA" -infile myApplication_ohos. 关于该命令的参数说明如下: -- **alias**:用于签发证书的CA私钥别名,OpenHarmony社区CA私钥存于OpenHarmony.p12密钥库文件中,该参数不能修改。 -- **infile**:证书请求(CSR)文件的路径。 -- **outfile**:输出证书链文件名及路径。 -- **keystore**:签发证书的CA密钥库路径,OpenHarmony密钥库文件名为OpenHarmony.p12,文件在OpenHarmony SDK中**Sdk\\toolchains\\lib**路径下,该参数不能修改。请注意,该OpenHarmony.p12文件并不是[生成密钥和证书请求文件](#section153146467405)中生成的.p12文件。 -- **sigalg**:证书签名算法,该参数不能修改。 -- **storepass**:密钥库密码,密码为123456,该参数不能修改。 -- **ext**:证书扩展项,该参数不能修改。 -- **validity**:证书有效期,自定义天数。 -- **rfc**:输出文件格式指定,该参数不能修改。 +- **alias**:用于签发证书的CA私钥别名,OpenHarmony社区CA私钥存于OpenHarmony.p12密钥库文件中,该参数不能修改。 + +- **infile**:证书请求(CSR)文件的路径。 + +- **outfile**:输出证书链文件名及路径。 + +- **keystore**:签发证书的CA密钥库路径,OpenHarmony密钥库文件名为OpenHarmony.p12,文件在OpenHarmony SDK中 **Sdk\toolchains\lib**路径下,该参数不能修改。请注意,该OpenHarmony.p12文件并不是[生成密钥和证书请求文件](#生成密钥和证书请求文件)中生成的.p12文件。 + +- **sigalg**:证书签名算法,该参数不能修改。 + +- **storepass**:密钥库密码,密码为123456,该参数不能修改。 -## 生成应用Profile文件 +- **ext**:证书扩展项,该参数不能修改。 + +- **validity**:证书有效期,自定义天数。 + +- **rfc**:输出文件格式指定,该参数不能修改。 + + +## 生成应用Profile文件 Profile文件包含OpenHarmony应用的包名、数字证书信息、描述应用允许申请的证书权限列表,以及允许应用调试的设备列表(如果应用类型为Release类型,则设备列表为空)等内容,每个应用包中均必须包含一个Profile文件。 -进入**Sdk\\toolchains\\lib**目录下,打开命令行工具,执行如下命令。 +进入 **Sdk\toolchains\lib**目录下,打开命令行工具,执行如下命令。 ``` java -jar provisionsigtool.jar sign --in UnsgnedReleasedProfileTemplate.json --out myApplication_ohos_Provision.p7b --keystore OpenHarmony.p12 --storepass 123456 --alias "OpenHarmony Application Profile Release" --sigAlg SHA256withECDSA --cert OpenHarmonyProfileRelease.pem --validity 365 --developer-id ohosdeveloper --bundle-name 包名 --permission 受限权限名(可选) --permission 受限权限名(可选) --distribution-certificate myApplication_ohos.cer @@ -47,45 +59,62 @@ java -jar provisionsigtool.jar sign --in UnsgnedReleasedProfileTemplate.json --o 关于该命令的参数说明如下: -- **provisionsigtool**:Profile文件生成工具,文件在OpenHarmony SDK的**Sdk\\toolchains\\lib**路径下。 -- **in**:Profile模板文件所在路径,文件在OpenHarmony SDK中**Sdk\\toolchains\\lib**路径下,该参数不能修改。 -- **out**:输出的Profile文件名和路径。 -- **keystore**:签发证书的密钥库路径,OpenHarmony密钥库文件名为OpenHarmony.p12,文件在OpenHarmony SDK中**Sdk\\toolchains\\lib**路径下,该参数不能修改。 -- **storepass**:密钥库密码,密码为123456,该参数不能修改。 -- **alias**:用于签名Profile私钥别名,OpenHarmony社区CA私钥存于OpenHarmony.p12密钥库文件中,该参数不能修改。 -- **sigalg**:证书签名算法,该参数不能修改。 -- **cert**:签名Profile的证书文件路径,文件在OpenHarmony SDK中**Sdk\\toolchains\\lib**路径下,该参数不能修改。 -- **validity**:证书有效期,自定义天数。 -- **developer-id**:开发者标识符,自定义一个字符串。 -- **bundle-name**:填写应用包名。 -- **permission**:可选字段,如果不需要,则可以不用填写此字段;如果需要添加多个受限权限,则如示例所示重复输入。受限权限列表如下:ohos.permission.READ\_CONTACTS、ohos.permission.WRITE\_CONTACTS。 -- **distribution-certificate**:[生成应用证书文件](#section136609429562)中生成的证书文件。 - -## 配置应用签名信息 +- **provisionsigtool**:Profile文件生成工具,文件在OpenHarmony SDK的 **Sdk\toolchains\lib**路径下。 + +- **in**:Profile模板文件所在路径,文件在OpenHarmony SDK中 **Sdk\toolchains\lib**路径下,该参数不能修改。 + +- **out**:输出的Profile文件名和路径。 + +- **keystore**:签发证书的密钥库路径,OpenHarmony密钥库文件名为OpenHarmony.p12,文件在OpenHarmony SDK中 **Sdk\toolchains\lib**路径下,该参数不能修改。 + +- **storepass**:密钥库密码,密码为123456,该参数不能修改。 + +- **alias**:用于签名Profile私钥别名,OpenHarmony社区CA私钥存于OpenHarmony.p12密钥库文件中,该参数不能修改。 + +- **sigalg**:证书签名算法,该参数不能修改。 + +- **cert**:签名Profile的证书文件路径,文件在OpenHarmony SDK中 **Sdk\toolchains\lib**路径下,该参数不能修改。 + +- **validity**:证书有效期,自定义天数。 + +- **developer-id**:开发者标识符,自定义一个字符串。 + +- **bundle-name**:填写应用包名。 + +- **permission**:可选字段,如果不需要,则可以不用填写此字段;如果需要添加多个受限权限,则如示例所示重复输入。受限权限列表如下:ohos.permission.READ_CONTACTS、ohos.permission.WRITE_CONTACTS。 + +- **distribution-certificate**:[生成应用证书文件](#生成应用证书文件)中生成的证书文件。 + + +## 配置应用签名信息 在真机设备上调试前,需要使用到制作的私钥(.p12)文件、证书(.cer)文件和Profile(.p7b)文件对调试的模块进行签名。 -打开**File \> Project Structure**,点击**Project \> Signing Configs \> debug**窗口中,去除勾选“Automatically generate signing”,然后配置指定模块的调试签名信息。 +打开 **File > Project Structure**,点击 **Project > Signing Configs > debug**窗口中,去除勾选“Automatically generate signing”,然后配置指定模块的调试签名信息。 +- **Store File**:选择密钥库文件,文件后缀为.p12,该文件为[生成密钥和证书请求文件](#生成密钥和证书请求文件)中生成的.p12文件。 + +- **Store Password**:输入密钥库密码,该密码为[生成密钥和证书请求文件](#生成密钥和证书请求文件)中填写的密钥库密码保持一致。 + +- **Key Alias**:输入密钥的别名信息,与[生成密钥和证书请求文件](#生成密钥和证书请求文件)中填写的别名保持一致。 -- **Store File**:选择密钥库文件,文件后缀为.p12,该文件为[生成密钥和证书请求文件](#section153146467405)中生成的.p12文件。 -- **Store Password**:输入密钥库密码,该密码为[生成密钥和证书请求文件](#section153146467405)中填写的密钥库密码保持一致。 -- **Key Alias**:输入密钥的别名信息,与[生成密钥和证书请求文件](#section153146467405)中填写的别名保持一致。 -- **Key Password**:输入密钥的密码,与**Store Password**保持一致。 -- **Sign Alg**:签名算法,固定为SHA256withECDSA。 -- **Profile File**:选择[生成应用Profile文件](#section2048641015325)中生成的Profile文件,文件后缀为.p7b。 -- **Certpath File**:选择[生成应用证书文件](#section136609429562)中生成的数字证书文件,文件后缀为.cer。 +- **Key Password**:输入密钥的密码,与 **Store Password**保持一致。 -![](figures/zh-cn_image_0000001155643492.png) +- **Sign Alg**:签名算法,固定为SHA256withECDSA。 -设置完签名信息后,点击**OK**进行保存,然后可以在工程下的build.gradle中查看签名的配置信息。 +- **Profile File**:选择[生成应用Profile文件](#生成应用profile文件)中生成的Profile文件,文件后缀为.p7b。 -![](figures/zh-cn_image_0000001202722349.png) +- **Certpath File**:选择[生成应用证书文件](#生成应用证书文件)中生成的数字证书文件,文件后缀为.cer。 + +![zh-cn_image_0000001155643492](figures/zh-cn_image_0000001155643492.png) + +设置完签名信息后,点击 **OK**进行保存,然后可以在工程下的build.gradle中查看签名的配置信息。 + +![zh-cn_image_0000001202722349](figures/zh-cn_image_0000001202722349.png) 默认情况下,DevEco Studio编译hap包的类型为debug类型,如果需要编译release类型的hap包,请打开工程左下角的OhosBuild Variants,设置模块的编译构建类型为release。关于编译构建hap的详细说明请参考[HUAWEI DevEco Studio使用指南](https://developer.harmonyos.com/cn/docs/documentation/doc-guides/build_hap-0000001053342418)。 -![](figures/zh-cn_image_0000001115066116.png) +![zh-cn_image_0000001115066116](figures/zh-cn_image_0000001115066116.png) 编译完成后,OpenHarmony应用的Hap包可以从工程的bulid目录下获取。 -![](figures/zh-cn_image_0000001163918627.png) - +![zh-cn_image_0000001163918627](figures/zh-cn_image_0000001163918627.png) diff --git a/zh-cn/application-dev/quick-start/configuring-openharmony-sdk.md b/zh-cn/application-dev/quick-start/configuring-openharmony-sdk.md index 7df6f77927e..9bdbfd644c6 100644 --- a/zh-cn/application-dev/quick-start/configuring-openharmony-sdk.md +++ b/zh-cn/application-dev/quick-start/configuring-openharmony-sdk.md @@ -1,193 +1,175 @@ -# 配置OpenHarmony SDK - -- [前提条件](#section164161442154812) -- [配置SDK信息](#section1265592425017) -- [参考信息](#section0384143616409) - - [配置DevEco Studio代理](#section10129720184214) - - [配置NPM代理](#section19984059114316) - - [设置Gradle代理](#section164211820465) +# 配置OpenHarmony SDK +- [前提条件](#前提条件) +- [配置SDK信息](#配置sdk信息) +- [参考信息](#参考信息) + - [配置DevEco Studio代理](#配置deveco-studio代理) + - [配置NPM代理](#配置npm代理) + - [设置Gradle代理](#设置gradle代理) 在设置OpenHarmony应用开发环境时,需要开发者在DevEco Studio中配置对应的SDK信息。 ->![](../public_sys-resources/icon-note.gif) **说明:** ->请注意,OpenHarmony SDK版本精简了部分工具链,因此不适用于HarmonyOS应用开发。 - -## 前提条件 -已下载并安装好DevEco Studio 3.0 Beta1及以上版本,点击[链接下载](https://developer.harmonyos.com/cn/develop/deveco-studio#download)。 - -## 配置SDK信息 +>![icon-note.gif](public_sys-resources/icon-note.gif) **说明:**
+>请注意,OpenHarmony SDK版本精简了部分工具链,因此不适用于HarmonyOS应用开发。 -DevEco Studio通过SDK Manager统一管理SDK及工具链,OpenHarmony包含如下SDK包: - - - - - - - - - - - - - - - - - - -

类别

-

包名

-

说明

-

SDK

-

JS

-

JS语言SDK包。

-

SDK Tool

-

Toolchains

-

SDK工具链,OpenHarmony应用开发必备工具集,包括编译、打包、签名、数据库管理等工具的集合。

-

Previewer

-

OpenHarmony应用预览器,可以在应用开发过程中查看界面UI布局效果。

-
+## 前提条件 -1. 运行已安装的DevEco Studio,首次使用,请选择**Do not import settings**,点击OK。 -2. 进入配置向导页面,设置**npm registry**,DevEco Studio已预置对应的仓,直接点击**Start using DevEco Studio**进入下一步。 +已下载并安装好DevEco Studio 3.0 Beta1及以上版本,点击[链接下载](https://developer.harmonyos.com/cn/develop/deveco-studio#download)。 - >![](../public_sys-resources/icon-note.gif) **说明:** - >如果配置向导界面出现的是设置**Set up HTTP Proxy**界面,说明网络受限,请根据[参考信息](#section0384143616409)配置DevEco Studio代理、NPM代理和Gradle代理后,再下载OpenHarmony SDK。 - ![](figures/zh-cn_image_0000001163314102.png) +## 配置SDK信息 -3. DevEco Studio向导指引开发者下载SDK,默认下载OpenHarmony SDK。SDK下载到user目录下,也可以指定对应的存储路径,SDK存储路径不支持中文字符,然后点击**Next**。 +DevEco Studio通过SDK Manager统一管理SDK及工具链,OpenHarmony包含如下SDK包: - ![](figures/zh-cn_image_0000001208394019.png) +| 类别 | 包名 | 说明 | +| -------- | -------- | -------- | +| SDK | JS | JS语言SDK包。 | +| SDK Tool | Toolchains | SDK工具链,OpenHarmony应用开发必备工具集,包括编译、打包、签名、数据库管理等工具的集合。 | +| | Previewer | OpenHarmony应用预览器,可以在应用开发过程中查看界面UI布局效果。 | - >![](../public_sys-resources/icon-note.gif) **说明:** - >如果不是首次安装DevEco Studio,可能无法查看进入该界面,可通过欢迎页的**Configure (或**![](figures/zh-cn_image_0000001208274069.png)**图标)\> Settings \> SDK Manager \> OpenHarmony SDK**界面,点击**OpenHarmony SDK Location**加载SDK。 +1. 运行已安装的DevEco Studio,首次使用,请选择 **Do not import settings**,点击OK。 -4. 在弹出的SDK下载信息页面,点击**Next**,并在弹出的**License Agreement**窗口,点击**Accept**开始下载SDK。 +2. 进入配置向导页面,设置 **npm registry**,DevEco Studio已预置对应的仓,直接点击 **Start using DevEco Studio**进入下一步。 + > ![icon-note.gif](public_sys-resources/icon-note.gif) **说明:**
+ > 如果配置向导界面出现的是设置 **Set up HTTP Proxy**界面,说明网络受限,请根据[参考信息](#参考信息)配置DevEco Studio代理、NPM代理和Gradle代理后,再下载OpenHarmony SDK。 - >![](../public_sys-resources/icon-note.gif) **说明:** - >下载SDK过程中,如果出现下载JS SDK失败,提示“Install js dependencies failed”,请根据[JS SDK安装失败处理指导](https://developer.harmonyos.com/cn/docs/documentation/doc-guides/faq-development-environment-0000001168829643#section1311117111474)进行处理。 + + ![zh-cn_image_0000001163314102](figures/zh-cn_image_0000001163314102.png) - ![](figures/zh-cn_image_0000001163472654.png) +3. DevEco Studio向导指引开发者下载SDK,默认下载OpenHarmony SDK。SDK下载到user目录下,也可以指定对应的存储路径,SDK存储路径不支持中文字符,然后点击 **Next**。 + ![zh-cn_image_0000001208394019](figures/zh-cn_image_0000001208394019.png) -5. 等待OpenHarmony SDK及工具下载完成,点击**Finish**,界面会进入到DevEco Studio欢迎页。 + > ![icon-note.gif](public_sys-resources/icon-note.gif) **说明:**
+ > 如果不是首次安装DevEco Studio,可能无法查看进入该界面,可通过欢迎页的 **Configure (** **或**![zh-cn_image_0000001208274069](figures/zh-cn_image_0000001208274069.png) **图标** **)> Settings > SDK Manager > OpenHarmony SDK**界面,点击 **OpenHarmony SDK Location**加载SDK。 - ![](figures/zh-cn_image_0000001163632602.png) +4. 在弹出的SDK下载信息页面,点击 **Next**,并在弹出的 **License Agreement**窗口,点击 **Accept**开始下载SDK。 + + + > ![icon-note.gif](public_sys-resources/icon-note.gif) **说明:**
+ > 下载SDK过程中,如果出现下载JS SDK失败,提示“Install js dependencies failed”,请根据[JS SDK安装失败处理指导](https://developer.harmonyos.com/cn/docs/documentation/doc-guides/faq-development-environment-0000001168829643#section1311117111474)进行处理。 + + + ![zh-cn_image_0000001163472654](figures/zh-cn_image_0000001163472654.png) + +5. 等待OpenHarmony SDK及工具下载完成,点击 **Finish**,界面会进入到DevEco Studio欢迎页。 + ![zh-cn_image_0000001163632602](figures/zh-cn_image_0000001163632602.png) -## 参考信息 +## 参考信息 DevEco Studio开发环境需要依赖于网络环境,需要连接上网络才能确保工具的正常使用。 一般来说,如果使用的是个人或家庭网络,是不需要设置代理信息的;只有部分企业网络受限的情况下,才需要设置代理信息。 -如果是第一次打开DevEco Studio,配置向导界面出现设置**Set up HTTP Proxy**界面,说明网络受限,可以通过配置代理的方式来解决,需要配置DevEco Studio代理、NPM代理和Gradle代理。 - -![](figures/zh-cn_image_0000001123021842.png) - -### 配置DevEco Studio代理 - -1. 启动DevEco Studio,配置向导进入**Set up HTTP Proxy**界面,勾选**Manual proxy configuration**,设置DevEco Studio的HTTP Proxy。 - - >![](../public_sys-resources/icon-note.gif) **说明:** - >如果非首次设置向导进入HTTP Proxy,可以通过如下方式进入HTTP Proxy配置界面: - >- 在欢迎页点击**Configure(或**![](figures/zh-cn_image_0000001122862128.png)**图标) \> Settings \> Appearance & Behavior \> System Settings \> HTTP Proxy**进入HTTP Proxy设置界面(Mac系统为**Configure \> Preferences \> Appearance & Behavior \> System Settings \> HTTP Proxy**)。 - >- 在打开了工程的情况下,可以点击**File \> Settings \> Appearance & Behavior \> System Settings \> HTTP Proxy**进入HTTP Proxy设置界面(Mac系统为**DevEco Studio \> Preferences \> Appearance & Behavior \> System Settings \> HTTP Proxy**) +如果是第一次打开DevEco Studio,配置向导界面出现设置 **Set up HTTP Proxy**界面,说明网络受限,可以通过配置代理的方式来解决,需要配置DevEco Studio代理、NPM代理和Gradle代理。 - - **HTTP**配置项,设置代理服务器信息。**如果不清楚代理服务器信息,可以咨询你们的网络管理人员**。 - - **Host name**:代理服务器主机名或IP地址。 - - **Port number**:代理服务器对应的端口号。 - - **No proxy for**:不需要通过代理服务器访问的URL或者IP地址(地址之间用英文逗号分隔)。 +![zh-cn_image_0000001166582138](figures/zh-cn_image_0000001166582138.png) - - **Proxy authentication**配置项,如果代理服务器需要通过认证鉴权才能访问,则需要设置。否则,请跳过该配置项。 - - **Login**:访问代理服务器的用户名。 - - **Password**:访问代理服务器的密码。 - - **Remember**:勾选,记住密码。 - ![](figures/zh-cn_image_0000001123021962.png) +### 配置DevEco Studio代理 -2. 配置完成后,点击**Check connection**,输入网络地址(如:https://developer.harmonyos.com),检查网络连通性。提示“Connection successful“表示代理设置成功。 -3. 点击**Next: Configure npm**继续设置NPM代理信息,请参考[配置NPM代理](#section19984059114316)。 +1. 启动DevEco Studio,配置向导进入 **Set up HTTP Proxy**界面,勾选 **Manual proxy configuration**,设置DevEco Studio的HTTP Proxy。 + > ![icon-note.gif](public_sys-resources/icon-note.gif) **说明:**
+ > 如果非首次设置向导进入HTTP Proxy,可以通过如下方式进入HTTP Proxy配置界面: + > + > - 在欢迎页点击 **Configure(或**![zh-cn_image_0000001212142015](figures/zh-cn_image_0000001212142015.png) **图标) > Settings > Appearance & Behavior > System Settings > HTTP Proxy**进入HTTP Proxy设置界面(Mac系统为 **Configure > Preferences > Appearance & Behavior > System Settings > HTTP Proxy**)。 + > + > - 在打开了工程的情况下,可以点击 **File > Settings > Appearance & Behavior > System Settings > HTTP Proxy**进入HTTP Proxy设置界面(Mac系统为 **DevEco Studio > Preferences > Appearance & Behavior > System Settings > HTTP Proxy**) -### 配置NPM代理 + - **HTTP**配置项,设置代理服务器信息。 **如果不清楚代理服务器信息,可以咨询你们的网络管理人员**。 + - **Host name**:代理服务器主机名或IP地址。 + - **Port number**:代理服务器对应的端口号。 + - **No proxy for**:不需要通过代理服务器访问的URL或者IP地址(地址之间用英文逗号分隔)。 + - **Proxy authentication**配置项,如果代理服务器需要通过认证鉴权才能访问,则需要设置。否则,请跳过该配置项。 + - **Login**:访问代理服务器的用户名。 + - **Password**:访问代理服务器的密码。 + - **Remember**:勾选,记住密码。 + ![zh-cn_image_0000001212062065](figures/zh-cn_image_0000001212062065.png) -通过DevEco Studio的设置向导设置NPM代理信息,代理信息将写入用户“users/用户名/”目录下的**.npmrc**文件。 +2. 配置完成后,点击 **Check connection**,输入网络地址(如:https://developer.harmonyos.com),检查网络连通性。提示Connection successful表示代理设置成功。 ->![](../public_sys-resources/icon-note.gif) **说明:** ->该向导只有第一次安装DevEco Studio才会出现。如果未出现该向导,可以直接在“users/用户名/”目录下的**.npmrc**文件中,添加代理配置信息。 +3. 点击 **Next: Configure npm**继续设置NPM代理信息,请参考[配置NPM代理](#配置npm代理)。 -- npm registry:设置npm仓的地址信息,建议勾选。 -- HTTP proxy:代理服务器信息,默认会与DevEco Studio的HTTP proxy设置项保持一致。 -- Enable Https Proxy:同步设置HTTPS Proxy配置信息,建议勾选。 -![](figures/zh-cn_image_0000001164577336.png) +### 配置NPM代理 -然后点击**Start using DevEco Studio**继续下一步操作。 +通过DevEco Studio的设置向导设置NPM代理信息,代理信息将写入用户“users/用户名/”目录下的 **.npmrc**文件。 +> ![icon-note.gif](public_sys-resources/icon-note.gif) **说明:**
+> 该向导只有第一次安装DevEco Studio才会出现。如果未出现该向导,可以直接在“users/用户名/”目录下的 **.npmrc**文件中,添加代理配置信息。 -如果代理服务器需要认证(需要用户名和密码),请先根据如下指导配置代理服务器的用户名和密码信息,然后再下载OpenHarmony SDK;否则,请跳过该操作,参考[配置SDK信息](#section1265592425017)进行操作即可。 +- npm registry:设置npm仓的地址信息,建议勾选。 -![](figures/zh-cn_image_0000001209817299.png) +- HTTP proxy:代理服务器信息,默认会与DevEco Studio的HTTP proxy设置项保持一致。 -1. 进入用户的users目录,打开**.npmrc**文件。 -2. 修改npm代理信息,在proxy和https-proxy中,增加user和password字段,具体取值请以实际代理信息为准。示例如下所示: +- Enable Https Proxy:同步设置HTTPS Proxy配置信息,建议勾选。 - ``` - proxy=http://user:password@proxy.server.com:80 - https-proxy=http://user:password@proxy.server.com:80 - ``` +![zh-cn_image_0000001164577336](figures/zh-cn_image_0000001164577336.png) - >![](../public_sys-resources/icon-note.gif) **说明:** - >如果password中存在特殊字符,如@、\#、\*等符号,可能导致配置不生效,建议将特殊字符替换为ASCII码,并在ASCII码前加百分号%。常用符号替换为ASCII码对照表如下: - >- !:%21 - >- @:%40 - >- \#:%23 - >- ¥:%24 - >- &:%26 - >- \*:%2A +然后点击 **Start using DevEco Studio**继续下一步操作。 -3. 代理设置完成后,打开命令行工具,执行如下命令进行验证网络是否正常。 +如果代理服务器需要认证(需要用户名和密码),请先根据如下指导配置代理服务器的用户名和密码信息,然后再下载OpenHarmony SDK;否则,请跳过该操作,参考[配置SDK信息](#配置sdk信息)进行操作即可。 - ``` - npm info express - ``` +![zh-cn_image_0000001209817299](figures/zh-cn_image_0000001209817299.png) - 执行结果如下图所示,则说明代理设置成功。 +1. 进入用户的users目录,打开 **.npmrc**文件。 - ![](figures/zh-cn_image_0000001164417356.png) +2. 修改npm代理信息,在proxy和https-proxy中,增加user和password字段,具体取值请以实际代理信息为准。示例如下所示: + ``` + proxy=http://user:password@proxy.server.com:80 + https-proxy=http://user:password@proxy.server.com:80 + ``` -4. 网络设置完成后,然后再[配置SDK信息](#section1265592425017)。 + > ![icon-note.gif](public_sys-resources/icon-note.gif) **说明:**
+ > 如果password中存在特殊字符,如\@、\#、\*等符号,可能导致配置不生效,建议将特殊字符替换为ASCII码,并在ASCII码前加百分号%。常用符号替换为ASCII码对照表如下: + > + > - !:%21 + > + > - \@:%40 + > + > - \#:%23 + > + > - ¥:%24 + > + > - &:%26 + > + > - \*:%2A -### 设置Gradle代理 +3. 代理设置完成后,打开命令行工具,执行如下命令进行验证网络是否正常。 + ``` + npm info express + ``` -1. 打开“此电脑”,在文件夹地址栏中输入**%userprofile%**(Mac系统请点击**前往 \> 个人**),进入个人用户文件夹。 + 执行结果如下图所示,则说明代理设置成功。 - ![](figures/zh-cn_image_0000001123024482.png) + ![zh-cn_image_0000001164417356](figures/zh-cn_image_0000001164417356.png) -2. 创建一个文件夹,命名为**.gradle**。如果已有.gradle文件夹,请跳过此操作。 +4. 网络设置完成后,然后再[配置SDK信息](#配置sdk信息)。 - >![](../public_sys-resources/icon-note.gif) **说明:** - >macOS系统创建.gradle文件夹前,请将系统设置为“显示隐藏文件”。 -3. 进入.gradle文件夹,新建一个文本文档,命名为**gradle**,并修改后缀为**.properties**。 -4. 打开**gradle.properties**文件中,添加如下脚本,然后保存。 +### 设置Gradle代理 - 其中代理服务器、端口、用户名、密码和不使用代理的域名,请根据实际代理情况进行修改。其中不使用代理的“nonProxyHosts“的配置间隔符是 “|”。 +1. 打开“此电脑”,在文件夹地址栏中输入 **%userprofile%**(Mac系统请点击 **前往 > 个人**),进入个人用户文件夹。 + ![zh-cn_image_0000001166740700](figures/zh-cn_image_0000001166740700.png) - ``` - systemProp.http.proxyHost=proxy.server.com - systemProp.http.proxyPort=8080 - systemProp.http.nonProxyHosts=*.company.com|10.*|100.* - systemProp.http.proxyUser=userId - systemProp.http.proxyPassword=password - systemProp.https.proxyHost=proxy.server.com - systemProp.https.proxyPort=8080 - systemProp.https.nonProxyHosts=*.company.com|10.*|100.* - systemProp.https.proxyUser=userId - systemProp.https.proxyPassword=password - ``` +2. 创建一个文件夹,命名为 **.gradle**。如果已有.gradle文件夹,请跳过此操作。 + > ![icon-note.gif](public_sys-resources/icon-note.gif) **说明:**
+ > macOS系统创建.gradle文件夹前,请将系统设置为“显示隐藏文件”。 +3. 进入.gradle文件夹,新建一个文本文档,命名为 **gradle**,并修改后缀为 **.properties**。 +4. 打开 **gradle.properties**文件中,添加如下脚本,然后保存。 + 其中代理服务器、端口、用户名、密码和不使用代理的域名,请根据实际代理情况进行修改。其中不使用代理的nonProxyHosts的配置间隔符是 “|”。 + ``` + systemProp.http.proxyHost=proxy.server.com + systemProp.http.proxyPort=8080 + systemProp.http.nonProxyHosts=*.company.com|10.*|100.* + systemProp.http.proxyUser=userId + systemProp.http.proxyPassword=password + systemProp.https.proxyHost=proxy.server.com + systemProp.https.proxyPort=8080 + systemProp.https.nonProxyHosts=*.company.com|10.*|100.* + systemProp.https.proxyUser=userId + systemProp.https.proxyPassword=password + ``` diff --git a/zh-cn/application-dev/quick-start/create-openharmony-project.md b/zh-cn/application-dev/quick-start/create-openharmony-project.md index 2ba5f2d1ba8..106f04c6879 100644 --- a/zh-cn/application-dev/quick-start/create-openharmony-project.md +++ b/zh-cn/application-dev/quick-start/create-openharmony-project.md @@ -1,7 +1,6 @@ -# 创建OpenHarmony工程 +# 创建OpenHarmony工程 -- **[使用工程向导创建新工程](use-wizard-to-create-project.md)** - -- **[通过导入Sample方式创建新工程](import-sample-to-create-project.md)** +- **[使用工程向导创建新工程](use-wizard-to-create-project.md)** +- **[通过导入Sample方式创建新工程](import-sample-to-create-project.md)** \ No newline at end of file diff --git a/zh-cn/application-dev/quick-start/deveco-studio-overview.md b/zh-cn/application-dev/quick-start/deveco-studio-overview.md index 40d3d26d1cb..9c22a824ee5 100644 --- a/zh-cn/application-dev/quick-start/deveco-studio-overview.md +++ b/zh-cn/application-dev/quick-start/deveco-studio-overview.md @@ -1,100 +1,48 @@ -# 概述 +# 概述 -- [总体说明](#section189422248491) -- [使用约束](#section65191625782) -- [DevEco Studio演进路标](#section187875207166) +- [总体说明](#总体说明) +- [使用约束](#使用约束) +- [DevEco Studio演进路标](#deveco-studio演进路标) -## 总体说明 +## 总体说明 -DevEco Studio是HarmonyOS的配套的开发IDE,因为HarmonyOS是基于OpenHarmony开发的,因此,使用DevEco Studio(配套HarmonyOS)也可以进行OpenHarmony的应用开发。 +DevEco Studio 是 HarmonyOS 的配套的开发 IDE ,因为HarmonyOS 是基于OpenHarmony 开发的,因此,使用 DevEco Studio (配套 HarmonyOS )也可以进行 OpenHarmony 的应用开发。 使用DevEco Studio开发OpenHarmony应用的流程与开发HarmonyOS的流程完全一样,本文档仅描述OpenHarmony应用开发与HarmonyOS应用开发的差异点。 -- **搭建开发环境差异**:OpenHarmony应用开发环境需要先安装OpenHarmony SDK,具体可参考[配置OpenHarmony SDK](configuring-openharmony-sdk.md)章节。 -- **导入OpenHarmony工程**:OpenHarmony应用开发,只能通过导入Sample工程的方式来创建一个新工程,具体可参考[通过导入Sample方式创建新工程](import-sample-to-create-project.md)。 -- **调试签名配置**:OpenHarmony应用运行在真机设备上,需要对应用进行签名,关于OpenHarmony应用的签名指导请参考[配置OpenHarmony应用签名信息](configuring-openharmony-app-signature.md)。 -- **在真机设备上运行应用**:需要使用hdc工具将OpenHarmony的hap包推送到真机设备上进行安装,具体可参考[安装运行OpenHarmony应用](installing-openharmony-app.md)。 +- **搭建开发环境差异**:OpenHarmony应用开发环境需要先安装OpenHarmony SDK,具体可参考[配置OpenHarmony SDK](../quick-start/configuring-openharmony-sdk.md)章节。 + +- **导入OpenHarmony工程**:OpenHarmony应用开发,只能通过导入Sample工程的方式来创建一个新工程,具体可参考[通过导入Sample方式创建新工程](../quick-start/import-sample-to-create-project.md)。 + +- **调试签名配置**:OpenHarmony应用运行在真机设备上,需要对应用进行签名,关于OpenHarmony应用的签名指导请参考[配置OpenHarmony应用签名信息](../quick-start/configuring-openharmony-app-signature.md)。 + +- **在真机设备上运行应用**:需要使用hdc工具将OpenHarmony的hap包推送到真机设备上进行安装,具体可参考[安装运行OpenHarmony应用](../quick-start/installing-openharmony-app.md)。 关于DevEco Studio的详细操作指导,请访问[HUAWEI DevEco Studio使用指南](https://developer.harmonyos.com/cn/docs/documentation/doc-guides/tools_overview-0000001053582387)。 -## 使用约束 -- OpenHarmony只支持使用JS语言开发应用,不支持Java、C/C++语言。 -- OpenHarmony开发环境DevEco Studio暂只支持Windows系统。 +## 使用约束 + +- OpenHarmony只支持使用JS语言开发应用,不支持Java、C/C++语言。 + +- OpenHarmony开发环境DevEco Studio暂只支持Windows系统。 OpenHarmony与HarmonyOS的开发工具都是DevEco Studio,下表为OpenHarmony相比HarmonyOS不支持的功能说明: - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

特性名称

-

HarmonyOS版本

-

OpenHarmony版本

-

创建Module

-

-

X

-

服务卡片

-

-

X

-

自动化签名

-

-

X

-

远程模拟器

-

-

X

-

本地模拟器

-

-

X

-

使用DevEco Studio运行调试、日志查看、调优

-

-

X

-

云测试

-

-

X

-

安全测试

-

-

X

-
- -## DevEco Studio演进路标 +| 特性名称 | HarmonyOS版本 | OpenHarmony版本 | +| -------- | -------- | -------- | +| 创建Module | **√** | **X** | +| 服务卡片 | **√** | **X** | +| 自动化签名 | **√** | **X** | +| 远程模拟器 | **√** | **X** | +| 本地模拟器 | **√** | **X** | +| 使用DevEco Studio运行调试、日志查看、调优 | **√** | **X** | +| 云测试 | **√** | **X** | +| 安全测试 | **√** | **X** | -Huawei DevEco Studio分阶段支持OpenHarmony应用开发的演进路标如下: -![](figures/zh-cn_image_0000001210018359.png) +## DevEco Studio演进路标 + +Huawei DevEco Studio分阶段支持OpenHarmony应用开发的演进路标如下: +![zh-cn_image_0000001210018359](figures/zh-cn_image_0000001210018359.png) diff --git a/zh-cn/application-dev/quick-start/deveco-studio-release-notes.md b/zh-cn/application-dev/quick-start/deveco-studio-release-notes.md index d37efb01603..d0bd3eb6e1c 100644 --- a/zh-cn/application-dev/quick-start/deveco-studio-release-notes.md +++ b/zh-cn/application-dev/quick-start/deveco-studio-release-notes.md @@ -1,15 +1,9 @@ -# 版本变更说明 +# 版本变更说明 -- [V3.0 Beta1(2021-09-29)](#section21092033115018) +- [V3.0 Beta1(2021-09-29)](#v3-0-beta1-2021-09-29-) -## V3.0 Beta1(2021-09-29) - - - - -
新增特性:
  • 新增支持OpenHarmony SDK的管理,开发者可通过DevEco Studio的SDK Manager功能来下载和管理OpenHarmony SDK。
  • 在编译构建HAP包时,新增支持对单个Module进行编译,对于多Module工程中只需要编译其中一个Module的场景,可以提升编译构建速度;同时还新增支持一键重构建HAP包,即在编译构建HAP前,会自动执行Clean Project操作。
-
-
增强特性:
  • 编译构建插件更新至3.0.3.2版本。
  • Json编辑器增强,资源索引错误支持快速修复,并支持快速查看资源的取值。
  • 工程视图支持Ohos视图,默认视图为Project视图,开发者可手动切换。
  • OpenHarmony工程支持ark方舟编译。
  • OpenHarmony工程类型标识字段supportSystem "standard",由模块级build.gradle调整至工程级build.gradle。
-
-
+## V3.0 Beta1(2021-09-29) +| | +| -------- | +|  **新增特性:**
- 新增支持OpenHarmony SDK的管理,开发者可通过DevEco Studio的SDK Manager功能来下载和管理OpenHarmony SDK。
- 在编译构建HAP包时,新增支持对单个Module进行编译,对于多Module工程中只需要编译其中一个Module的场景,可以提升编译构建速度;同时还新增支持一键重构建HAP包,即在编译构建HAP前,会自动执行Clean Project操作。
 **增强特性:**
- 编译构建插件更新至3.0.3.2版本。
- Json编辑器增强,资源索引错误支持快速修复,并支持快速查看资源的取值。
- 工程视图支持Ohos视图,默认视图为Project视图,开发者可手动切换。
- OpenHarmony工程支持ark方舟编译。
- OpenHarmony工程类型标识字段supportSystem "standard",由模块级build.gradle调整至工程级build.gradle。 | diff --git a/zh-cn/application-dev/quick-start/deveco-studio-user-guide-for-openharmony.md b/zh-cn/application-dev/quick-start/deveco-studio-user-guide-for-openharmony.md index 53fda8d36d3..2afa5a6c8bc 100644 --- a/zh-cn/application-dev/quick-start/deveco-studio-user-guide-for-openharmony.md +++ b/zh-cn/application-dev/quick-start/deveco-studio-user-guide-for-openharmony.md @@ -1,15 +1,14 @@ -# DevEco Studio(OpenHarmony)使用指南 +# DevEco Studio(OpenHarmony)使用指南 -- **[概述](deveco-studio-overview.md)** -- **[版本变更说明](deveco-studio-release-notes.md)** +- **[概述](deveco-studio-overview.md)** -- **[配置OpenHarmony SDK](configuring-openharmony-sdk.md)** +- **[版本变更说明](deveco-studio-release-notes.md)** -- **[创建OpenHarmony工程](create-openharmony-project.md)** +- **[配置OpenHarmony SDK](configuring-openharmony-sdk.md)** -- **[配置OpenHarmony应用签名信息](configuring-openharmony-app-signature.md)** - -- **[安装运行OpenHarmony应用](installing-openharmony-app.md)** +- **[创建OpenHarmony工程](create-openharmony-project.md)** +- **[配置OpenHarmony应用签名信息](configuring-openharmony-app-signature.md)** +- **[安装运行OpenHarmony应用](installing-openharmony-app.md)** \ No newline at end of file diff --git a/zh-cn/application-dev/quick-start/figures/1-0.png b/zh-cn/application-dev/quick-start/figures/1-0.png deleted file mode 100644 index 7ff0d06f4af8d0cfe137995d5c37c661cff3887c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3725 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 diff --git a/zh-cn/application-dev/quick-start/figures/page-ability-lifecycle.png b/zh-cn/application-dev/quick-start/figures/page-ability-lifecycle.png deleted file mode 100644 index d4fff2a49bf103cb5d8763f271c847fc1b711723..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 14658 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 CHLaNd literal 0 HcmV?d00001 diff --git a/zh-cn/application-dev/quick-start/figures/3.png b/zh-cn/application-dev/quick-start/figures/zh-cn_image_0000001166904552.png old mode 100755 new mode 100644 similarity index 100% rename from zh-cn/application-dev/quick-start/figures/3.png rename to zh-cn/application-dev/quick-start/figures/zh-cn_image_0000001166904552.png diff --git a/zh-cn/application-dev/quick-start/figures/2.png b/zh-cn/application-dev/quick-start/figures/zh-cn_image_0000001166904582.png old mode 100755 new mode 100644 similarity index 100% rename from zh-cn/application-dev/quick-start/figures/2.png rename to zh-cn/application-dev/quick-start/figures/zh-cn_image_0000001166904582.png diff --git a/zh-cn/application-dev/quick-start/figures/zh-cn_image_0000001123021962.png b/zh-cn/application-dev/quick-start/figures/zh-cn_image_0000001212062065.png similarity index 100% rename from zh-cn/application-dev/quick-start/figures/zh-cn_image_0000001123021962.png rename to zh-cn/application-dev/quick-start/figures/zh-cn_image_0000001212062065.png diff --git a/zh-cn/application-dev/quick-start/figures/1.png b/zh-cn/application-dev/quick-start/figures/zh-cn_image_0000001212066021.png old mode 100755 new mode 100644 similarity index 100% rename from zh-cn/application-dev/quick-start/figures/1.png rename to zh-cn/application-dev/quick-start/figures/zh-cn_image_0000001212066021.png diff --git a/zh-cn/application-dev/quick-start/figures/zh-cn_image_0000001122862128.png b/zh-cn/application-dev/quick-start/figures/zh-cn_image_0000001212142015.png similarity index 100% rename from zh-cn/application-dev/quick-start/figures/zh-cn_image_0000001122862128.png rename to zh-cn/application-dev/quick-start/figures/zh-cn_image_0000001212142015.png diff --git a/zh-cn/application-dev/quick-start/import-sample-to-create-project.md b/zh-cn/application-dev/quick-start/import-sample-to-create-project.md index 1c031207ad2..ee58adb9471 100644 --- a/zh-cn/application-dev/quick-start/import-sample-to-create-project.md +++ b/zh-cn/application-dev/quick-start/import-sample-to-create-project.md @@ -1,33 +1,26 @@ -# 通过导入Sample方式创建新工程 +# 通过导入Sample方式创建新工程 ->![](../public_sys-resources/icon-note.gif) **说明:** ->该功能适用于通过DevEco Studio 2.1 Release及以上版本,创建OpenHarmony工程。 +> ![icon-note.gif](public_sys-resources/icon-note.gif) **说明:** +> 该功能适用于通过DevEco Studio 2.1 Release及以上版本,创建OpenHarmony工程。 -OpenHarmony SDK配置完成后,便可以启动应用开发。针对OpenHarmony应用开发,**可以通过导入Sample工程的方式来创建一个新工程**。 -1. 在DevEco Studio的欢迎页,进入**Configure (或**![](figures/zh-cn_image_0000001118018452.png)**图标) \> Settings \> Version Control \> Git**界面,点击Test按钮检测是否安装Git工具。 - - 已安装,请根据[2](#li5947194711181)开始导入Sample。 +OpenHarmony SDK配置完成后,便可以启动应用开发。针对OpenHarmony应用开发, **可以通过导入Sample工程的方式来创建一个新工程**。 - ![](figures/zh-cn_image_0000001118018088.png) - - 未安装,请点击**Download and Install**,DevEco Studio会自动下载并安装。安装完成后,请根据[2](#li5947194711181)开始导入Sample。 +1. 在DevEco Studio的欢迎页,进入 **Configure (** **或**![zh-cn_image_0000001118018452](figures/zh-cn_image_0000001118018452.png) **图标** **) > Settings > Version Control > Git**界面,点击Test按钮检测是否安装Git工具。 + - 已安装,请根据**步骤2**开始导入Sample。 + ![zh-cn_image_0000001118018088](figures/zh-cn_image_0000001118018088.png) + - 未安装,请点击 **Download and Install**,DevEco Studio会自动下载并安装。安装完成后,请根据**步骤2**开始导入Sample。 + ![zh-cn_image_0000001164498191](figures/zh-cn_image_0000001164498191.png) - ![](figures/zh-cn_image_0000001164498191.png) +2. 在DevEco Studio的欢迎页,点击 **Import Sample**按钮,导入Sample工程。 + ![zh-cn_image_0000001208006117](figures/zh-cn_image_0000001208006117.png) -2. 在DevEco Studio的欢迎页,点击**Import Sample**按钮,导入Sample工程。 - - ![](figures/zh-cn_image_0000001208006117.png) - -3. 选择OpenHarmony Samples \> common下的**JsHelloWorld**工程,然后点击**Next**。 - - ![](figures/zh-cn_image_0000001152459178.png) - -4. 设置**App Name**和**Project Location**,然后点击**Finish**,等待Sample工程导入完成。 - - ![](figures/zh-cn_image_0000001207744539.png) - -5. 等待工程同步完成,同步成功后,便可以进行OpenHarmony应用开发了。 - - ![](figures/zh-cn_image_0000001163915523.png) +3. 选择OpenHarmony Samples > common下的 **JsHelloWorld**工程,然后点击 **Next**。 + ![zh-cn_image_0000001152459178](figures/zh-cn_image_0000001152459178.png) +4. 设置 **App Name**和 **Project Location**,然后点击 **Finish**,等待Sample工程导入完成。 + ![zh-cn_image_0000001207744539](figures/zh-cn_image_0000001207744539.png) +5. 等待工程同步完成,同步成功后,便可以进行OpenHarmony应用开发了。 + ![zh-cn_image_0000001163915523](figures/zh-cn_image_0000001163915523.png) diff --git a/zh-cn/application-dev/quick-start/installing-openharmony-app.md b/zh-cn/application-dev/quick-start/installing-openharmony-app.md index 8e921c8ce2f..d7ece1e0766 100644 --- a/zh-cn/application-dev/quick-start/installing-openharmony-app.md +++ b/zh-cn/application-dev/quick-start/installing-openharmony-app.md @@ -1,41 +1,41 @@ -# 安装运行OpenHarmony应用 +# 安装运行OpenHarmony应用 安装OpenHarmony应用需要使用hdc工具,通过手动执行命令行完成应用的安装。 -hdc工具本身需要手动从开源仓中获取。然后使用工具将编译后的hap包发送至设备侧,然后通过hdc命令完成app的安装。 -相关命令如下: +hdc工具本身需要手动从开源仓中获取。然后使用工具将编译后的hap包发送至设备侧,然后通过hdc命令完成app的安装。 -- 文件发送命令 - **file send _localpath remotepath_** +相关命令如下: - 命令示例: - ``` - hdc_std file send E:\hwadmin.hap /data/local/tmp/hwadmin.hap - ``` +- 文件发送命令 + **file send *localpath remotepath*** -- 安装命令 + 命令示例: - **install \[-r/-d/-g\] _package_** + ``` + hdc_std file send E:\hwadmin.hap /data/local/tmp/hwadmin.hap + ``` - 命令示例: +- 安装命令 + **install [-r/-d/-g] *package*** - ``` - hdc_std install hwadmin.hap - ``` + 命令示例: -- 日志抓取命令 + ``` + hdc_std install hwadmin.hap + ``` - **hilog** +- 日志抓取命令 + **hilog** - 命令示例: + 命令示例: - ``` - hdc_std hilog - ``` + ``` + hdc_std hilog + ``` -完整的hdc工具使用指导及命令格式请参见开源仓“docs/zh-cn/device-dev/subsystems/hdc使用指导.md“。 +完整的hdc工具使用指导及命令格式请参见开源仓”docs/zh-cn/device-dev/subsystems/hdc使用指导.md“。 diff --git a/zh-cn/application-dev/quick-start/package-structure.md b/zh-cn/application-dev/quick-start/package-structure.md index 94c83987ac6..21eb8417d4d 100644 --- a/zh-cn/application-dev/quick-start/package-structure.md +++ b/zh-cn/application-dev/quick-start/package-structure.md @@ -1,9 +1,11 @@ -# 包结构说明 +# 包结构说明 在应用开发的工程中,需要在config.json配置文件中对应用的包结构进行声明。 + 配置文件示例如下: + ``` { "app": { @@ -67,9 +69,12 @@ } ``` + **包结构声明需要注意以下约束:** -- "package"字段命名要保证在相同bundleName的应用内唯一。 -- "abilities"字段下只能声明一个ability。 -- "abilities"字段中ability的"name"字段命名要保证在相同bundleName的应用内唯一。 +- "package"字段命名要保证在相同bundleName的应用内唯一。 + +- "abilities"字段下只能声明一个ability。 + +- "abilities"字段中ability的"name"字段命名要保证在相同bundleName的应用内唯一。 diff --git a/zh-cn/application-dev/quick-start/public_sys-resources/icon-caution.gif b/zh-cn/application-dev/quick-start/public_sys-resources/icon-caution.gif new file mode 100644 index 0000000000000000000000000000000000000000..6e90d7cfc2193e39e10bb58c38d01a23f045d571 GIT binary patch literal 580 zcmV-K0=xZ3Nk%w1VIu$?0Hp~4{QBgqmQ+MG9K51r{QB&)np^||1PlfQ%(86!{`~yv zv{XhUWKt}AZaiE{EOcHp{O-j3`t;<+eEiycJT4p@77X;(jQsMfB$R?oG%6hQ z+MMLZbQBH@)Vg&1^3?qHb(5!%>3r0+`eq=&V&E}0Dypi0000000000 z00000A^8LW000R9EC2ui03!e$000L5z=Uu}ED8YtqjJd<+B}(9bIOb$3-31_h|V>=0A{ z1Hh0#H30>fNT})^fRU_83uewx9oRr{f{Sx1Ml`t)EQ zGkHZ67&~y{W5Jpq4H_WfuLxp*3<7O}GEl;1ESe36fLNs=B0&LQM1Buf(R)qg(BRd`t1OPjI1m_q4 literal 0 HcmV?d00001 diff --git a/zh-cn/application-dev/quick-start/public_sys-resources/icon-danger.gif b/zh-cn/application-dev/quick-start/public_sys-resources/icon-danger.gif new file mode 100644 index 0000000000000000000000000000000000000000..6e90d7cfc2193e39e10bb58c38d01a23f045d571 GIT binary patch literal 580 zcmV-K0=xZ3Nk%w1VIu$?0Hp~4{QBgqmQ+MG9K51r{QB&)np^||1PlfQ%(86!{`~yv zv{XhUWKt}AZaiE{EOcHp{O-j3`t;<+eEiycJT4p@77X;(jQsMfB$R?oG%6hQ z+MMLZbQBH@)Vg&1^3?qHb(5!%>3r0+`eq=&V&E}0Dypi0000000000 z00000A^8LW000R9EC2ui03!e$000L5z=Uu}ED8YtqjJd<+B}(9bIOb$3-31_h|V>=0A{ z1Hh0#H30>fNT})^fRU_83uewx9oRr{f{Sx1Ml`t)EQ zGkHZ67&~y{W5Jpq4H_WfuLxp*3<7O}GEl;1ESe36fLNs=B0&LQM1Buf(R)qg(BRd`t1OPjI1m_q4 literal 0 HcmV?d00001 diff --git a/zh-cn/application-dev/quick-start/public_sys-resources/icon-note.gif b/zh-cn/application-dev/quick-start/public_sys-resources/icon-note.gif new file mode 100644 index 0000000000000000000000000000000000000000..6314297e45c1de184204098efd4814d6dc8b1cda GIT binary patch literal 394 zcmZ?wbhEHblx7fPSjxcg=ii?@_wH=jwxy=7CMGH-B`L+l$wfv=#>UF#$gv|VY%C^b zCQFtrnKN(Bo_%|sJbO}7RAORe!otL&qo<>yq_Sq+8Xqqo5h0P3w3Lvb5E(g{p01vl zxR@)KuDH0l^z`+-dH3eaw=XqSH7aTIx{kzVBN;X&hha0dQSgWuiw0NWUvMRmkD|> literal 0 HcmV?d00001 diff --git a/zh-cn/application-dev/quick-start/public_sys-resources/icon-notice.gif b/zh-cn/application-dev/quick-start/public_sys-resources/icon-notice.gif new file mode 100644 index 0000000000000000000000000000000000000000..86024f61b691400bea99e5b1f506d9d9aef36e27 GIT binary patch literal 406 zcmV;H0crk6Nk%w1VIu$@0J8u9|NsB@_xJDb@8;&_*4Ea}&d#;9wWXz{jEszHYim+c zQaU<1At50E0000000000A^8Le000gEEC2ui03!e%000R7038S%NU)&51O^i-Tu6`s z0)`MFE@;3YqD6xSC^kTNu_J>91{PH8XfZ(p1pp2-SU@u3#{mEUC}_}tg3+I#{z}{Ok@D_ZUDg- zt0stin4;pC8M{WLSlRH*1pzqEw1}3oOskyNN?j;7HD{BBZ*OEcv4HK!6Bk6beR+04 z&8}k>SkTusVTDmkyOz#5fCA$JTPGJVQvr3uZ?QzzPQFvD0rGf_PdrcF`pMs}p^BcF zKtKTd`0wipR%nKN&Wj+V}pX;WC3SdJV!a_8Qi zE7z`U*|Y^H0^}fB$R?oG%6hQ z+MMLZbQBH@)Vg&1^3?qHb(5!%>3r0+`eq=&V&E}0Dypi0000000000 z00000A^8LW000R9EC2ui03!e$000L5z=Uu}ED8YtqjJd<+B}(9bIOb$3-31_h|V>=0A{ z1Hh0#H30>fNT})^fRU_83uewx9oRr{f{Sx1Ml`t)EQ zGkHZ67&~y{W5Jpq4H_WfuLxp*3<7O}GEl;1ESe36fLNs=B0&LQM1Buf(R)qg(BRd`t1OPjI1m_q4 literal 0 HcmV?d00001 diff --git a/zh-cn/application-dev/quick-start/start-overview.md b/zh-cn/application-dev/quick-start/start-overview.md index 664004226b2..85d00dcd6ce 100644 --- a/zh-cn/application-dev/quick-start/start-overview.md +++ b/zh-cn/application-dev/quick-start/start-overview.md @@ -1,23 +1,26 @@ -# 开发准备 +# 开发准备 -- [任务说明](#section2073881513322) -- [开发准备](#section11843205017326) +- [任务说明](#任务说明) +- [开发准备](#开发准备) -## 任务说明 +## 任务说明 本文档适用于OpenHarmony应用开发的初学者。通过构建一个简单的具有页面跳转功能的应用(如下图[预览器](https://developer.harmonyos.com/cn/docs/documentation/doc-guides/previewer-0000001054328973#ZH-CN_TOPIC_0000001056725592__section16523172216252)运行效果所示),熟悉OpenHarmony应用开发流程。 -为确保运行效果,请使用最新版本的**DevEco Studio**完成本任务,点击[此处](https://developer.harmonyos.com/cn/develop/deveco-studio#download)获取下载链接。 +为确保运行效果,请使用最新版本的 **DevEco Studio**完成本任务,点击[此处](https://developer.harmonyos.com/cn/develop/deveco-studio#download)获取下载链接。 -![](figures/3.png) +![zh-cn_image_0000001166904552](figures/zh-cn_image_0000001166904552.png) -## 开发准备 -1. 开始前请参考[配置OpenHarmony SDK](configuring-openharmony-sdk.md),完成**DevEco Studio**的安装和开发环境配置。 -2. 开发环境配置完成后,请参考[创建OpenHarmony工程](use-wizard-to-create-project.md)创建工程。 - - 使用JS语言开发,模板选择“Empty Ability“,Language选择Js。 -3. 工程创建完成后,使用[预览器](https://developer.harmonyos.com/cn/docs/documentation/doc-guides/previewer-0000001054328973#ZH-CN_TOPIC_0000001056725592__section16523172216252)或[模拟器](https://developer.harmonyos.com/cn/docs/documentation/doc-guides/run_simulator-0000001053303709)运行该工程。 +## 开发准备 -完成上述操作后,请参考[使用JS语言开发](start-with-js.md)继续下一步的学习。 +1. 开始前请参考[配置OpenHarmony SDK](../quick-start/configuring-openharmony-sdk.md),完成 **DevEco Studio**的安装和开发环境配置。 +2. 开发环境配置完成后,请参考[创建OpenHarmony工程](../quick-start/use-wizard-to-create-project.md)创建工程。 + - 使用JS语言开发,模板选择Empty Ability,Language选择Js。 + + +3. 工程创建完成后,使用[预览器](https://developer.harmonyos.com/cn/docs/documentation/doc-guides/previewer-0000001054328973#ZH-CN_TOPIC_0000001056725592__section16523172216252)或[模拟器](https://developer.harmonyos.com/cn/docs/documentation/doc-guides/run_simulator-0000001053303709)运行该工程。 + +完成上述操作后,请参考[使用JS语言开发](../quick-start/start-with-js.md)继续下一步的学习。 diff --git a/zh-cn/application-dev/quick-start/start-with-js.md b/zh-cn/application-dev/quick-start/start-with-js.md index e11af482e98..4565f0f8789 100644 --- a/zh-cn/application-dev/quick-start/start-with-js.md +++ b/zh-cn/application-dev/quick-start/start-with-js.md @@ -1,112 +1,106 @@ -# 使用JS语言开发 - -- [编写第一个页面](#section17436202895811) -- [创建另一个页面](#section944219415598) -- [实现页面跳转](#section126857614017) - -## 编写第一个页面 - -1. 第一个页面内有一个文本和一个按钮,通过text和button组件来实现。 - - 在“Project“窗口,选择“entry \> src \> main \> js \> default \> pages \> index“,打开“index.hml“文件,添加一个文本和一个按钮,示例代码如下: - - ``` - -
- - - Hello World - - - -
- ``` - -2. 打开“index.css“文件,设置文本和按钮的样式,示例代码如下: - - ``` - /* index.css */ - .container { - flex-direction: column; /* 设置容器内的项目纵向排列 */ - justify-content: center; /* 设置项目位于容器主轴的中心 */ - align-items: center; /* 项目在交叉轴居中 */ - } - /* 对class="text"的组件设置样式 */ - .text{ - font-size: 42px; - } - /* 对class="button"的组件设置样式 */ - .button { - width: 240px; - height: 60px; - background-color: #007dff; - font-size: 30px; - text-color: white; - margin-top: 20px; - } - ``` - -3. 使用[预览器](https://developer.harmonyos.com/cn/docs/documentation/doc-guides/previewer-0000001054328973#ZH-CN_TOPIC_0000001056725592__section16523172216252)或[模拟器](https://developer.harmonyos.com/cn/docs/documentation/doc-guides/run_simulator-0000001053303709)运行项目,效果如下图所示: - - ![](figures/1.png) - - -## 创建另一个页面 - -1. 在“Project“窗口,打开“entry \> src \> main \> js \> default“,右键点击“pages“文件夹,选择“New \> JS Page“,命名为“details“,单击回车键。 - - 创建完成后,可以看到“pages.index“文件夹下的文件目录结构如下: - - ![](figures/1-0.png) - -2. 打开“details.hml“文件,添加一个文本,示例代码如下: - - ``` - -
- - Hi there - -
- ``` - -3. 打开“details.css“文件,设置文本的样式,示例代码如下: - - ``` - /* details.css */ - .container { - flex-direction: column; - justify-content: center; - align-items: center; - } - .text { - font-size: 42px; - text-align: center; - } - ``` - - -## 实现页面跳转 - -1. 打开第一个页面的“index.js“文件,导入router模块,页面路由router根据页面的uri来找到目标页面,从而实现跳转。示例代码如下: - - ``` - // index.js - import router from '@system.router'; - - export default { - launch() { - router.push ({ - uri:'pages/index/details/details', // 指定要跳转的页面 - }) - } - } - ``` - -2. 再次使用[预览器](https://developer.harmonyos.com/cn/docs/documentation/doc-guides/previewer-0000001054328973#ZH-CN_TOPIC_0000001056725592__section16523172216252)或[模拟器](https://developer.harmonyos.com/cn/docs/documentation/doc-guides/run_simulator-0000001053303709)运行项目,效果如下图所示: - - ![](figures/2.png) - +# 使用JS语言开发 + +- [编写第一个页面](#编写第一个页面) +- [创建另一个页面](#创建另一个页面) +- [实现页面跳转](#实现页面跳转) + +## 编写第一个页面 + +1. 第一个页面内有一个文本和一个按钮,通过text和button组件来实现。 + 在 “Project“窗口,选择“entry > src > mainjsdefaultpages > index”,打开”index.hml“文件,添加一个文本和一个按钮,示例代码如下: + + ``` + +
+ + + Hello World + + + +
+ ``` + +2. 打开“index.css”文件,设置文本和按钮的样式,示例代码如下: + ``` + /* index.css */ + .container { + flex-direction: column; /* 设置容器内的项目纵向排列 */ + justify-content: center; /* 设置项目位于容器主轴的中心 */ + align-items: center; /* 项目在交叉轴居中 */ + width:100%; + height:100%; + } + /* 对class="text"的组件设置样式 */ + .text{ + font-size: 42px; + } + /* 对class="button"的组件设置样式 */ + .button { + width: 240px; + height: 60px; + background-color: #007dff; + font-size: 30px; + text-color: white; + margin-top: 20px; + } + ``` + +3. 使用[预览器](https://developer.harmonyos.com/cn/docs/documentation/doc-guides/previewer-0000001054328973#ZH-CN_TOPIC_0000001056725592__section16523172216252)或[模拟器](https://developer.harmonyos.com/cn/docs/documentation/doc-guides/run_simulator-0000001053303709)运行项目,效果如下图所示: + ![zh-cn_image_0000001212066021](figures/zh-cn_image_0000001212066021.png) + + +## 创建另一个页面 + +1. 在 “Project“窗口,打开“entry > src > mainjsdefault”,右键点击“pages”文件夹,选择“New > JS Page”,命名为“details”,单击回车键。 + 创建完成后,可以看到pages文件夹下的文件目录结构如下: + + ![zh-cn_image_0000001166744640](figures/zh-cn_image_0000001166744640.png) + +2. 打开“details.hml”文件,添加一个文本,示例代码如下: + ``` + +
+ + Hi there + +
+ ``` + +3. 打开“details.css”文件,设置文本的样式,示例代码如下: + ``` + /* details.css */ + .container { + flex-direction: column; + justify-content: center; + align-items: center; + width:100%; + height:100%; + } + .text { + font-size: 42px; + text-align: center; + } + ``` + + +## 实现页面跳转 + +1. 打开第一个页面的“index.js”文件,导入router模块,页面路由router根据页面的uri来找到目标页面,从而实现跳转。示例代码如下: + ``` + // index.js + import router from '@system.router'; + + export default { + launch() { + router.push ({ + uri:'pages/details/details', // 指定要跳转的页面 + }) + } + } + ``` + +2. 再次使用[预览器](https://developer.harmonyos.com/cn/docs/documentation/doc-guides/previewer-0000001054328973#ZH-CN_TOPIC_0000001056725592__section16523172216252)或[模拟器](https://developer.harmonyos.com/cn/docs/documentation/doc-guides/run_simulator-0000001053303709)运行项目,效果如下图所示: + ![zh-cn_image_0000001166904582](figures/zh-cn_image_0000001166904582.png) 恭喜你,至此已成功完成OpenHarmony快速入门-使用JS语言开发。 - diff --git a/zh-cn/application-dev/quick-start/start.md b/zh-cn/application-dev/quick-start/start.md index a667e2decf0..f48551a3206 100644 --- a/zh-cn/application-dev/quick-start/start.md +++ b/zh-cn/application-dev/quick-start/start.md @@ -1,7 +1,7 @@ -# 快速入门 +# 快速入门 -- **[开发准备](start-overview.md)** -- **[使用JS语言开发](start-with-js.md)** +- **[开发准备](start-overview.md)** +- **[使用JS语言开发](start-with-js.md)** diff --git a/zh-cn/application-dev/quick-start/use-wizard-to-create-project.md b/zh-cn/application-dev/quick-start/use-wizard-to-create-project.md index d3013d019ce..e3c9fa6ee67 100644 --- a/zh-cn/application-dev/quick-start/use-wizard-to-create-project.md +++ b/zh-cn/application-dev/quick-start/use-wizard-to-create-project.md @@ -1,46 +1,45 @@ -# 使用工程向导创建新工程 +# 使用工程向导创建新工程 -- [前提条件](#section13642104391619) -- [操作步骤](#section132671712101714) +- [前提条件](#前提条件) +- [操作步骤](#操作步骤) -通过工程向导创建一个OpenHarmony工程,该功能只有DevEco Studio 2.2 Beta1及以上版本支持。如果是DevEco Studio 2.1 Release版本,请根据[通过导入Sample方式创建新工程](import-sample-to-create-project.md)进行操作。 +通过工程向导创建一个OpenHarmony工程,该功能只有DevEco Studio 2.2 Beta1及以上版本支持。如果是DevEco Studio 2.1 Release版本,请根据[通过导入Sample方式创建新工程](../quick-start/import-sample-to-create-project.md)进行操作。 -## 前提条件 -已安装OpenHarmony SDK,具体请参考[配置OpenHarmony SDK](configuring-openharmony-sdk.md)。 +## 前提条件 -## 操作步骤 +已安装OpenHarmony SDK,具体请参考[配置OpenHarmony SDK](../quick-start/configuring-openharmony-sdk.md)。 -1. 通过如下两种方式,打开工程创建向导界面。 - - 如果当前未打开任何工程,可以在DevEco Studio的欢迎页,选择**Create Project**开始创建一个新工程。 - - 如果已经打开了工程,可以在菜单栏选择**File \> New \> New Project**来创建一个新工程。 -2. 根据工程创建向导,选择**\[Standard\]Empty Ability**模板,点击**Next**。 +## 操作步骤 - ![](figures/zh-cn_image_0000001162463400.png) +1. 通过如下两种方式,打开工程创建向导界面。 + - 如果当前未打开任何工程,可以在DevEco Studio的欢迎页,选择 **Create Project**开始创建一个新工程。 + - 如果已经打开了工程,可以在菜单栏选择 **File > New > New Project**来创建一个新工程。 -3. 点击**Next**,进入到工程配置阶段,需要根据向导配置工程的基本信息。 - - **Project Name**:工程的名称,可以自定义。 - - **Project Type**:工程的类型,标识该工程是一个[原子化服务](https://developer.harmonyos.com/cn/docs/documentation/doc-guides/atomic-service-definition-0000001090840664)(Service)或传统方式的需要安装的应用(Application)。 +2. 根据工程创建向导,选择 **[Standard]Empty Ability**模板,点击 **Next**。 + ![zh-cn_image_0000001162463400](figures/zh-cn_image_0000001162463400.png) - >![](../public_sys-resources/icon-note.gif) **说明:** - >如果是创建的原子化服务,则: - >- 原子化服务调试、运行时,在设备桌面上没有应用图标,请使用DevEco Studio的调试和运行功能,来启动原子化服务。 - >- 原子化服务是免安装的,config.json中自动添加**installationFree**字段,取值为“true”。 - >- 如果entry模块的**installationFree**字段为true,则其相关的所有hap模块的**installationFree**字段都默认为true;如果entry模块的**installationFree**字段为false,则其相关的所有hap模块可以配置为true或false。 - >- 编译构建App时,每个hap包大小不能超过10MB。 - - - **Package Name**:软件包名称,默认情况下,应用ID也会使用该名称,应用发布时,应用ID需要唯一。 - - **Save Location**:工程文件本地存储路径。 - - **Compatible API Version**:兼容的SDK最低版本。 - - >![](../public_sys-resources/icon-note.gif) **说明:** - >OpenHarmony工程如果配置了compileSdkVersion 7以上,对应模块默认使用方舟编译器进行编译,如果要修改编译方式为非方舟编译,在模块级build.gradle的**ohos**闭包中添加**arkEnable false**字段。 - - - **Language:**支持的开发语言。 - - **Device Type**:该工程模板支持的设备类型。 - - ![](figures/zh-cn_image_0000001208210505.png) - -4. 点击**Finish**,工具会自动生成示例代码和相关资源,等待工程创建完成。 +3. 点击 **Next**,进入到工程配置阶段,需要根据向导配置工程的基本信息。 + - **Project Name**:工程的名称,可以自定义。 + - **Project Type**:工程的类型,标识该工程是一个[原子化服务](https://developer.harmonyos.com/cn/docs/documentation/doc-guides/atomic-service-definition-0000001090840664)(Service)或传统方式的需要安装的应用(Application)。 + > ![icon-note.gif](public_sys-resources/icon-note.gif) **说明:**
+ > 如果是创建的原子化服务,则: + > + > - 原子化服务调试、运行时,在设备桌面上没有应用图标,请使用DevEco Studio的调试和运行功能,来启动原子化服务。 + > + > - 原子化服务是免安装的,config.json中自动添加 **installationFree**字段,取值为“true”。 + > + > - 如果entry模块的 **installationFree**字段为true,则其相关的所有hap模块的 **installationFree**字段都默认为true;如果entry模块的 **installationFree**字段为false,则其相关的所有hap模块可以配置为true或false。 + > + > - 编译构建App时,每个hap包大小不能超过10MB。 + - **Package Name**:软件包名称,默认情况下,应用ID也会使用该名称,应用发布时,应用ID需要唯一。 + - **Save Location**:工程文件本地存储路径。 + - **Compatible API Version**:兼容的SDK最低版本。 + > ![icon-note.gif](public_sys-resources/icon-note.gif) **说明:**
+ > OpenHarmony工程如果配置了compileSdkVersion 7以上,对应模块默认使用方舟编译器进行编译,如果要修改编译方式为非方舟编译,在模块级build.gradle的 **ohos**闭包中添加 **arkEnable false**字段。 + - **Language**:支持的开发语言。 + - **Device Type**:该工程模板支持的设备类型。
+ ![zh-cn_image_0000001208210505](figures/zh-cn_image_0000001208210505.png) +4. 点击 **Finish**,工具会自动生成示例代码和相关资源,等待工程创建完成。 diff --git a/zh-cn/application-dev/ui/Readme-CN.md b/zh-cn/application-dev/ui/Readme-CN.md index fec0a247e1b..17013f84064 100755 --- a/zh-cn/application-dev/ui/Readme-CN.md +++ b/zh-cn/application-dev/ui/Readme-CN.md @@ -1,19 +1,17 @@ # UI - - [JS UI框架](ui-js.md) - - [JS UI框架概述](ui-js-overview.md) - - [构建用户界面](ui-js-building-ui.md) - - [组件介绍](ui-js-building-ui-component.md) - - [构建布局](ui-js-building-ui-layout.md) - - [布局说明](ui-js-building-ui-layout-intro.md) - - [添加标题行和文本区域](ui-js-building-ui-layout-text.md) - - [添加图片区域](ui-js-building-ui-layout-image.md) - - [添加留言区域](ui-js-building-ui-layout-comment.md) - - [添加容器](ui-js-building-ui-layout-external-container.md) - - - [添加交互](ui-js-building-ui-interactions.md) - - [动画](ui-js-building-ui-animation.md) - - [事件](ui-js-building-ui-event.md) - - [页面路由](ui-js-building-ui-routes.md) - - - [自定义组件](ui-js-custom-components.md) +- JS UI框架 + - [JS UI框架概述](ui-js-overview.md) + - 构建用户界面 + - [组件介绍](ui-js-building-ui-component.md) + - 构建布局 + - [布局说明](ui-js-building-ui-layout-intro.md) + - [添加标题行和文本区域](ui-js-building-ui-layout-text.md) + - [添加图片区域](ui-js-building-ui-layout-image.md) + - [添加留言区域](ui-js-building-ui-layout-comment.md) + - [添加容器](ui-js-building-ui-layout-external-container.md) + - [添加交互](ui-js-building-ui-interactions.md) + - [动画](ui-js-building-ui-animation.md) + - [事件](ui-js-building-ui-event.md) + - [页面路由](ui-js-building-ui-routes.md) + - [自定义组件](ui-js-custom-components.md) diff --git a/zh-cn/application-dev/ui/figures/zh-cn_image_0000001077953992.png b/zh-cn/application-dev/ui/figures/zh-cn_image_0000001166426358.png similarity index 100% rename from zh-cn/application-dev/ui/figures/zh-cn_image_0000001077953992.png rename to zh-cn/application-dev/ui/figures/zh-cn_image_0000001166426358.png diff --git "a/zh-cn/application-dev/ui/figures/\351\241\265\351\235\242\345\270\203\345\261\200\345\210\206\350\247\243.png" b/zh-cn/application-dev/ui/figures/zh-cn_image_0000001166426374.png old mode 100755 new mode 100644 similarity index 100% rename from "zh-cn/application-dev/ui/figures/\351\241\265\351\235\242\345\270\203\345\261\200\345\210\206\350\247\243.png" rename to zh-cn/application-dev/ui/figures/zh-cn_image_0000001166426374.png diff --git "a/zh-cn/application-dev/ui/figures/\345\233\276\347\211\2073.png" b/zh-cn/application-dev/ui/figures/zh-cn_image_0000001166586348.png old mode 100755 new mode 100644 similarity index 100% rename from "zh-cn/application-dev/ui/figures/\345\233\276\347\211\2073.png" rename to zh-cn/application-dev/ui/figures/zh-cn_image_0000001166586348.png diff --git "a/zh-cn/application-dev/ui/figures/\350\277\236\347\273\255\345\212\250\347\224\273\346\225\210\346\236\234\345\233\276.gif" b/zh-cn/application-dev/ui/figures/zh-cn_image_0000001166744904.gif old mode 100755 new mode 100644 similarity index 100% rename from "zh-cn/application-dev/ui/figures/\350\277\236\347\273\255\345\212\250\347\224\273\346\225\210\346\236\234\345\233\276.gif" rename to zh-cn/application-dev/ui/figures/zh-cn_image_0000001166744904.gif diff --git "a/zh-cn/application-dev/ui/figures/\351\241\265\351\235\242\350\267\257\347\224\261\346\225\210\346\236\234.png" b/zh-cn/application-dev/ui/figures/zh-cn_image_0000001166904852.png old mode 100755 new mode 100644 similarity index 100% rename from "zh-cn/application-dev/ui/figures/\351\241\265\351\235\242\350\267\257\347\224\261\346\225\210\346\236\234.png" rename to zh-cn/application-dev/ui/figures/zh-cn_image_0000001166904852.png diff --git a/zh-cn/application-dev/ui/figures/zh-cn_image_0000001212066259.png b/zh-cn/application-dev/ui/figures/zh-cn_image_0000001212066259.png new file mode 100644 index 0000000000000000000000000000000000000000..bf7c20aab02bcf3a56d95c43913778c447066295 GIT binary patch literal 43265 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 Ws9GO)EBq$|5O})!xvXfB$R?oG%6hQ z+MMLZbQBH@)Vg&1^3?qHb(5!%>3r0+`eq=&V&E}0Dypi0000000000 z00000A^8LW000R9EC2ui03!e$000L5z=Uu}ED8YtqjJd<+B}(9bIOb$3-31_h|V>=0A{ z1Hh0#H30>fNT})^fRU_83uewx9oRr{f{Sx1Ml`t)EQ zGkHZ67&~y{W5Jpq4H_WfuLxp*3<7O}GEl;1ESe36fLNs=B0&LQM1Buf(R)qg(BRd`t1OPjI1m_q4 literal 0 HcmV?d00001 diff --git a/zh-cn/application-dev/ui/public_sys-resources/icon-danger.gif b/zh-cn/application-dev/ui/public_sys-resources/icon-danger.gif new file mode 100644 index 0000000000000000000000000000000000000000..6e90d7cfc2193e39e10bb58c38d01a23f045d571 GIT binary patch literal 580 zcmV-K0=xZ3Nk%w1VIu$?0Hp~4{QBgqmQ+MG9K51r{QB&)np^||1PlfQ%(86!{`~yv zv{XhUWKt}AZaiE{EOcHp{O-j3`t;<+eEiycJT4p@77X;(jQsMfB$R?oG%6hQ z+MMLZbQBH@)Vg&1^3?qHb(5!%>3r0+`eq=&V&E}0Dypi0000000000 z00000A^8LW000R9EC2ui03!e$000L5z=Uu}ED8YtqjJd<+B}(9bIOb$3-31_h|V>=0A{ z1Hh0#H30>fNT})^fRU_83uewx9oRr{f{Sx1Ml`t)EQ zGkHZ67&~y{W5Jpq4H_WfuLxp*3<7O}GEl;1ESe36fLNs=B0&LQM1Buf(R)qg(BRd`t1OPjI1m_q4 literal 0 HcmV?d00001 diff --git a/zh-cn/application-dev/ui/public_sys-resources/icon-note.gif b/zh-cn/application-dev/ui/public_sys-resources/icon-note.gif new file mode 100644 index 0000000000000000000000000000000000000000..6314297e45c1de184204098efd4814d6dc8b1cda GIT binary patch literal 394 zcmZ?wbhEHblx7fPSjxcg=ii?@_wH=jwxy=7CMGH-B`L+l$wfv=#>UF#$gv|VY%C^b zCQFtrnKN(Bo_%|sJbO}7RAORe!otL&qo<>yq_Sq+8Xqqo5h0P3w3Lvb5E(g{p01vl zxR@)KuDH0l^z`+-dH3eaw=XqSH7aTIx{kzVBN;X&hha0dQSgWuiw0NWUvMRmkD|> literal 0 HcmV?d00001 diff --git a/zh-cn/application-dev/ui/public_sys-resources/icon-notice.gif b/zh-cn/application-dev/ui/public_sys-resources/icon-notice.gif new file mode 100644 index 0000000000000000000000000000000000000000..86024f61b691400bea99e5b1f506d9d9aef36e27 GIT binary patch literal 406 zcmV;H0crk6Nk%w1VIu$@0J8u9|NsB@_xJDb@8;&_*4Ea}&d#;9wWXz{jEszHYim+c zQaU<1At50E0000000000A^8Le000gEEC2ui03!e%000R7038S%NU)&51O^i-Tu6`s z0)`MFE@;3YqD6xSC^kTNu_J>91{PH8XfZ(p1pp2-SU@u3#{mEUC}_}tg3+I#{z}{Ok@D_ZUDg- zt0stin4;pC8M{WLSlRH*1pzqEw1}3oOskyNN?j;7HD{BBZ*OEcv4HK!6Bk6beR+04 z&8}k>SkTusVTDmkyOz#5fCA$JTPGJVQvr3uZ?QzzPQFvD0rGf_PdrcF`pMs}p^BcF zKtKTd`0wipR%nKN&Wj+V}pX;WC3SdJV!a_8Qi zE7z`U*|Y^H0^}fB$R?oG%6hQ z+MMLZbQBH@)Vg&1^3?qHb(5!%>3r0+`eq=&V&E}0Dypi0000000000 z00000A^8LW000R9EC2ui03!e$000L5z=Uu}ED8YtqjJd<+B}(9bIOb$3-31_h|V>=0A{ z1Hh0#H30>fNT})^fRU_83uewx9oRr{f{Sx1Ml`t)EQ zGkHZ67&~y{W5Jpq4H_WfuLxp*3<7O}GEl;1ESe36fLNs=B0&LQM1Buf(R)qg(BRd`t1OPjI1m_q4 literal 0 HcmV?d00001 diff --git a/zh-cn/application-dev/ui/ui-js-building-ui-animation.md b/zh-cn/application-dev/ui/ui-js-building-ui-animation.md index 6fa473789fa..2a472cdc9b6 100755 --- a/zh-cn/application-dev/ui/ui-js-building-ui-animation.md +++ b/zh-cn/application-dev/ui/ui-js-building-ui-animation.md @@ -1,17 +1,20 @@ -# 动画 +# 动画 -- [静态动画](#section456613911492) -- [连续动画](#section17836125204914) +- [静态动画](#静态动画) +- [连续动画](#连续动画) -动画分为[静态动画](#section456613911492)和[连续动画](#section17836125204914)。 +动画分为[静态动画](#静态动画)和[连续动画](#连续动画)。 -## 静态动画 + +## 静态动画 静态动画的核心是transform样式,主要可以实现以下三种变换类型,一次样式设置只能实现一种类型变换。 -- **translate**:沿水平或垂直方向将指定组件移动所需距离。 -- **scale**:横向或纵向将指定组件缩小或放大到所需比例。 -- **rotate**:将指定组件沿横轴或纵轴或中心点旋转指定的角度。 +- **translate**:沿水平或垂直方向将指定组件移动所需距离。 + +- **scale**:横向或纵向将指定组件缩小或放大到所需比例。 + +- **rotate**:将指定组件沿横轴或纵轴或中心点旋转指定的角度。 具体的使用示例如下。 @@ -54,20 +57,26 @@ } ``` -**图 1** 静态动画效果图 -![](figures/静态动画效果图.png "静态动画效果图") -## 连续动画 +**图1** 静态动画效果图
+![zh-cn_image_0000001212066279](figures/zh-cn_image_0000001212066279.png) + + +## 连续动画 静态动画只有开始状态和结束状态,没有中间状态,如果需要设置中间的过渡状态和转换效果,需要使用连续动画实现。 连续动画的核心是animation样式,它定义了动画的开始状态、结束状态以及时间和速度的变化曲线。通过animation样式可以实现的效果有: -- **animation-name**:设置动画执行后应用到组件上的背景颜色、透明度、宽高和变换类型。 -- **animation-delay**和**animation-duration**:分别设置动画执行后元素延迟和持续的时间。 -- **animation-timing-function**:描述动画执行的速度曲线,使动画更加平滑。 -- **animation-iteration-count**:定义动画播放的次数。 -- **animation-fill-mode**:指定动画执行结束后是否恢复初始状态。 +- **animation-name**:设置动画执行后应用到组件上的背景颜色、透明度、宽高和变换类型。 + +- **animation-delay**和 **animation-duration**:分别设置动画执行后元素延迟和持续的时间。 + +- **animation-timing-function**:描述动画执行的速度曲线,使动画更加平滑。 + +- **animation-iteration-count**:定义动画播放的次数。 + +- **animation-fill-mode**:指定动画执行结束后是否恢复初始状态。 animation样式需要在css文件中先定义keyframe,在keyframe中设置动画的过渡效果,并通过一个样式类型在hml文件中调用。animation-name的使用示例如下: @@ -150,6 +159,6 @@ export default { } ``` -**图 2** 连续动画效果图 -![](figures/连续动画效果图.gif "连续动画效果图") +**图2** 连续动画效果图
+![zh-cn_image_0000001166744904](figures/zh-cn_image_0000001166744904.gif) diff --git a/zh-cn/application-dev/ui/ui-js-building-ui-component.md b/zh-cn/application-dev/ui/ui-js-building-ui-component.md index d67645103dc..49d2a1ef3f2 100755 --- a/zh-cn/application-dev/ui/ui-js-building-ui-component.md +++ b/zh-cn/application-dev/ui/ui-js-building-ui-component.md @@ -1,35 +1,21 @@ -# 组件介绍 +# 组件介绍 -- [组件分类](#section154381954142018) +- [组件分类](#组件分类) -组件(Component)是构建页面的核心,每个组件通过对数据和方法的简单封装,实现独立的可视、可交互功能单元。组件之间相互独立,随取随用,也可以在需求相同的地方重复使用。 +组件(Component)是构建页面的核心,每个组件通过对数据和方法的简单封装,实现独立的可视、可交互功能单元。组件之间相互独立,随取随用,也可以在需求相同的地方重复使用。关于组件的详细参考文档请参见[组件](../js-reference/component/Readme-CN.md)。 -## 组件分类 +开发者还可以通过组件间合理的搭配定义满足业务需求的新组件,减少开发量,自定义组件的开发方法请参见[自定义组件](../js-reference/component/js-components-custom.md)。 + +## 组件分类 根据组件的功能,可以分为以下四大类: - - - - - - - - - - - - - - - -

组件类型

-

主要组件

-

基础组件

-

text、image、progress、rating、span、marquee、image-animator、divider、search、menu、chart

-

容器组件

-

div、list、list-item、stack、swiper、tabs、tab-bar、tab-content、list-item-group、refresh、dialog

-

画布组件

-

canvas

-
+| 组件类型 | 主要组件 | +| -------- | -------- | +| 基础组件 | button、chart、divider、image、image-animator、input、label、marquee、menu、option、picker、picker-view、piece、progress、qrcode、rating、richtext、search、select、slider、span、switch、text、textarea、toolbar、toolbar-item、toggle | +| 容器组件 | badge、dialog、div、form、list、list-item、list-item-group、panel、popup、refresh、stack、stepper、stepper-item、swiper、tabs、tab-bar、tab-content | +|媒体组件|video| +| 画布组件 | canvas | +|栅格组件|grid-container、grid-row、grid-col| +|svg组件|svg、rect、circle、ellipse、path、line、polyline、polygon、text、tspan、textPath、animate、animateMotion、animateTransform| diff --git a/zh-cn/application-dev/ui/ui-js-building-ui-event.md b/zh-cn/application-dev/ui/ui-js-building-ui-event.md index fad1987dfad..2d6f82caacf 100755 --- a/zh-cn/application-dev/ui/ui-js-building-ui-event.md +++ b/zh-cn/application-dev/ui/ui-js-building-ui-event.md @@ -1,19 +1,23 @@ -# 事件 +# 事件 -- [手势事件](#section21104561094) +- [手势事件](#手势事件) +- [按键事件](#按键事件) 事件主要为手势事件。手势事件主要用于具有触摸屏的设备。 -## 手势事件 + +## 手势事件 手势表示由单个或多个事件识别的语义动作(例如:点击、拖动和长按)。一个完整的手势也可能由多个事件组成,对应手势的生命周期。JS UI框架支持的手势事件有: -**触摸** + **触摸** +- touchstart:手指触摸动作开始。 + +- touchmove:手指触摸后移动。 + +- touchcancel:手指触摸动作被打断,如来电提醒、弹窗。 -- touchstart:手指触摸动作开始。 -- touchmove:手指触摸后移动。 -- touchcancel:手指触摸动作被打断,如来电提醒、弹窗。 -- touchend:手指触摸动作结束。 +- touchend:手指触摸动作结束。 **点击** diff --git a/zh-cn/application-dev/ui/ui-js-building-ui-interactions.md b/zh-cn/application-dev/ui/ui-js-building-ui-interactions.md index 1e365a8ed05..d569f7970c9 100755 --- a/zh-cn/application-dev/ui/ui-js-building-ui-interactions.md +++ b/zh-cn/application-dev/ui/ui-js-building-ui-interactions.md @@ -1,19 +1,22 @@ -# 添加交互 +# 添加交互 添加交互可以通过在组件上关联事件实现。本节将介绍如何用div、text、image组件关联click事件,构建一个如下图所示的点赞按钮。 +**图1** 点赞按钮效果 -**图 1** 点赞按钮效果 +![zh-cn_image_0000001212146221](figures/zh-cn_image_0000001212146221.gif) -![](figures/zan.gif) - 点赞按钮通过一个div组件关联click事件实现。div组件包含一个image组件和一个text组件: -- image组件用于显示未点赞和点赞的效果。click事件函数会交替更新点赞和未点赞图片的路径。 -- text组件用于显示点赞数,点赞数会在click事件的函数中同步更新。 + +- image组件用于显示未点赞和点赞的效果。click事件函数会交替更新点赞和未点赞图片的路径。 + +- text组件用于显示点赞数,点赞数会在click事件的函数中同步更新。 + click事件作为一个函数定义在js文件中,可以更改isPressed的状态,从而更新显示的image组件。如果isPressed为真,则点赞数加1。该函数在hml文件中对应的div组件上生效,点赞按钮各子组件的样式设置在css文件当中。具体的实现示例如下: + ``` @@ -25,6 +28,7 @@ click事件作为一个函数定义在js文件中,可以更改isPressed的状 ``` + ``` /* xxx.css */ .like { @@ -48,6 +52,7 @@ click事件作为一个函数定义在js文件中,可以更改isPressed的状 } ``` + ``` // xxx.js export default { @@ -71,5 +76,5 @@ export default { } ``` -JS UI框架还提供了很多表单组件,例如开关、标签、滑动选择器等,以便于开发者在页面布局时灵活使用和提高交互性。 +JS UI框架还提供了很多表单组件,例如开关、标签、滑动选择器等,以便于开发者在页面布局时灵活使用和提高交互性。 diff --git a/zh-cn/application-dev/ui/ui-js-building-ui-layout-comment.md b/zh-cn/application-dev/ui/ui-js-building-ui-layout-comment.md index 0ee00abda5a..6de57196284 100755 --- a/zh-cn/application-dev/ui/ui-js-building-ui-layout-comment.md +++ b/zh-cn/application-dev/ui/ui-js-building-ui-layout-comment.md @@ -1,8 +1,10 @@ -# 添加留言区域 +# 添加留言区域 留言框的功能为:用户输入留言后点击完成,留言区域即显示留言内容;用户点击右侧的删除按钮可删除当前留言内容并重新输入。 -留言区域由div、text、input关联click事件实现。开发者可以使用input组件实现输入留言的部分,使用text组件实现留言完成部分,使用commentText的状态标记此时显示的组件(通过if属性控制)。在包含文本“完成“和“删除“的text组件中关联click事件,更新commentText状态和inputValue的内容。具体的实现示例如下: + +留言区域由div、text、input关联click事件实现。开发者可以使用input组件实现输入留言的部分,使用text组件实现留言完成部分,使用commentText的状态标记此时显示的组件(通过if属性控制)。在包含文本完成和删除的text组件中关联click事件,更新commentText状态和inputValue的内容。具体的实现示例如下: + ``` @@ -19,6 +21,7 @@ ``` + ``` /* xxx.css */ .container { @@ -30,7 +33,7 @@ color: #1a1a1a; font-weight: bold; margin-top: 40px; - margin-bottom: 10px; +margin-bottom: 10px; } .comment { width: 550px; @@ -60,6 +63,7 @@ } ``` + ``` // xxx.js export default { @@ -75,4 +79,3 @@ export default { }, } ``` - diff --git a/zh-cn/application-dev/ui/ui-js-building-ui-layout-external-container.md b/zh-cn/application-dev/ui/ui-js-building-ui-layout-external-container.md index 56ff8b0ed49..65cdb858892 100755 --- a/zh-cn/application-dev/ui/ui-js-building-ui-layout-external-container.md +++ b/zh-cn/application-dev/ui/ui-js-building-ui-layout-external-container.md @@ -1,11 +1,12 @@ -# 添加容器 +# 添加容器 -- [List组件](#section1875054932714) -- [Tabs组件](#section91861363535) +- [List组件](#list组件) +- [Tabs组件](#tabs组件) 要将页面的基本元素组装在一起,需要使用容器组件。在页面布局中常用到三种容器组件,分别是div、list和tabs。在页面结构相对简单时,可以直接用div作为容器,因为div作为单纯的布局容器,可以支持多种子组件,使用起来更为方便。 -## List组件 + +## List组件 当页面结构较为复杂时,如果使用div循环渲染,容易出现卡顿,因此推荐使用list组件代替div组件实现长列表布局,从而实现更加流畅的列表滚动体验。需要注意的是,list仅支持list-item作为子组件,具体的使用示例如下: @@ -37,7 +38,8 @@ export default { 为避免示例代码过长,以上示例的list中只包含一个list-item,list-item中只有一个text组件。在实际应用中可以在list中加入多个list-item,同时list-item下可以包含多个其他子组件。 -## Tabs组件 + +## Tabs组件 当页面经常需要动态加载时,推荐使用tabs组件。tabs组件支持change事件,在页签切换后触发。tabs组件仅支持一个tab-bar和一个tab-content。具体的使用示例如下: @@ -69,4 +71,3 @@ export default { ``` tab-content组件用来展示页签的内容区,高度默认充满tabs剩余空间。 - diff --git a/zh-cn/application-dev/ui/ui-js-building-ui-layout-image.md b/zh-cn/application-dev/ui/ui-js-building-ui-layout-image.md index 4c378cf7376..d0fbeb8983f 100755 --- a/zh-cn/application-dev/ui/ui-js-building-ui-layout-image.md +++ b/zh-cn/application-dev/ui/ui-js-building-ui-layout-image.md @@ -1,14 +1,17 @@ -# 添加图片区域 +# 添加图片区域 添加图片区域通常用image组件来实现,使用的方法和text组件类似。 -图片资源建议放在“js \> default \> common“目录下,common目录需自行创建。代码示例如下: + +图片资源建议放在jsdefaultcommon目录下,common目录需自行创建。代码示例如下: + ``` ``` + ``` /* xxx.css */ .img { @@ -18,6 +21,7 @@ } ``` + ``` // xxx.js export default { @@ -26,4 +30,3 @@ export default { }, } ``` - diff --git a/zh-cn/application-dev/ui/ui-js-building-ui-layout-intro.md b/zh-cn/application-dev/ui/ui-js-building-ui-layout-intro.md index 4e6400693ca..74ed1ef084e 100644 --- a/zh-cn/application-dev/ui/ui-js-building-ui-layout-intro.md +++ b/zh-cn/application-dev/ui/ui-js-building-ui-layout-intro.md @@ -1,26 +1,31 @@ -# 布局说明 +# 布局说明 JS UI框架中,设备的基准宽度为720px(px为逻辑像素,非物理像素),实际显示效果会根据实际屏幕宽度进行缩放。 + 其换算关系如下: + 组件的width设为100px时,在宽度为720物理像素的屏幕上,实际显示为100物理像素;在宽度为1440物理像素的屏幕上,实际显示为200物理像素。 一个页面的基本元素包含标题区域、文本区域、图片区域等,每个基本元素内还可以包含多个子元素,开发者根据需求还可以添加按钮、开关、进度条等组件。在构建页面布局时,需要对每个基本元素思考以下几个问题: -- 该元素的尺寸和排列位置 -- 是否有重叠的元素 -- 是否需要设置对齐、内间距或者边界 -- 是否包含子元素及其排列位置 -- 是否需要容器组件及其类型 -将页面中的元素分解之后再对每个基本元素按顺序实现,可以减少多层嵌套造成的视觉混乱和逻辑混乱,提高代码的可读性,方便对页面做后续的调整。以下图为例进行分解: +- 该元素的尺寸和排列位置 + +- 是否有重叠的元素 + +- 是否需要设置对齐、内间距或者边界 + +- 是否包含子元素及其排列位置 -**图 1** 页面布局分解 -![](figures/页面布局分解.png "页面布局分解") +- 是否需要容器组件及其类型 -**图 2** 留言区布局分解 +将页面中的元素分解之后再对每个基本元素按顺序实现,可以减少多层嵌套造成的视觉混乱和逻辑混乱,提高代码的可读性,方便对页面做后续的调整。以下图为例进行分解:
+**图1** 页面布局分解
+![zh-cn_image_0000001166426374](figures/zh-cn_image_0000001166426374.png) -![](figures/图片3.png) +**图2** 留言区布局分解
+![zh-cn_image_0000001166586348](figures/zh-cn_image_0000001166586348.png) diff --git a/zh-cn/application-dev/ui/ui-js-building-ui-layout-text.md b/zh-cn/application-dev/ui/ui-js-building-ui-layout-text.md index 2a1c927a22f..4dd5e395201 100755 --- a/zh-cn/application-dev/ui/ui-js-building-ui-layout-text.md +++ b/zh-cn/application-dev/ui/ui-js-building-ui-layout-text.md @@ -1,7 +1,8 @@ -# 添加标题行和文本区域 +# 添加标题行和文本区域 实现标题和文本区域最常用的是基础组件text。text组件用于展示文本,可以设置不同的属性和样式,文本内容需要写在标签内容区。在页面中插入标题和文本区域的示例如下: + ```
@@ -11,6 +12,7 @@
``` + ``` /* xxx.css */ .container { @@ -31,6 +33,7 @@ } ``` + ``` // xxx.js export default { @@ -41,4 +44,3 @@ export default { }, } ``` - diff --git a/zh-cn/application-dev/ui/ui-js-building-ui-layout.md b/zh-cn/application-dev/ui/ui-js-building-ui-layout.md index 9cc3a1138d7..72d4a2292c4 100644 --- a/zh-cn/application-dev/ui/ui-js-building-ui-layout.md +++ b/zh-cn/application-dev/ui/ui-js-building-ui-layout.md @@ -1,13 +1,12 @@ -# 构建布局 +# 构建布局 -- **[布局说明](ui-js-building-ui-layout-intro.md)** -- **[添加标题行和文本区域](ui-js-building-ui-layout-text.md)** +- **[布局说明](ui-js-building-ui-layout-intro.md)** -- **[添加图片区域](ui-js-building-ui-layout-image.md)** +- **[添加标题行和文本区域](ui-js-building-ui-layout-text.md)** -- **[添加留言区域](ui-js-building-ui-layout-comment.md)** - -- **[添加容器](ui-js-building-ui-layout-external-container.md)** +- **[添加图片区域](ui-js-building-ui-layout-image.md)** +- **[添加留言区域](ui-js-building-ui-layout-comment.md)** +- **[添加容器](ui-js-building-ui-layout-external-container.md)** \ No newline at end of file diff --git a/zh-cn/application-dev/ui/ui-js-building-ui-routes.md b/zh-cn/application-dev/ui/ui-js-building-ui-routes.md index dac9f8d307e..5d1a79323a0 100644 --- a/zh-cn/application-dev/ui/ui-js-building-ui-routes.md +++ b/zh-cn/application-dev/ui/ui-js-building-ui-routes.md @@ -1,18 +1,23 @@ -# 页面路由 +# 页面路由 -- [构建页面布局](#section135242911291) -- [构建页面样式](#section174441114183216) -- [实现跳转](#section1276711211359) +- [构建页面布局](#构建页面布局) +- [构建页面样式](#构建页面样式) +- [实现跳转](#实现跳转) 很多应用由多个页面组成,比如用户可以从音乐列表页面点击歌曲,跳转到该歌曲的播放界面。开发者需要通过页面路由将这些页面串联起来,按需实现跳转。 + 页面路由router根据页面的uri找到目标页面,从而实现跳转。以最基础的两个页面之间的跳转为例,具体实现步骤如下: -1. 在“Project“窗口,打开“entry \> src \> main \> js \> default“,右键点击“pages“文件夹,选择“New \> JS Page“,创建一个详情页。 -2. 调用router.push\(\)路由到详情页。 -3. 调用router.back\(\)回到首页。 -## 构建页面布局 +1. 在 “Project“窗口,打开“entry > src > main > js > default”,右键点击“pages”文件夹,选择“New > JS Page”,创建一个详情页。 + +2. 调用router.push()路由到详情页。 + +3. 调用router.back()回到首页。 + + +## 构建页面布局 index和detail这两个页面均包含一个text组件和button组件:text组件用来指明当前页面,button组件用来实现两个页面之间的相互跳转。hml文件代码示例如下: @@ -32,7 +37,8 @@ index和detail这两个页面均包含一个text组件和button组件:text组 ``` -## 构建页面样式 + +## 构建页面样式 构建index和detail页面的页面样式,text组件和button组件居中显示,两个组件之间间距为50px。css代码如下(两个页面样式代码一致): @@ -51,9 +57,10 @@ index和detail这两个页面均包含一个text组件和button组件:text组 } ``` -## 实现跳转 -为了使button组件的launch方法生效,需要在页面的js文件中实现跳转逻辑。调用router.push\(\)接口将uri指定的页面添加到路由栈中,即跳转到uri指定的页面。在调用router方法之前,需要导入router模块。代码示例如下: +## 实现跳转 + +为了使button组件的launch方法生效,需要在页面的js文件中实现跳转逻辑。调用router.push()接口将uri指定的页面添加到路由栈中,即跳转到uri指定的页面。在调用router方法之前,需要导入router模块。代码示例如下: ``` // index.js @@ -79,6 +86,5 @@ export default { 运行效果如下图所示: -**图 1** 页面路由效果 -![](figures/页面路由效果.png "页面路由效果") - +**图1** 页面路由效果
+![zh-cn_image_0000001166904852](figures/zh-cn_image_0000001166904852.png) diff --git a/zh-cn/application-dev/ui/ui-js-building-ui.md b/zh-cn/application-dev/ui/ui-js-building-ui.md index 934f5970d8a..ccb63dde2ef 100644 --- a/zh-cn/application-dev/ui/ui-js-building-ui.md +++ b/zh-cn/application-dev/ui/ui-js-building-ui.md @@ -1,15 +1,14 @@ -# 构建用户界面 +# 构建用户界面 -- **[组件介绍](ui-js-building-ui-component.md)** -- **[构建布局](ui-js-building-ui-layout.md)** +- **[组件介绍](ui-js-building-ui-component.md)** -- **[添加交互](ui-js-building-ui-interactions.md)** +- **[构建布局](ui-js-building-ui-layout.md)** -- **[动画](ui-js-building-ui-animation.md)** +- **[添加交互](ui-js-building-ui-interactions.md)** -- **[事件](ui-js-building-ui-event.md)** - -- **[页面路由](ui-js-building-ui-routes.md)** +- **[动画](ui-js-building-ui-animation.md)** +- **[事件](ui-js-building-ui-event.md)** +- **[页面路由](ui-js-building-ui-routes.md)** \ No newline at end of file diff --git a/zh-cn/application-dev/ui/ui-js-custom-components.md b/zh-cn/application-dev/ui/ui-js-custom-components.md index 806d4aaf48d..05f8bf0164f 100755 --- a/zh-cn/application-dev/ui/ui-js-custom-components.md +++ b/zh-cn/application-dev/ui/ui-js-custom-components.md @@ -1,100 +1,99 @@ -# 自定义组件 +# 自定义组件 JS UI框架支持自定义组件,用户可根据业务需求将已有的组件进行扩展,增加自定义的私有属性和事件,封装成新的组件,方便在工程中多次调用,提高页面布局代码的可读性。具体的封装方法示例如下: -- **构建自定义组件** - ``` - -
- {{title}} - 点击这里查看隐藏文本 - hello world -
- ``` +- **构建自定义组件** + ``` + +
+ {{title}} + 点击这里查看隐藏文本 + hello world +
+ ``` - ``` - /* comp.css */ - .item { - width: 700px; - flex-direction: column; - height: 300px; - align-items: center; - margin-top: 100px; - } - .text-style { - width: 100%; - text-align: center; - font-weight: 500; - font-family: Courier; - font-size: 36px; - } - .title-style { - font-weight: 500; - font-family: Courier; - font-size: 50px; - color: #483d8b; - } - ``` + ``` + /* comp.css */ + .item { + width: 700px; + flex-direction: column; + height: 300px; + align-items: center; + margin-top: 100px; + } + .text-style { + width: 100%; + text-align: center; + font-weight: 500; + font-family: Courier; + font-size: 36px; + } + .title-style { + font-weight: 500; + font-family: Courier; + font-size: 50px; + color: #483d8b; + } + ``` - ``` - // comp.js - export default { - props: { - title: { - default: 'title', - }, - showObject: {}, + ``` + // comp.js + export default { + props: { + title: { + default: 'title', }, - data() { - return { - showObj: this.showObject, - }; - }, - childClicked () { - this.$emit('eventType1', {text: '收到子组件参数'}); - this.showObj = !this.showObj; - }, - } - ``` + showObject: {}, + }, + data() { + return { + showObj: this.showObject, + }; + }, + childClicked () { + this.$emit('eventType1', {text: '收到子组件参数'}); + this.showObj = !this.showObj; + }, + } + ``` -- **引入自定义组件** +- **引入自定义组件** + ``` + + +
+ 父组件:{{text}} + +
+ ``` - ``` - - -
- 父组件:{{text}} - -
- ``` + ``` + /* xxx.css */ + .container { + background-color: #f8f8ff; + flex: 1; + flex-direction: column; + align-content: center; + } + ``` - ``` - /* xxx.css */ - .container { - background-color: #f8f8ff; - flex: 1; - flex-direction: column; - align-content: center; - } - ``` - - ``` - // xxx.js - export default { - data: { - text: '开始', - isShow: false, - }, - textClicked (e) { - this.text = e.detail.text; - }, - } - ``` + ``` + // xxx.js + export default { + data: { + text: '开始', + isShow: false, + }, + textClicked (e) { + this.text = e.detail.text; + }, + } + ``` 本示例中父组件通过添加自定义属性向子组件传递了名称为title的参数,子组件在props中接收。同时子组件也通过事件绑定向上传递了参数text,接收时通过e.detail获取。要绑定子组件事件,父组件事件命名必须遵循事件绑定规则。自定义组件效果如下图所示: -**图 1** 自定义组件的效果 -![](figures/自定义组件的效果.png "自定义组件的效果") +**图1** 自定义组件的效果 +![zh-cn_image_0000001212146243](figures/zh-cn_image_0000001212146243.png) diff --git a/zh-cn/application-dev/ui/ui-js-overview.md b/zh-cn/application-dev/ui/ui-js-overview.md index 3fdabc8b7e4..d373b1e9102 100755 --- a/zh-cn/application-dev/ui/ui-js-overview.md +++ b/zh-cn/application-dev/ui/ui-js-overview.md @@ -1,38 +1,31 @@ -# JS UI框架概述 +# JS UI框架概述 -- [基础能力](#section1393616301083) -- [整体架构](#section105231413161115) +- [基础能力](#基础能力) +- [整体架构](#整体架构) JS UI框架是OpenHarmony UI开发框架,提供基础类、容器类、画布类等UI组件和标准CSS动画能力,支持类Web范式编程。 -## 基础能力 +## 基础能力 +- **类Web范式编程**
+ JS UI框架采用类HTML和CSS Web编程语言作为页面布局和页面样式的开发语言,页面业务逻辑则支持ECMAScript规范的JavaScript语言。JS UI框架提供的类Web编程范式,可以让开发者避免编写UI状态切换的代码,视图配置信息更加直观。 -- **类Web范式编程** - - JS UI框架采用类HTML和CSS Web编程语言作为页面布局和页面样式的开发语言,页面业务逻辑则支持ECMAScript规范的JavaScript语言。JS UI框架提供的类Web编程范式,可以让开发者避免编写UI状态切换的代码,视图配置信息更加直观。 - - - -## 整体架构 +## 整体架构 JS UI框架包括应用层(Application)、前端框架层(Framework)、引擎层(Engine)和平台适配层(Porting Layer)。 -![](figures/zh-cn_image_0000001077953992.png) - -- **Application** - - 应用层表示开发者使用JS UI框架开发的FA应用,这里的FA应用特指JS FA应用。 - -- **Framework** - 前端框架层主要完成前端页面解析,以及提供MVVM(Model-View-ViewModel)开发模式、页面路由机制和自定义组件等能力。 -- **Engine** +![zh-cn_image_0000001166426358](figures/zh-cn_image_0000001166426358.png) - 引擎层主要提供动画解析、DOM(Document Object Model)树构建、布局计算、渲染命令构建与绘制、事件管理等能力。 +- **Application**
+ 应用层表示开发者使用JS UI框架开发的FA应用,这里的FA应用特指JS FA应用。 -- **Porting Layer** +- **Framework**
+ 前端框架层主要完成前端页面解析,以及提供MVVM(Model-View-ViewModel)开发模式、页面路由机制和自定义组件等能力。 - 适配层主要完成对平台层进行抽象,提供抽象接口,可以对接到系统平台。比如:事件对接、渲染管线对接和系统生命周期对接等。 +- **Engine**
+ 引擎层主要提供动画解析、DOM(Document Object Model)树构建、布局计算、渲染命令构建与绘制、事件管理等能力。 +- **Porting Layer**
+ 适配层主要完成对平台层进行抽象,提供抽象接口,可以对接到系统平台。比如:事件对接、渲染管线对接和系统生命周期对接等。 diff --git a/zh-cn/application-dev/ui/ui-js.md b/zh-cn/application-dev/ui/ui-js.md index 11cacfcb1d4..88a6092003a 100644 --- a/zh-cn/application-dev/ui/ui-js.md +++ b/zh-cn/application-dev/ui/ui-js.md @@ -1,9 +1,9 @@ -# JS UI框架 +# JS UI框架 -- **[JS UI框架概述](ui-js-overview.md)** -- **[构建用户界面](ui-js-building-ui.md)** +- **[JS UI框架概述](ui-js-overview.md)** -- **[自定义组件](ui-js-custom-components.md)** +- **[构建用户界面](ui-js-building-ui.md)** +- **[自定义组件](ui-js-custom-components.md)** -- Gitee