提交 8f9059c7 编写于 作者: W wangqingkaihong

检视修改

Signed-off-by: Nwangqingkaihong <wangqing@kaihong.com>
上级 0196fee3
......@@ -2,7 +2,9 @@
## 场景说明
两台设备组网,实现修改文件时两个设备同时绘制的分布式画布场景有助于加快工作效率,减少工作中的冗余,本例将为大家介绍如何实现上述功能。
两台设备组网,当其中一个设备修改文件时,两个设备可以同步修改的结果。分布式场景可以在协同办公(如多人多设备编辑同一文件),设备文档更新(分布式设备更新文件内容,所有设备同步更新)中发挥重要作用,有助于加快工作效率,减少工作中的冗余。
本示例将为大家介绍如何实现上述功能。
## 效果呈现
......@@ -40,12 +42,12 @@
## 开发步骤
1.申请所需权限
1. 申请所需权限
在model.json5中添加以下配置:
在model.json5中添加以下配置:
```json
"requestPermissions": [
```json
"requestPermissions": [
{
"name": "ohos.permission.DISTRIBUTED_DATASYNC"//允许不同设备间的数据交换
},
......@@ -53,14 +55,20 @@
"name": "ohos.permission.ACCESS_SERVICE_DM"//允许系统应用获取分布式设备的认证组网能力
}
]
```
```
2. 构建UI框架
indexCanvas页面:
2.构建UI框架
TitleBar组件呈现标题栏。通过数据懒加载的方式遍历绘制的图形。被划出可视区域外的资源会被回收。
indexCanvas页面:
绘制ellipse图形、rect图形的按钮使用Button组件呈现。
```typescript
build() {
返回按钮、删除按钮也通过Button组件呈现。
```typescript
build() {
Column() {
TitleBar({ rightBtn: $r('app.media.trans'), onRightBtnClicked: this.showDialog })
//自/common/TitleBar.ets中引入标题栏相关。点击标题栏中的右侧按钮会调用showDialog()函数连接组网设备
......@@ -148,14 +156,16 @@ build() {
.justifyContent(FlexAlign.Center)
.alignItems(HorizontalAlign.Center)
}
}
```
}
```
2.数据model
3. 数据model
```
//BasicDataSource.ets
class BasicDataSource implements IDataSource {
通过registerDataChangeListener进行对数据变动的监听,数据发生变化时,调用notifyDataReload方法通知数据已经准备就绪。
```typescript
//BasicDataSource.ets
class BasicDataSource implements IDataSource {
private listeners: DataChangeListener[] = []
public totalCount(): number {
......@@ -182,7 +192,7 @@ class BasicDataSource implements IDataSource {
}
}
//数据reloaded,分布式数据数值变化需要调用这个接口重载下
//数据reloaded,分布式数据数值变化需要调用这个接口重载下
notifyDataReload(): void {
this.listeners.forEach(listener => {
listener.onDataReloaded()
......@@ -197,7 +207,7 @@ class BasicDataSource implements IDataSource {
....
export class CanvasDataSource extends BasicDataSource {
export class CanvasDataSource extends BasicDataSource {
//监听的数据类型
private pathArray: Canvas[] = []
......@@ -219,13 +229,15 @@ export class CanvasDataSource extends BasicDataSource {
this.pathArray.push(data)
this.notifyDataAdd(this.pathArray.length - 1)
}
}
```
}
```
3.将两台设备组网
4. 将两台设备组网
```typescript
showDialog = () => {
使用自RemoteDeviceModel.ts中引入的类RemoteDeviceModel以扫描获得附近可以连接的设备。
```typescript
showDialog = () => {
//RemoteDeviceModel引入自model/RemoteDeviceModel.ts
RemoteDeviceModel.registerDeviceListCallback(() => {
//得到附近可信的设备列表
......@@ -246,10 +258,10 @@ showDialog = () => {
this.dialogController.open()
})
}
....................................
//model/RemoteDeviceModel.ts
import deviceManager from '@ohos.distributedHardware.deviceManager'
registerDeviceListCallback(stateChangeCallback: () => void) {
....................................
//model/RemoteDeviceModel.ts
import deviceManager from '@ohos.distributedHardware.deviceManager'
registerDeviceListCallback(stateChangeCallback: () => void) {
if (typeof (this.deviceManager) !== 'undefined') {
this.registerDeviceListCallbackImplement(stateChangeCallback)
return
......@@ -271,7 +283,7 @@ registerDeviceListCallback(stateChangeCallback: () => void) {
Logger.info(TAG, 'deviceManager.createDeviceManager end')
}
registerDeviceListCallbackImplement(stateChangeCallback: () => void) {
registerDeviceListCallbackImplement(stateChangeCallback: () => void) {
Logger.info(TAG, 'registerDeviceListCallback')
this.stateChangeCallback = stateChangeCallback
if (this.deviceManager === undefined) {
......@@ -334,7 +346,7 @@ registerDeviceListCallbackImplement(stateChangeCallback: () => void) {
}
this.startDeviceDiscovery()
}
startDeviceDiscovery() {
startDeviceDiscovery() {
SUBSCRIBE_ID = Math.floor(65536 * Math.random())
var info = {
subscribeId: SUBSCRIBE_ID,
......@@ -353,13 +365,16 @@ startDeviceDiscovery() {
}
}
```
```
5. 实现同步编辑
4.实现同步编辑
通过AppStorage设置持久性数据,然后实现IDataSource接口,通过注册数据监听接口监听数据的变化。
```typescript
onPageShow() {
```typescript
onPageShow() {
//每当完成编辑或者新建文件,就会回到主页,此时就会执行onPageShow()
//noteDataSource获取globalObject保存的分布式的持久性数据,并进行Reload操作传递。
this.noteDataSource['dataArray'] = this.globalObject.distributedObject.documents
this.noteDataSource.notifyDataReload()
Logger.info(TAG, `this.sessionId = ${this.sessionId}`)
......@@ -369,8 +384,8 @@ onPageShow() {
this.share()
}
}
share() {
//多个设备间的对象如果设置为同一个sessionId的笔记数据自动同步
share() {
//多个设备间的对象如果设置为同一个sessionId,数据自动同步
Logger.info(TAG, `sessionId = ${this.sessionId}`)
this.globalObject.setChangeCallback(() => {
this.noteDataSource['dataArray'] = this.globalObject.distributedObject.documents
......@@ -387,11 +402,11 @@ share() {
this.globalObject.distributedObject.setSessionId(this.sessionId)
AppStorage.SetOrCreate('objectModel', this.globalObject)
}
```
```
## 全部代码
本例完整代码sample示例链接:[分布式文件](https://gitee.com/openharmony/applications_app_samples/tree/master/code/SuperFeature/DistributedAppDev/DistributedNote)
本例完整代码sample示例链接:[分布式对象](https://gitee.com/openharmony/applications_app_samples/tree/master/code/SuperFeature/DistributedAppDev/DistributedNote)
## 参考
......
......@@ -2,7 +2,7 @@
## 场景说明
两台设备组网,实现修改文件时两个设备同时修改的分布式文件场景有助于加快工作效率,减少工作中的冗余,本例将为大家介绍如何实现上述功能。
两台设备组网的分布式场景是工作中常常需要的。常见的如代码的同步编辑、文档的同步修改等。这样的分布式场景有助于加快工作效率,减少工作中的冗余,本例将为大家介绍如何实现上述功能。
## 效果呈现
......@@ -40,12 +40,12 @@
## 开发步骤
1.申请所需权限
1. 申请所需权限
在model.json5中添加以下配置:
```json
"requestPermissions": [
```json
"requestPermissions": [
{
"name": "ohos.permission.DISTRIBUTED_DATASYNC"//允许不同设备间的数据交换
},
......@@ -53,15 +53,16 @@
"name": "ohos.permission.ACCESS_SERVICE_DM"//允许系统应用获取分布式设备的认证组网能力
}
]
```
```
2.构建UI框架
2. 构建UI框架
indexNote页面:
index页面:
```typescript
TitleBar组件呈现标题栏。使用List组件呈现文件列表,ListItem由一个呈现文件类型标志的Image组件,一个呈现文件标题的Text组件,一个呈现文件内容的Text组件组成。
build() {
```typescript
build() {
Column() {
TitleBar({ rightBtn: $r('app.media.trans'), onRightBtnClicked: this.showDialog })
//自/common/TitleBar.ets中引入标题栏相关。点击标题栏中的右侧按钮会调用showDialog()函数连接组网设备
......@@ -132,15 +133,15 @@ build() {
.height('100%')
.backgroundColor('#F5F5F5')
}
}
....................................
//common/NoteItem.ets
import router from '@ohos.router'
import { MARKS } from '../model/Const'
import Note from '../model/Note'
}
...
//common/NoteItem.ets
import router from '@ohos.router'
import { MARKS } from '../model/Const'
import Note from '../model/Note'
@Component
export default struct NoteItem {
@Component
export default struct NoteItem {
@State note: Note | undefined = undefined
private index: number = 0
......@@ -181,13 +182,15 @@ export default struct NoteItem {
})
})
}
}
```
}
```
Edit页面:
Edit页面:
```typescript
build() {
使用TextInput组件呈现文件标题输入框,使用TextArea组件呈现文件内容的输入区域,使用Button组件呈现保存按钮并绑定点击事件以新建或更新文件内容。
```typescript
build() {
Column() {
TitleBar({ title: this.note.title === '' ? $r('app.string.add_note') : this.note.title })
Column() {
......@@ -260,13 +263,15 @@ build() {
.height('100%')
.backgroundColor('#F5F5F5')
}
}
```
}
```
3.将两台设备组网
3. 将两台设备组网
```typescript
showDialog = () => {
使用自RemoteDeviceModel.ts中引入的类RemoteDeviceModel以扫描获得附近可以连接的设备。
```typescript
showDialog = () => {
//RemoteDeviceModel引入自model/RemoteDeviceModel.ts
RemoteDeviceModel.registerDeviceListCallback(() => {
//得到附近可信的设备列表
......@@ -287,10 +292,10 @@ showDialog = () => {
this.dialogController.open()
})
}
....................................
//model/RemoteDeviceModel.ts
import deviceManager from '@ohos.distributedHardware.deviceManager'
registerDeviceListCallback(stateChangeCallback: () => void) {
...
//model/RemoteDeviceModel.ts
import deviceManager from '@ohos.distributedHardware.deviceManager'
registerDeviceListCallback(stateChangeCallback: () => void) {
if (typeof (this.deviceManager) !== 'undefined') {
this.registerDeviceListCallbackImplement(stateChangeCallback)
return
......@@ -312,7 +317,7 @@ registerDeviceListCallback(stateChangeCallback: () => void) {
Logger.info(TAG, 'deviceManager.createDeviceManager end')
}
registerDeviceListCallbackImplement(stateChangeCallback: () => void) {
registerDeviceListCallbackImplement(stateChangeCallback: () => void) {
Logger.info(TAG, 'registerDeviceListCallback')
this.stateChangeCallback = stateChangeCallback
if (this.deviceManager === undefined) {
......@@ -375,7 +380,7 @@ registerDeviceListCallbackImplement(stateChangeCallback: () => void) {
}
this.startDeviceDiscovery()
}
startDeviceDiscovery() {
startDeviceDiscovery() {
SUBSCRIBE_ID = Math.floor(65536 * Math.random())
var info = {
subscribeId: SUBSCRIBE_ID,
......@@ -394,13 +399,50 @@ startDeviceDiscovery() {
}
}
```
```
4. 实现同步编辑
通过AppStorage设置持久性数据,然后实现IDataSource接口,通过注册数据监听接口监听数据的变化。
4.实现同步编辑
```typescript
class BasicDataSource implements IDataSource {
private listeners: DataChangeListener[] = []
```typescript
onPageShow() {
public totalCount(): number {
return 0
}
public getData(index: number): any {
return undefined
}
registerDataChangeListener(listener: DataChangeListener): void {
if (this.listeners.indexOf(listener) < 0) {
console.info('add listener')
this.listeners.push(listener)
}
}
unregisterDataChangeListener(listener: DataChangeListener): void {
const pos = this.listeners.indexOf(listener);
if (pos >= 0) {
console.info('remove listener')
this.listeners.splice(pos, 1)
}
}
//数据准备好了
notifyDataReload(): void {
this.listeners.forEach(listener => {
listener.onDataReloaded()
})
}
...
}
onPageShow() {
//每当完成编辑或者新建文件,就会回到主页,此时就会执行onPageShow()
//noteDataSource获取globalObject保存的分布式的持久性数据,并进行Reload操作传递。
this.noteDataSource['dataArray'] = this.globalObject.distributedObject.documents
this.noteDataSource.notifyDataReload()
Logger.info(TAG, `this.sessionId = ${this.sessionId}`)
......@@ -410,7 +452,7 @@ onPageShow() {
this.share()
}
}
share() {
share() {
//多个设备间的对象如果设置为同一个sessionId的笔记数据自动同步
Logger.info(TAG, `sessionId = ${this.sessionId}`)
this.globalObject.setChangeCallback(() => {
......@@ -428,14 +470,13 @@ share() {
this.globalObject.distributedObject.setSessionId(this.sessionId)
AppStorage.SetOrCreate('objectModel', this.globalObject)
}
```
```
## 全部代码
本例完整代码sample示例链接:[分布式文件](https://gitee.com/openharmony/applications_app_samples/tree/master/code/SuperFeature/DistributedAppDev/DistributedNote)
本例完整代码sample示例链接:[分布式对象](https://gitee.com/openharmony/applications_app_samples/tree/master/code/SuperFeature/DistributedAppDev/DistributedNote)
## 参考
[权限列表](https://gitee.com/openharmony/docs/blob/master/zh-cn/application-dev/security/permission-list.md#ohospermissiondistributed_datasync)
[分布式数据对象](../application-dev/reference/apis/js-apis-data-distributedobject.md)
- [权限列表](../application-dev/security/permission-list.md#ohospermissiondistributed_datasync)
- [分布式数据对象](../application-dev/reference/apis/js-apis-data-distributedobject.md)
......@@ -8,10 +8,16 @@
本例效果如下:
![contactlist](figures/camera.png)
| 拍照 | 预览 |
| :----------------------------------------------------------: | :----------------------------------------------------------: |
| <img src="figures/camera.png" alt="contactlist" style="zoom: 45%;" /> | <img src="figures/camerapreview.gif" alt="contactlist" style="zoom: 50%;" /> |
## 运行环境
本例基于以下环境开发,开发者也可以基于其他适配的版本进行开发。
- IDE:DevEco Studio 4.0.0.201 Beta1
- SDK:Ohos_sdk_public 4.0.7.5 (API Version 10 Beta1)
......@@ -19,22 +25,18 @@
本例使用@ohos.multimedia.camera接口实现相机示例的主要功能:拍照、预览;
使用@ohos.multimedia.image接口实现图片接收;
使用@ohos.multimedia.mediaLibrary接口实现对媒体文件的存储。
- 拍照:XComponent组件负责绘制摄像头画面呈现的窗口,其onload事件调用cameraModel.ts的initCamera方法初始化相机功能输出画面信息。拍照动作使用Image组件实现,其onclick事件调用cameraModel.ts的takepicture方法开始拍照。
- XComponent组件负责绘制摄像头画面呈现的窗口,其onload事件调用cameraModel.ts的initCamera方法初始化相机功能输出预览信息。
- 拍照按钮:使用Image组件实现,其onclick事件调用cameraModel.ts的takepicture方法开始拍照。
- 照片存储:MediaModel.ts中的createAndGetUri方法通过引用自@ohos.multimedia.mediaLibrary的mediaLibraryTest类创建媒体资源,saveImage方法将拍摄的照片写入到Mediamodel传回的资源中去。
- 预览:返回相机界面点击底部左侧预览图可进入相册应用,可以在其中查看照片和录制的视频。
## 开发步骤
1.申请所需权限
1. 申请所需权限
在model.json5中添加以下配置:
在model.json5中添加以下配置:
```json
"requestPermissions": [
```json
"requestPermissions": [
{
"name": "ohos.permission.CAMERA"//允许应用使用相机拍摄照片和录制视频
},
......@@ -51,12 +53,12 @@
"name": "ohos.permission.READ_MEDIA"//允许应用读取用户外部存储中的媒体文件信息
}
]
```
```
2.创建绘制组件XComponent
2. 创建绘制组件XComponent以输出摄像头获取的画面,其绑定的onload方法中设定了画幅的大小。
```typescript
build() {
```typescript
build() {
Column() {
Title()
.visibility(this.isTitleShow ? Visibility.Visible : Visibility.None)
......@@ -80,16 +82,18 @@ build() {
}
.width('97%')
.height('100%')
```
```
3.初始化相机功能
3. 初始化相机功能
```typescript
import image from '@ohos.multimedia.image';//自@ohos.multimedia.image引入image,提供图片处理效果
..................
private receiver: image.ImageReceiver = undefined;//图像接收类,用于获取组件surface id,接收最新的图片和读取下一张图片
..................
constructor() {
initCamera方法通过创建相机管理器实例cameraMgr来创建画面输出对象previewOutput。cameraMgr再通过创建CaptureSession实例来配置会话,完成相机功能的准备工作。
```typescript
import image from '@ohos.multimedia.image';//自@ohos.multimedia.image引入image,提供图片处理效果
...
private receiver: image.ImageReceiver = undefined;//图像接收类,用于获取组件surface id,接收最新的图片和读取下一张图片
...
constructor() {
this.mediaModel = MediaModel.getMediaInstance();//通过调用model/MediaModel.ets中的方法创建mediaInstance类mediaModel
//创建ImageReceiver实例receiver
this.receiver = image.createImageReceiver(
......@@ -121,8 +125,8 @@ constructor() {
}
async initCamera(surfaceId: string): Promise<void> {
..................
async initCamera(surfaceId: string): Promise<void> {
...
try {
this.cameraMgr = camera.getCameraManager(globalThis.cameraContext);//获取相机管理器实例
}
......@@ -156,12 +160,14 @@ async initCamera(surfaceId: string): Promise<void> {
await this.capSession.start();//开始输出
}
```
```
4. 点击按钮进行拍照
4.点击按钮进行拍照
拍照按钮通过Image组件呈现,其绑定的onClick方法调用takePicture方法开始拍照。
```typescript
Image(this.getCameraIcon())
```typescript
Image(this.getCameraIcon())
.size({ width: 64, height: 64 })
.margin({ left: 10 })
.id('camera')
......@@ -171,11 +177,11 @@ Image(this.getCameraIcon())
this.cameraModel.takePicture();//调用model/cameraModel.takePicture()开始拍照
}
})
```
```
5.拍照功能具体实现
5. 拍照功能具体实现
- 拍照
- 拍照
```typescript
async takePicture(): Promise<void> {
......@@ -196,10 +202,12 @@ Image(this.getCameraIcon())
}
```
- 保存图片
- 保存图片
saveImage方法使用MediaModel中的createAndGetUri方法创建Image类型资源,将拍摄到的照片写入到这个资源中去。
```typescript
..................//model/MediaModel.ts中定义的负责保存图片的相关方法
//model/MediaModel.ts中定义的负责保存图片的相关方法
async createAndGetUri(mediaType: mediaLibrary.MediaType): Promise<mediaLibrary.FileAsset> {
let dateTimeUtil: DateTimeUtil = new DateTimeUtil();
let info: FileInfo = this.getInfoFromMediaType(mediaType);
......@@ -220,7 +228,7 @@ Image(this.getCameraIcon())
let fd: number = await fileAsset.open('Rw');//打开当前文件
return fd;
}
..................
...
async saveImage(buffer: ArrayBuffer, img: image.Image): Promise<void> {
this.fileAsset = await this.mediaModel.createAndGetUri(mediaLibrary.MediaType.IMAGE);
......@@ -242,7 +250,8 @@ Image(this.getCameraIcon())
## 参考
[权限列表](https://gitee.com/openharmony/docs/blob/master/zh-cn/application-dev/security/permission-list.md#ohospermissiondistributed_datasync)
- [权限列表](https://gitee.com/openharmony/docs/blob/master/zh-cn/application-dev/security/permission-list.md#ohospermissiondistributed_datasync)
- [@ohos.multimedia.camera](../application-dev/reference/apis/js-apis-camera.md)
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册