MultiMedia应用接口下架整改

Signed-off-by: 王鑫 <wangxin601@huawei.com>
This commit is contained in:
王鑫 2024-07-08 18:03:12 +08:00
parent dd60ab1ad6
commit 906897415f
31 changed files with 1056 additions and 843 deletions

View File

@ -16,10 +16,10 @@
{
"app": {
"signingConfigs": [],
"compileSdkVersion": 9,
"compatibleSdkVersion": 9,
"products": [
{
"compileSdkVersion": 10,
"compatibleSdkVersion": 10,
"name": "default",
"signingConfig": "default",
}

View File

@ -15,12 +15,12 @@
import camera from '@ohos.multimedia.camera'
import deviceInfo from '@ohos.deviceInfo'
import fileio from '@ohos.fileio'
import fileio from '@ohos.file.fs'
import image from '@ohos.multimedia.image'
import media from '@ohos.multimedia.media'
import mediaLibrary from '@ohos.multimedia.mediaLibrary'
import userFileManager from '@ohos.filemanagement.userFileManager'
import Logger from '../model/Logger'
import MediaUtils from '../model/MediaUtils'
import MediaUtils, { FileType } from '../model/MediaUtils'
const CameraMode = {
MODE_PHOTO: 0, // 拍照模式
@ -45,7 +45,7 @@ export default class CameraService {
private captureSession: camera.CaptureSession = undefined
private mReceiver: image.ImageReceiver = undefined
private photoUri: string = ''
private fileAsset: mediaLibrary.FileAsset = undefined
private fileAsset: userFileManager.FileAsset = undefined
private fd: number = -1
private curMode = CameraMode.MODE_PHOTO
private videoRecorder: media.VideoRecorder = undefined
@ -110,7 +110,7 @@ export default class CameraService {
async savePicture(buffer: ArrayBuffer, img: image.Image) {
Logger.info(this.tag, 'savePicture')
this.fileAsset = await this.mediaUtil.createAndGetUri(mediaLibrary.MediaType.IMAGE)
this.fileAsset = await this.mediaUtil.createAndGetUri(FileType.IMAGE)
this.photoUri = this.fileAsset.uri
Logger.info(this.tag, `this.photoUri = ${this.photoUri}`)
this.fd = await this.mediaUtil.getFdPath(this.fileAsset)
@ -133,9 +133,9 @@ export default class CameraService {
} else {
this.videoConfig.videoSourceType = 0
}
this.cameraManager = await camera.getCameraManager(this.context)
this.cameraManager = camera.getCameraManager(this.context)
Logger.info(this.tag, 'getCameraManager')
this.cameras = await this.cameraManager.getSupportedCameras()
this.cameras = this.cameraManager.getSupportedCameras()
Logger.info(this.tag, `get cameras ${this.cameras.length}`)
if (this.cameras.length === 0) {
Logger.info(this.tag, 'cannot get cameras')
@ -143,23 +143,23 @@ export default class CameraService {
}
let cameraDevice = this.cameras[0]
this.cameraInput = await this.cameraManager.createCameraInput(cameraDevice)
this.cameraInput = this.cameraManager.createCameraInput(cameraDevice)
this.cameraInput.open()
Logger.info(this.tag, 'createCameraInput')
this.cameraOutputCapability = await this.cameraManager.getSupportedOutputCapability(cameraDevice)
this.cameraOutputCapability = this.cameraManager.getSupportedOutputCapability(cameraDevice)
let previewProfile = this.cameraOutputCapability.previewProfiles[0]
this.previewOutput = await this.cameraManager.createPreviewOutput(previewProfile, surfaceId)
this.previewOutput = this.cameraManager.createPreviewOutput(previewProfile, surfaceId)
Logger.info(this.tag, 'createPreviewOutput')
let mSurfaceId = await this.mReceiver.getReceivingSurfaceId()
let photoProfile = this.cameraOutputCapability.photoProfiles[0]
this.photoOutPut = await this.cameraManager.createPhotoOutput(photoProfile, mSurfaceId)
this.captureSession = await this.cameraManager.createCaptureSession()
let profile = this.cameraOutputCapability.photoProfiles[0]
this.photoOutPut = this.cameraManager.createPhotoOutput(profile, mSurfaceId)
this.captureSession = this.cameraManager.createCaptureSession()
Logger.info(this.tag, 'createCaptureSession')
await this.captureSession.beginConfig()
this.captureSession.beginConfig()
Logger.info(this.tag, 'beginConfig')
await this.captureSession.addInput(this.cameraInput)
await this.captureSession.addOutput(this.previewOutput)
await this.captureSession.addOutput(this.photoOutPut)
this.captureSession.addInput(this.cameraInput)
this.captureSession.addOutput(this.previewOutput)
this.captureSession.addOutput(this.photoOutPut)
await this.captureSession.commitConfig()
await this.captureSession.start()
Logger.info(this.tag, 'captureSession start')
@ -186,37 +186,36 @@ export default class CameraService {
}
await this.photoOutPut.capture(photoSettings)
Logger.info(this.tag, 'takePicture done')
AppStorage.Set('isRefresh', true)
}
async startVideo() {
Logger.info(this.tag, 'startVideo begin')
await this.captureSession.stop()
await this.captureSession.beginConfig()
this.captureSession.beginConfig()
if (this.curMode === CameraMode.MODE_PHOTO) {
this.curMode = CameraMode.MODE_VIDEO
if (this.photoOutPut) {
await this.captureSession.removeOutput(this.photoOutPut)
this.captureSession.removeOutput(this.photoOutPut)
this.photoOutPut.release()
}
} else {
if (this.videoOutput) {
await this.captureSession.removeOutput(this.videoOutput)
this.captureSession.removeOutput(this.videoOutput)
}
}
if (this.videoOutput) {
await this.captureSession.removeOutput(this.videoOutput)
this.captureSession.removeOutput(this.videoOutput)
await this.videoOutput.release()
}
this.fileAsset = await this.mediaUtil.createAndGetUri(mediaLibrary.MediaType.VIDEO)
this.fileAsset = await this.mediaUtil.createAndGetUri(FileType.VIDEO)
this.fd = await this.mediaUtil.getFdPath(this.fileAsset)
this.videoRecorder = await media.createVideoRecorder()
this.videoConfig.url = `fd://${this.fd}`
await this.videoRecorder.prepare(this.videoConfig)
let videoId = await this.videoRecorder.getInputSurface()
let videoProfile = this.cameraOutputCapability.videoProfiles[0];
this.videoOutput = await this.cameraManager.createVideoOutput(videoProfile, videoId)
await this.captureSession.addOutput(this.videoOutput)
let profile = this.cameraOutputCapability.videoProfiles[0];
this.videoOutput = this.cameraManager.createVideoOutput(profile, videoId)
this.captureSession.addOutput(this.videoOutput)
await this.captureSession.commitConfig()
await this.captureSession.start()
await this.videoOutput.start()

View File

@ -12,13 +12,23 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import mediaLibrary from '@ohos.multimedia.mediaLibrary'
import userFileManager from '@ohos.filemanagement.userFileManager'
import fileAccess from '@ohos.file.fileAccess';
import dataSharePredicates from '@ohos.data.dataSharePredicates';
import DateTimeUtil from '../model/DateTimeUtil'
import Logger from '../model/Logger'
import common from '@ohos.app.ability.common';
export enum FileType {
IMAGE = 1,
VIDEO = 2,
AUDIO = 3,
FILE= 4
}
export default class MediaUtils {
private tag: string = 'MediaUtils'
private mediaTest: mediaLibrary.MediaLibrary = undefined
private mediaTest: userFileManager.UserFileManager = undefined
private static instance: MediaUtils = undefined
public static getInstance(context: any) {
@ -29,33 +39,24 @@ export default class MediaUtils {
}
constructor(context: any) {
this.mediaTest = mediaLibrary.getMediaLibrary(context)
this.mediaTest = userFileManager.getUserFileMgr(context)
}
async createAndGetUri(mediaType: number) {
async createAndGetUri(mediaType: number): Promise<userFileManager.FileAsset> {
let info = this.getInfoFromType(mediaType)
let dateTimeUtil = new DateTimeUtil()
let name = `${dateTimeUtil.getDate()}_${dateTimeUtil.getTime()}`
let displayName = `${info.prefix}${name}${info.suffix}`
Logger.info(this.tag, `displayName = ${displayName},mediaType = ${mediaType}`)
let publicPath = await this.mediaTest.getPublicDirectory(info.directory)
Logger.info(this.tag, `publicPath = ${publicPath}`)
return await this.mediaTest.createAsset(mediaType, displayName, publicPath)
}
async queryFile(dataUri: any) {
let fileKeyObj = mediaLibrary.FileKey
if (dataUri !== undefined) {
let args = dataUri.id.toString()
let fetchOp = {
selections: `${fileKeyObj.ID}=?`,
selectionArgs: [args],
}
const fetchFileResult = await this.mediaTest.getFileAssets(fetchOp)
Logger.info(this.tag, `fetchFileResult.getCount() = ${fetchFileResult.getCount()}`)
const fileAsset = await fetchFileResult.getAllObject()
return fileAsset[0]
let fetchFileResult: userFileManager.FileAsset = undefined;
// 新建音频资源
if (mediaType === FileType.AUDIO) {
fetchFileResult = await this.mediaTest.createAudioAsset(displayName);
} else {
// 新建图片/视频资源
fetchFileResult = await this.mediaTest.createPhotoAsset(displayName);
}
return fetchFileResult;
}
async getFdPath(fileAsset: any) {
@ -64,121 +65,148 @@ export default class MediaUtils {
return fd
}
async createFile(mediaType: number) {
let dataUri = await this.createAndGetUri(mediaType)
if (dataUri) {
let fileAsset = await this.queryFile(dataUri)
if (fileAsset) {
let fd = await this.getFdPath(fileAsset)
return fd
}
}
}
async getFileAssetsFromType(mediaType: number) {
Logger.info(this.tag, `getFileAssetsFromType,mediaType = ${mediaType}`);
let fileKeyObj = mediaLibrary.FileKey;
let fileAssets = [];
async createFile(mediaType: number, context: common.UIAbilityContext) {
let info = this.getInfoFromType(mediaType)
let dateTimeUtil = new DateTimeUtil()
let name = `${dateTimeUtil.getDate()}_${dateTimeUtil.getTime()}`
let displayName = `${info.prefix}${name}${info.suffix}`
Logger.info(this.tag, `displayName = ${displayName},mediaType = ${mediaType}`)
let fd: number = -1;
try {
let fetchOp = {
selections: `${fileKeyObj.MEDIA_TYPE}=?`,
selectionArgs: [`${mediaType}`],
};
const fetchFileResult = await this.mediaTest.getFileAssets(fetchOp);
Logger.info(this.tag, `getFileAssetsFromType,fetchFileResult.count = ${fetchFileResult.getCount()}`);
if (fetchFileResult.getCount() > 0) {
let fileAccessHelper = fileAccess.createFileAccessHelper(context);
// 获取目录url
let rootIterator: fileAccess.RootIterator = await fileAccessHelper.getRoots();
let sourceUri: string = rootIterator.next().value.uri
// 以异步方法创建文件到指定目录返回新文件uri
let fileUri = await fileAccessHelper.createFile(sourceUri, displayName);
Logger.info(this.tag, "createFile success, fileUri: " + JSON.stringify(fileUri));
// 以异步方法打开文件,返回文件描述符
fd = await fileAccessHelper.openFile(fileUri, fileAccess.OPENFLAGS.WRITE_READ);
Logger.info(this.tag, `openFile success, fd = ${fd}`)
} catch (err) {
Logger.info(this.tag, "createFile failed, err:" + JSON.stringify(err));
}
return fd;
}
async getFileAssetsFromType(mediaType: number): Promise<userFileManager.FileAsset[]> {
Logger.info(this.tag, `getFileAssetsFromType,mediaType = ${mediaType}`);
let fileAssets: Array<userFileManager.FileAsset> = [];
try {
let predicates: dataSharePredicates.DataSharePredicates = new dataSharePredicates.DataSharePredicates();
let fetchOptions: userFileManager.FetchOptions = {
fetchColumns: ['duration', 'date_added'],
predicates: predicates
}
let fetchFileResult: userFileManager.FetchResult<userFileManager.FileAsset> = undefined;
// 获取音频资源
if (mediaType === FileType.AUDIO) {
fetchFileResult = await this.mediaTest.getAudioAssets(fetchOptions);
fileAssets = await fetchFileResult.getAllObject();
} else {
// 获取图片/视频资源
fetchFileResult = await this.mediaTest.getPhotoAssets(fetchOptions);
fileAssets = await fetchFileResult.getAllObject();
// 过滤资源
fileAssets = fileAssets.filter(item => item.fileType === mediaType)
}
} catch (err) {
console.info(`LSQ: err ${JSON.stringify(err)}`);
Logger.info(this.tag, `err ${JSON.stringify(err)}`);
}
Logger.info(this.tag, `getFileAssetsFromType = ${mediaType},fileAssets.count = ${fileAssets.length}`);
return fileAssets
}
async getAlbums() {
async getFileAssets(context: common.UIAbilityContext): Promise<fileAccess.FileInfo[]> {
let isDone: boolean = false;
let fileInfos: Array<fileAccess.FileInfo> = [];
try {
let fileAccessHelper = fileAccess.createFileAccessHelper(context);
let rootIterator: fileAccess.RootIterator = await fileAccessHelper.getRoots();
// 获取目录url
let catalogueUrl: string = rootIterator.next().value.uri;
let fileInfo: fileAccess.FileInfo = await fileAccessHelper.getFileInfoFromUri(catalogueUrl);
let fileIterator = fileInfo.scanFile();
while (!isDone) {
let result = fileIterator.next();
isDone = result.done;
if (!isDone) {
fileInfos.push(result.value);
}
}
} catch (error) {
Logger.info(this.tag, "getRoots failed, errCode:" + error.code + ", errMessage:" + error.message);
}
return fileInfos;
}
async getAlbums(context: common.UIAbilityContext) {
Logger.info(this.tag, 'getAlbums begin')
let albums = []
const [ files, images, videos, audios ] = await Promise.all([
this.getFileAssetsFromType(mediaLibrary.MediaType.FILE),
this.getFileAssetsFromType(mediaLibrary.MediaType.IMAGE),
this.getFileAssetsFromType(mediaLibrary.MediaType.VIDEO),
this.getFileAssetsFromType(mediaLibrary.MediaType.AUDIO)
const [ images, videos, audios, fileInfos ] = await Promise.all([
this.getFileAssetsFromType(FileType.IMAGE),
this.getFileAssetsFromType(FileType.VIDEO),
this.getFileAssetsFromType(FileType.AUDIO),
this.getFileAssets(context)
])
albums.push({
albumName: 'Documents', count: files.length, mediaType: mediaLibrary.MediaType.FILE
albumName: 'Documents', count: fileInfos.length, mediaType: FileType.FILE
})
albums.push({
albumName: 'Pictures', count: images.length, mediaType: mediaLibrary.MediaType.IMAGE
albumName: 'Pictures', count: images.length, mediaType: FileType.IMAGE
})
albums.push({
albumName: 'Videos', count: videos.length, mediaType: mediaLibrary.MediaType.VIDEO
albumName: 'Videos', count: videos.length, mediaType: FileType.VIDEO
})
albums.push({
albumName: 'Audios', count: audios.length, mediaType: mediaLibrary.MediaType.AUDIO
albumName: 'Audios', count: audios.length, mediaType: FileType.AUDIO
})
return albums
}
deleteFile(fileAsset: mediaLibrary.FileAsset): Promise<void> {
return fileAsset.trash(true);
}
onDateChange(callback: () => void) {
this.mediaTest.on('albumChange', () => {
Logger.info(this.tag, 'albumChange called')
callback()
})
this.mediaTest.on('imageChange', () => {
Logger.info(this.tag, 'imageChange called')
callback()
})
this.mediaTest.on('audioChange', () => {
Logger.info(this.tag, 'audioChange called')
callback()
})
this.mediaTest.on('videoChange', () => {
Logger.info(this.tag, 'videoChange called')
callback()
})
this.mediaTest.on('fileChange', () => {
Logger.info(this.tag, 'fileChange called')
callback()
})
}
offDateChange() {
this.mediaTest.off('albumChange')
this.mediaTest.off('imageChange')
this.mediaTest.off('audioChange')
this.mediaTest.off('videoChange')
this.mediaTest.off('fileChange')
async deleteFile(mediaType: number, uri: string, context?: common.UIAbilityContext): Promise<void> {
// 删除文件资源
if (mediaType === 4 && context !== undefined) {
try {
let fileAccessHelper = fileAccess.createFileAccessHelper(context);
let code = await fileAccessHelper.delete(uri);
if (code != 0)
Logger.info(this.tag, `delete failed, code: ${code}`);
} catch (err) {
Logger.info(this.tag, `delete failed, err: ${err}`);
}
} else {
// 删除图片/视频/音频资源
return this.mediaTest.delete(uri);
}
}
getInfoFromType(mediaType: number) {
let result = {
prefix: '', suffix: '', directory: 0
prefix: '', suffix: ''
}
switch (mediaType) {
case mediaLibrary.MediaType.FILE:
result.prefix = 'FILE_'
result.suffix = '.txt'
result.directory = mediaLibrary.DirectoryType.DIR_DOCUMENTS
break
case mediaLibrary.MediaType.IMAGE:
case FileType.IMAGE:
result.prefix = 'IMG_'
result.suffix = '.jpg'
result.directory = mediaLibrary.DirectoryType.DIR_IMAGE
break
case mediaLibrary.MediaType.VIDEO:
case FileType.VIDEO:
result.prefix = 'VID_'
result.suffix = '.mp4'
result.directory = mediaLibrary.DirectoryType.DIR_VIDEO
break
case mediaLibrary.MediaType.AUDIO:
case FileType.AUDIO:
result.prefix = 'AUD_'
result.suffix = '.wav'
result.directory = mediaLibrary.DirectoryType.DIR_AUDIO
result.suffix = '.mp3'
break
default:
result.prefix = 'FILE_'
result.suffix = '.txt'
break
}
return result

View File

@ -15,60 +15,77 @@
import media from '@ohos.multimedia.media'
import Logger from '../model/Logger'
let audioConfig = {
audioSourceType: 1,
audioEncoder: 3,
audioEncodeBitRate: 22050,
audioSampleRate: 22050,
numberOfChannels: 2,
format: 6,
uri: ''
const avProfile = {
audioBitrate: 48000, // set audioBitrate according to device ability
audioChannels: 2, // set audioChannels, valid value 1-8
audioCodec: media.CodecMimeType.AUDIO_AAC, // set audioCodec, AUDIO_AAC is the only choice
audioSampleRate: 48000, // set audioSampleRate according to device ability
fileFormat: media.ContainerFormatType.CFT_MPEG_4A, // set fileFormat, for video is m4a
}
const audioConfig = {
audioSourceType: media.AudioSourceType.AUDIO_SOURCE_TYPE_MIC,
profile: avProfile,
url: 'fd://'
}
export default class RecordModel {
private tag: string = 'RecordModel'
private audioRecorder: media.AudioRecorder = undefined
private audioRecorder: media.AVRecorder = undefined
initAudioRecorder(handleStateChange: () => void) {
async initAudioRecorder(handleStateChange: () => void) {
this.release();
this.audioRecorder = media.createAudioRecorder()
this.audioRecorder = await media.createAVRecorder()
Logger.info(this.tag, 'create audioRecorder success')
this.audioRecorder.on('prepare', () => {
Logger.info(this.tag, 'setCallback prepare case callback is called')
this.audioRecorder.start()
})
this.audioRecorder.on('start', () => {
Logger.info(this.tag, 'setCallback start case callback is called')
handleStateChange()
})
this.audioRecorder.on('stop', () => {
Logger.info(this.tag, 'audioRecorder stop called')
this.audioRecorder.release()
})
this.audioRecorder.on('pause', () => {
Logger.info(this.tag, 'audioRecorder pause finish')
handleStateChange()
})
this.audioRecorder.on('resume', () => {
Logger.info(this.tag, 'audioRecorder resume finish')
handleStateChange()
})
this.audioRecorder.on('stateChange', (state, reason) => {
Logger.info(this.tag, 'case state has changed, new state is' + state);
switch (state) {
case 'idle':
break;
case 'prepared':
Logger.info(this.tag, 'setCallback prepare case callback is called')
this.audioRecorder.start()
break;
case 'started':
Logger.info(this.tag, 'setCallback start case callback is called')
handleStateChange()
break;
case 'paused':
Logger.info(this.tag, 'audioRecorder pause finish')
handleStateChange()
break;
case 'stopped':
Logger.info(this.tag, 'audioRecorder stop called')
break;
case 'released':
break;
case 'error':
Logger.info(this.tag, 'case error state!!!');
break;
default:
Logger.info(this.tag, 'case start is unknown');
break;
}
});
this.audioRecorder.on('error', (err) => {
Logger.info(this.tag, 'audioRecorder error:' + JSON.stringify(err))
});
}
release() {
async release() {
if (typeof (this.audioRecorder) !== `undefined`) {
Logger.info(this.tag, 'audioRecorder release')
this.audioRecorder.release()
this.audioRecorder = undefined
}
}
startRecorder(pathName: string) {
Logger.info(this.tag, `startRecorder, pathName = ${pathName}`)
async startRecorder(fd: number) {
Logger.info(this.tag, `startRecorder, fd = ${fd}`)
let fdPath = "fd://" + fd
if (typeof (this.audioRecorder) !== 'undefined') {
Logger.info(this.tag, 'start prepare')
audioConfig.uri = pathName
this.audioRecorder.prepare(audioConfig)
audioConfig.url = fdPath
await this.audioRecorder.prepare(audioConfig)
} else {
Logger.error(this.tag, 'case failed, audioRecorder is null')
}
@ -88,9 +105,15 @@ export default class RecordModel {
}
}
finish() {
async finish() {
if (typeof (this.audioRecorder) !== `undefined`) {
this.audioRecorder.stop()
// 1. 停止录制
await this.audioRecorder.stop()
// 2.重置
await this.audioRecorder.reset();
// 3.释放录制实例
await this.audioRecorder.release();
this.audioRecorder = undefined;
}
}
}

View File

@ -19,7 +19,7 @@ export function tempNum(num) {
return num.toString()
}
export function getDurationString(duration) {
export function getDurationString(duration: number) {
let hour = Math.floor(duration / (1000 * 60 * 60))
let minute = Math.floor((duration - hour * (1000 * 60 * 60)) / (1000 * 60))
let second = Math.floor((duration - hour * (1000 * 60 * 60) - minute * (60 * 1000)) / 1000)

View File

@ -13,69 +13,95 @@
* limitations under the License.
*/
import mediaLibrary from '@ohos.multimedia.mediaLibrary'
import userFileManager from '@ohos.filemanagement.userFileManager'
import fileAccess from '@ohos.file.fileAccess';
import router from '@ohos.router'
import Logger from '../model/Logger'
import MediaUtils from '../model/MediaUtils'
import MediaDataSource from '../view/BasicDataSource'
import MediaUtils, { FileType } from '../model/MediaUtils'
import MediaDataSource, { MediaData } from '../view/BasicDataSource'
import { MediaItem } from '../view/MediaItem'
import { RenameDialog } from '../view/RenameDialog'
import TitleBar from '../view/TitleBar'
import { BusinessError } from '@ohos.base'
import common from '@ohos.app.ability.common'
interface RouterParams {
albumName: string;
mediaType: number;
}
const context = getContext(this) as common.UIAbilityContext
@Entry
@Component
struct AlbumPage {
private tag: string = 'AlbumPage'
private albumName: string = <string> router.getParams()['albumName']
private mediaType: number = <number> router.getParams()['mediaType']
private albumName: string = (router.getParams() as RouterParams).albumName
private mediaType: number = (router.getParams() as RouterParams).mediaType
private mediaUtils: MediaUtils = MediaUtils.getInstance(getContext(this))
private renameDialogController: CustomDialogController = null
// @State mediaList: Array<mediaLibrary.FileAsset> = []
@State selectMedia: MediaData = {} as MediaData
private renameDialogController: CustomDialogController = new CustomDialogController({
builder: RenameDialog({
selectMedia: $selectMedia,
action: (selectMedia: MediaData) => this.renameMedia(selectMedia)
}),
autoCancel: true
});
private mediaDataSource: MediaDataSource = new MediaDataSource()
@State selectMedia: mediaLibrary.FileAsset = undefined
btnAction(operate, index, mediaItemId) {
Logger.info(this.tag, `btnAction callback,operate: ${operate}, index: ${index}`)
let selectMediaArray = this.mediaDataSource['dataArray'].filter((item) => {
return item.id === mediaItemId;
btnAction(operate: string, index: number, mediaItemUri: string): void {
Logger.info(this.tag, `btnAction callback,operate: ${operate}, index: ${index}, mediaItemUri: ${mediaItemUri}`)
let selectMediaArray = this.mediaDataSource.getDataArray().filter((item) => {
return item.uri === mediaItemUri;
});
this.selectMedia = selectMediaArray[0];
if (operate === 'delete') {
this.deleteMedia(() => {
this.mediaUtils.deleteFile(this.selectMedia);
this.mediaDataSource['dataArray'].forEach((item: mediaLibrary.FileAsset, index: number) => {
if (item.id === mediaItemId) {
this.mediaDataSource['dataArray'].splice(index, 1);
this.mediaUtils.deleteFile(this.mediaType, this.selectMedia.uri, context);
this.mediaDataSource.getDataArray().forEach((item: MediaData, index: number) => {
if (item.uri === mediaItemUri) {
this.mediaDataSource.deleteData(index, 1);
this.mediaDataSource.notifyDataReload();
}
})
})
} else {
if (this.renameDialogController === null) {
this.renameDialogController = new CustomDialogController({
builder: RenameDialog({ title: this.selectMedia.title, action: this.renameMedia.bind(this) }),
autoCancel: true
})
}
this.renameDialogController.open()
}
}
renameMedia(title) {
async renameMedia(selectMedia: MediaData): Promise<void> {
Logger.info(this.tag, `renameMedia newName = ${this.selectMedia.displayName}`)
this.selectMedia.title = title
this.selectMedia.commitModify(err => {
if (err !== undefined) {
// 重命名文件资源
if (this.mediaType === 4) {
let fileAccessHelper = fileAccess.createFileAccessHelper(context);
try {
await fileAccessHelper.rename(selectMedia.uri, selectMedia.displayName);
Logger.info(this.tag, 'commitModify success')
this.renameDialogController.close()
this.refreshData()
} catch (err) {
Logger.info(this.tag, `commitModify,err: ${err}`)
return
}
Logger.info(this.tag, 'commitModify success')
this.renameDialogController.close()
this.refreshData()
})
} else {
// 重命名图片/视频/音频资源
let fileAssetList: userFileManager.FileAsset[] = await this.mediaUtils.getFileAssetsFromType(this.mediaType)
let fileAsset: userFileManager.FileAsset | undefined = fileAssetList.find(item => item.uri === selectMedia.uri)
if (fileAsset !== undefined) {
try {
fileAsset.set('display_name', selectMedia.displayName)
await fileAsset.commitModify();
Logger.info(this.tag, 'commitModify success')
this.renameDialogController.close()
this.refreshData()
} catch (err) {
Logger.info(this.tag, `commitModify,err: ${err}`)
}
}
}
}
deleteMedia(deleteAction) {
deleteMedia(deleteAction: () => void) {
AlertDialog.show(
{
message: $r('app.string.delete_file'),
@ -97,14 +123,45 @@ struct AlbumPage {
}
refreshData() {
let fileAsset = this.mediaUtils.getFileAssetsFromType(this.mediaType)
fileAsset.then(fileList => {
Logger.info(this.tag, 'getFileList callback')
this.mediaDataSource['dataArray'] = fileList
this.mediaDataSource.notifyDataReload()
}).catch(err => {
Logger.error(this.tag, `getFileList err,err = ${err}`)
})
if (this.mediaType === 4) {
let fileInfos = this.mediaUtils.getFileAssets(context)
fileInfos.then(fileList => {
Logger.info(this.tag, 'getFileList callback')
let mediaDataList: MediaData[] = fileList.map(file => {
let mediaData: MediaData = {
uri: file.uri,
fileType: 4,
displayName: file.fileName,
duration: 0,
dateAdded: file.mtime
}
return mediaData
})
this.mediaDataSource.setDataArray(mediaDataList)
this.mediaDataSource.notifyDataReload()
}).catch((err: BusinessError) => {
Logger.error(this.tag, `getFileList err,err = ${err}`)
})
} else {
let fileAsset = this.mediaUtils.getFileAssetsFromType(this.mediaType)
fileAsset.then(fileList => {
Logger.info(this.tag, 'getFileList callback')
let mediaDataList: MediaData[] = fileList.map(file => {
let mediaData: MediaData = {
uri: file.uri,
fileType: file.fileType as number,
displayName: file.displayName,
duration: file.get('duration') as number,
dateAdded: file.get('date_added') as number
}
return mediaData
})
this.mediaDataSource.setDataArray(mediaDataList)
this.mediaDataSource.notifyDataReload()
}).catch((err: BusinessError) => {
Logger.error(this.tag, `getFileList err,err = ${err}`)
})
}
}
aboutToAppear() {
@ -116,21 +173,25 @@ struct AlbumPage {
Column() {
TitleBar({ title: this.albumName })
List() {
LazyForEach(this.mediaDataSource, (item, index) => {
LazyForEach(this.mediaDataSource, (item: MediaData, index) => {
ListItem() {
MediaItem({ media: item, index: index, btnAction: this.btnAction.bind(this) })
MediaItem({
media: item,
index: index,
btnAction: (operate, index, mediaItemUri) => this.btnAction(operate, index, mediaItemUri)
})
}
.id(`mediaId${index}`)
.onClick(() => {
if (item.mediaType === mediaLibrary.MediaType.VIDEO) {
Logger.info(this.tag, `onClick,item.id=${item.id}`)
let context = getContext(this) as any
console.log("item.fileType"+item.fileType)
if (item.fileType === FileType.VIDEO) {
Logger.info(this.tag, `onClick,item.id=${item.uri}`)
context.startAbility({
bundleName: 'ohos.samples.videoplayer',
abilityName: 'PlayAbility',
deviceId: "",
parameters: {
fileId: item.id
fileUri: item.uri
}
}, (error) => {
Logger.info(this.tag, `error.code = ${error.code}`)
@ -138,7 +199,7 @@ struct AlbumPage {
)
}
})
}, item => JSON.stringify(item.title))
}, (item: userFileManager.FileAsset) => JSON.stringify(item.displayName))
}
.layoutWeight(1)
}

View File

@ -12,12 +12,12 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import fileIo from '@ohos.fileio'
import mediaLibrary from '@ohos.multimedia.mediaLibrary'
import fileIo from '@ohos.file.fs'
import router from '@ohos.router'
import Logger from '../model/Logger'
import MediaUtils from '../model/MediaUtils'
import TitleBar from '../view/TitleBar'
import common from '@ohos.app.ability.common'
@Entry
@Component
@ -28,11 +28,11 @@ struct DocumentPage {
async saveFile() {
Logger.info(this.tag, 'saveFile')
let fd = await this.mediaUtils.createFile(mediaLibrary.MediaType.FILE)
let context = getContext(this) as common.UIAbilityContext
let fd: number = await this.mediaUtils.createFile(4, context)
Logger.info(this.tag, `fd = ${fd}`)
await fileIo.write(fd, this.fileContent)
await fileIo.close(fd)
AppStorage.Set('isRefresh', true)
router.back()
}

View File

@ -13,7 +13,6 @@
* limitations under the License.
*/
import mediaLibrary from '@ohos.multimedia.mediaLibrary';
import common from '@ohos.app.ability.common';
import Want from '@ohos.app.ability.Want';
import router from '@ohos.router';
@ -24,7 +23,12 @@ import Logger from '../model/Logger';
@Observed
export default class Album {
constructor(public albumName: string, public count: number, public mediaType?: mediaLibrary.MediaType) {
public albumName: string;
public count: number;
public mediaType?: string;
constructor(albumName: string, count: number, mediaType?: string) {
this.albumName = albumName;
this.count = count;
this.mediaType = mediaType;
@ -41,24 +45,8 @@ struct Index {
async onPageShow() {
this.albums = [];
this.albums = await this.mediaUtils.getAlbums();
}
@Builder OperateBtn(src, zIndex, translate, handleClick) {
Button() {
Image(src)
.width('70%')
.height('70%')
}
.type(ButtonType.Circle)
.width('40%')
.height('40%')
.backgroundColor('#0D9FFB')
.zIndex(zIndex)
.translate({ x: translate.x, y: translate.y })
.transition({ type: TransitionType.Insert, translate: { x: 0, y: 0 } })
.transition({ type: TransitionType.Delete, opacity: 0 })
.onClick(handleClick)
let context = getContext(this) as common.UIAbilityContext;
this.albums = await this.mediaUtils.getAlbums(context);
}
build() {
@ -71,7 +59,7 @@ struct Index {
MediaView({ album: item })
.id(`mediaType${index}`)
}
}, item => item.albumName)
}, (item: Album) => item.albumName)
}
.divider({ strokeWidth: 1, color: Color.Gray, startMargin: 16, endMargin: 16 })
.layoutWeight(1)
@ -167,8 +155,4 @@ struct Index {
.width('100%')
.height('100%')
}
aboutToDisappear() {
this.mediaUtils.offDateChange()
}
}

View File

@ -12,10 +12,10 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import mediaLibrary from '@ohos.multimedia.mediaLibrary'
import userFileManager from '@ohos.filemanagement.userFileManager'
import router from '@ohos.router'
import DateTimeUtil from '../model/DateTimeUtil'
import MediaUtils from '../model/MediaUtils'
import MediaUtils, { FileType } from '../model/MediaUtils'
import RecordModel from '../model/RecordModel'
import TitleBar from '../view/TitleBar'
@ -25,22 +25,18 @@ struct Record {
private recordModel: RecordModel = new RecordModel()
private isStartRecord: boolean = false
private mediaUtils: MediaUtils = MediaUtils.getInstance(getContext(this))
private intervalId: number = null
private fileAsset: mediaLibrary.FileAsset = undefined
private intervalId: number = -1
private fileAsset: userFileManager.FileAsset = {} as userFileManager.FileAsset
private fd: number = -1
@State format: string = 'hh:mm:ss.ms'
@State isRecording: boolean = false
@State millisecond: number = 0
async startRecord() {
let dataUri = await this.mediaUtils.createAndGetUri(mediaLibrary.MediaType.AUDIO)
if (dataUri) {
this.fileAsset = await this.mediaUtils.queryFile(dataUri)
this.fd = await this.mediaUtils.getFdPath(this.fileAsset)
let fdPath = "fd://" + this.fd
this.recordModel.startRecorder(fdPath)
this.isStartRecord = true
}
this.fileAsset = await this.mediaUtils.createAndGetUri(FileType.AUDIO)
this.fd = await this.mediaUtils.getFdPath(this.fileAsset)
this.recordModel.startRecorder(this.fd)
this.isStartRecord = true
}
getTime() {
@ -55,16 +51,14 @@ struct Record {
if (this.isRecording) {
if (this.intervalId) {
clearInterval(this.intervalId)
this.intervalId = null
}
if (this.isRecording) {
this.intervalId = setInterval(() => {
this.millisecond += 1000
}, 1000)
this.intervalId = -1
}
this.intervalId = setInterval(() => {
this.millisecond += 1000
}, 1000)
} else {
clearInterval(this.intervalId)
this.intervalId = null
this.intervalId = -1
}
}
@ -89,9 +83,13 @@ struct Record {
.backgroundColor('#FFFFFF')
.id('endOfRecording')
.onClick(() => {
router.back()
this.recordModel.finish()
AppStorage.Set('isRefresh', true)
this.isStartRecord = false
this.isRecording = false
// 关闭录制文件fd
this.fileAsset.close(this.fd).then(() =>{
router.back()
})
})
Blank()
@ -124,7 +122,6 @@ struct Record {
}
this.startRecord()
}
AppStorage.Set('isRefresh', true)
})
Blank()
@ -147,11 +144,11 @@ struct Record {
async aboutToDisappear() {
this.recordModel.finish()
if (this.fileAsset && this.millisecond < 1000) {
if (this.millisecond < 1000) {
if (this.fd !== -1) {
this.fileAsset.close(this.fd)
}
await this.mediaUtils.deleteFile(this.fileAsset)
await this.mediaUtils.deleteFile(FileType.AUDIO, this.fileAsset.uri)
}
}
}

View File

@ -13,7 +13,7 @@
* limitations under the License.
*/
import mediaLibrary from '@ohos.multimedia.mediaLibrary'
import userFileManager from '@ohos.filemanagement.userFileManager';
class BasicDataSource implements IDataSource {
private listeners: DataChangeListener[] = []
@ -22,8 +22,8 @@ class BasicDataSource implements IDataSource {
return 0
}
public getData(index: number): any {
return undefined
public getData(index: number): MediaData {
return {} as MediaData
}
registerDataChangeListener(listener: DataChangeListener): void {
@ -72,23 +72,43 @@ class BasicDataSource implements IDataSource {
}
}
export interface MediaData {
uri: string;
fileType: number;
displayName: string;
duration: number;
dateAdded: number;
}
export default class MediaDataSource extends BasicDataSource {
private dataArray: mediaLibrary.FileAsset[] = []
private dataArray: MediaData[] = []
public setDataArray(dataArray: MediaData[]): void {
this.dataArray = dataArray
}
public getDataArray(): MediaData[] {
return this.dataArray
}
public totalCount(): number {
return this.dataArray.length
}
public getData(index: number): mediaLibrary.FileAsset {
public getData(index: number): MediaData {
return this.dataArray[index]
}
public addData(index: number, data: mediaLibrary.FileAsset): void {
public deleteData(index: number, count: number): void {
this.dataArray.splice(index, count)
}
public addData(index: number, data: MediaData): void {
this.dataArray.splice(index, 0, data)
this.notifyDataAdd(index)
}
public pushData(data: mediaLibrary.FileAsset): void {
public pushData(data: MediaData): void {
this.dataArray.push(data)
this.notifyDataAdd(this.dataArray.length - 1)
}

View File

@ -12,16 +12,18 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import mediaLibrary from '@ohos.multimedia.mediaLibrary'
import { FileType } from '../model/MediaUtils'
import { getDurationString } from '../model/TimeUtils'
import { MediaData } from './BasicDataSource'
@Component
export struct MediaItem {
private media: mediaLibrary.FileAsset = undefined
private media: MediaData = {} as MediaData
private index: number = 0
private btnAction: (operate: string, index: number, mediaItemId) => void
private btnAction: (operate: string, index: number, mediaItemUri: string) => void = () => {}
tempNum(number) {
tempNum(number: number): string {
if (number < 10) {
return "0" + number
}
@ -29,23 +31,22 @@ export struct MediaItem {
}
getTimeString() {
const dateAdded: number = this.media.dateAdded as number
// js中Date时间戳单位是毫秒13位文件创建时间戳的单位是秒(10位)。故需转化成毫秒后表示
const date = new Date(this.media.dateAdded * 1000)
const date = new Date(dateAdded * 1000)
return `${date.getFullYear()}/${this.tempNum(date.getMonth() + 1)}/${this.tempNum(date.getDate())}`
}
getImgSrc() {
switch (this.media.mediaType) {
case mediaLibrary.MediaType.VIDEO:
getImgSrc(): string | Resource {
switch (this.media.fileType) {
case FileType.VIDEO:
return $r('app.media.video_poster')
case mediaLibrary.MediaType.AUDIO:
case FileType.AUDIO:
return $r('app.media.ic_play')
case mediaLibrary.MediaType.FILE:
return $r('app.media.ic_document')
break
default:
case FileType.IMAGE:
return this.media.uri
break
default:
return $r('app.media.ic_document')
}
}
@ -57,15 +58,15 @@ export struct MediaItem {
.borderRadius(10)
.objectFit(ImageFit.Fill)
Column() {
Text(this.media.title)
Text(this.media.displayName)
.width('100%')
.fontSize(22)
.id('fileName')
.id(`fileName${this.index}`)
Text(this.getTimeString())
.width('100%')
.fontSize(22)
.margin({ top: 10 })
if (this.media.mediaType === mediaLibrary.MediaType.VIDEO) {
if (this.media.fileType === FileType.VIDEO) {
Text(getDurationString(this.media.duration))
.width('100%')
.fontSize(22)
@ -86,7 +87,7 @@ export struct MediaItem {
.size({ width: 50, height: 50 })
.backgroundColor('#F5F5F5')
.onClick(() => {
this.btnAction('rename', this.index, this.media.id);
this.btnAction('rename', this.index, this.media.uri);
})
Button({ type: ButtonType.Circle, stateEffect: true }) {
@ -101,7 +102,7 @@ export struct MediaItem {
.margin({ left: 15, right: 10 })
.backgroundColor('#F5F5F5')
.onClick(() => {
this.btnAction('delete', this.index, this.media.id);
this.btnAction('delete', this.index, this.media.uri);
})
}
.padding({ top: 10, bottom: 10, left: 10, right: 10 })

View File

@ -13,12 +13,13 @@
* limitations under the License.
*/
import prompt from '@ohos.prompt'
import { MediaData } from './BasicDataSource'
@CustomDialog
export struct RenameDialog {
private controller: CustomDialogController
private action: (title: string) => void
@State title: string = ''
private action: (selectMedia: MediaData) => void = () => {}
@Link selectMedia: MediaData
build() {
Column() {
@ -26,15 +27,14 @@ export struct RenameDialog {
.fontSize(20)
.fontColor(Color.Black)
.fontWeight(FontWeight.Bold)
TextInput({ placeholder: 'input new name', text: this.title })
TextInput({ placeholder: 'input new name', text: this.selectMedia.displayName })
.id('inputRename')
.type(InputType.Normal)
.placeholderColor(Color.Gray)
.maxLength(20)
.fontSize(19)
.margin({ left: 10, top: 15 })
.onChange((value: string) => {
this.title = value
this.selectMedia.displayName = value
})
Row() {
Button() {
@ -46,11 +46,11 @@ export struct RenameDialog {
.backgroundColor(Color.White)
.margin(5)
.onClick(() => {
if (this.title === '') {
if (this.selectMedia.displayName === '') {
prompt.showToast({ message: 'please input the file name', duration: 1000 })
return
}
this.action(this.title)
this.action(this.selectMedia)
})
Divider()

View File

@ -33,7 +33,6 @@ export default struct TitleBar {
.objectFit(ImageFit.Contain)
.onClick(() => {
router.back()
AppStorage.Set('isRefresh', true)
})
}
Text(this.title)

View File

@ -17,7 +17,7 @@
"module": {
"name": "entry",
"type": "entry",
"srcEntrance": "./ets/Application/AbilityStage.ts",
"srcEntry": "./ets/Application/AbilityStage.ts",
"description": "$string:entry_desc",
"mainElement": "MainAbility",
"deviceTypes": [
@ -59,7 +59,7 @@
"abilities": [
"MainAbility"
],
"when": "inuse"
"when": "always"
}
},
{
@ -69,7 +69,27 @@
"abilities": [
"MainAbility"
],
"when": "inuse"
"when": "always"
}
},
{
"name": "ohos.permission.READ_AUDIO",
"reason": "$string:media_location_permission",
"usedScene": {
"abilities": [
"MainAbility"
],
"when": "always"
}
},
{
"name": "ohos.permission.WRITE_AUDIO",
"reason": "$string:media_location_permission",
"usedScene": {
"abilities": [
"MainAbility"
],
"when": "always"
}
},
{
@ -79,27 +99,46 @@
"abilities": [
"MainAbility"
],
"when": "inuse"
"when": "always"
}
},
{
"name": "ohos.permission.WRITE_MEDIA",
"name": "ohos.permission.WRITE_IMAGEVIDEO",
"reason": "$string:write_permission",
"usedScene": {
"abilities": [
"MainAbility"
],
"when": "inuse"
"when": "always"
}
},
{
"name": "ohos.permission.READ_MEDIA",
"name": "ohos.permission.READ_IMAGEVIDEO",
"reason": "$string:read_permission",
"usedScene": {
"abilities": [
"MainAbility"
],
"when": "inuse"
"when": "always"
}
}, {
"name" : "ohos.permission.FILE_ACCESS_MANAGER",
"reason": "$string:read_permission",
"usedScene": {
"abilities": [
"MainAbility"
],
"when":"always"
}
},
{
"name" : "ohos.permission.GET_BUNDLE_INFO_PRIVILEGED",
"reason": "$string:read_permission",
"usedScene": {
"abilities": [
"MainAbility"
],
"when":"always"
}
}
]

View File

@ -1,22 +0,0 @@
/*
* Copyright (c) 2022 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import AbilityStage from '@ohos.application.AbilityStage'
export default class TestAbilityStage extends AbilityStage {
onCreate() {
console.log('[Demo] TestAbilityStage onCreate')
}
}

View File

@ -20,59 +20,60 @@ var abilityDelegator = undefined
var abilityDelegatorArguments = undefined
function translateParamsToString(parameters) {
const keySet = new Set([
'-s class', '-s notClass', '-s suite', '-s it',
'-s level', '-s testType', '-s size', '-s timeout',
'-s dryRun'
])
let targetParams = ''
for (const key in parameters) {
if (keySet.has(key)) {
targetParams = `${targetParams} ${key} ${parameters[key]}`
const keySet = new Set([
'-s class', '-s notClass', '-s suite', '-s it',
'-s level', '-s testType', '-s size', '-s timeout',
'-s dryRun'
])
let targetParams = '';
for (const key in parameters) {
if (keySet.has(key)) {
targetParams = `${targetParams} ${key} ${parameters[key]}`
}
}
}
return targetParams.trim()
return targetParams.trim()
}
async function onAbilityCreateCallback() {
console.log("onAbilityCreateCallback");
console.log("onAbilityCreateCallback");
}
async function addAbilityMonitorCallback(err: any) {
console.info("addAbilityMonitorCallback : " + JSON.stringify(err))
console.info("addAbilityMonitorCallback : " + JSON.stringify(err))
}
export default class OpenHarmonyTestRunner implements TestRunner {
constructor() {
}
onPrepare() {
console.info("OpenHarmonyTestRunner OnPrepare ")
}
async onRun() {
console.log('OpenHarmonyTestRunner onRun run')
abilityDelegatorArguments = AbilityDelegatorRegistry.getArguments()
abilityDelegator = AbilityDelegatorRegistry.getAbilityDelegator()
var testAbilityName = abilityDelegatorArguments.bundleName + '.TestAbility'
let lMonitor = {
abilityName: testAbilityName,
onAbilityCreate: onAbilityCreateCallback,
constructor() {
}
abilityDelegator.addAbilityMonitor(lMonitor, addAbilityMonitorCallback)
var cmd = 'aa start -d 0 -a TestAbility' + ' -b ' + abilityDelegatorArguments.bundleName
cmd += ' ' + translateParamsToString(abilityDelegatorArguments.parameters)
var debug = abilityDelegatorArguments.parameters["-D"]
if (debug == 'true') {
cmd += ' -D'
onPrepare() {
console.info("OpenHarmonyTestRunner OnPrepare ")
}
console.info('cmd : ' + cmd)
abilityDelegator.executeShellCommand(cmd,
(err: any, d: any) => {
console.info('executeShellCommand : err : ' + JSON.stringify(err))
console.info('executeShellCommand : data : ' + d.stdResult)
console.info('executeShellCommand : data : ' + d.exitCode)
})
console.info('OpenHarmonyTestRunner onRun end')
}
}
async onRun() {
console.log('OpenHarmonyTestRunner onRun run')
abilityDelegatorArguments = AbilityDelegatorRegistry.getArguments()
abilityDelegator = AbilityDelegatorRegistry.getAbilityDelegator()
var testAbilityName = abilityDelegatorArguments.bundleName + '.TestAbility'
let lMonitor = {
abilityName: testAbilityName,
onAbilityCreate: onAbilityCreateCallback,
};
abilityDelegator.addAbilityMonitor(lMonitor, addAbilityMonitorCallback)
var cmd = 'aa start -d 0 -a TestAbility' + ' -b ' + abilityDelegatorArguments.bundleName
cmd += ' '+translateParamsToString(abilityDelegatorArguments.parameters)
var debug = abilityDelegatorArguments.parameters["-D"]
if (debug == 'true')
{
cmd += ' -D'
}
console.info('cmd : '+cmd)
abilityDelegator.executeShellCommand(cmd,
(err: any, d: any) => {
console.info('executeShellCommand : err : ' + JSON.stringify(err));
console.info('executeShellCommand : data : ' + d.stdResult);
console.info('executeShellCommand : data : ' + d.exitCode);
})
console.info('OpenHarmonyTestRunner onRun end')
}
};

View File

@ -0,0 +1,405 @@
/*
* Copyright (c) 2022-2024 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { describe, expect, it } from '@ohos/hypium';
import { Driver, ON, Component } from '@ohos.UiTest';
import hilog from '@ohos.hilog';
import AbilityDelegatorRegistry from '@ohos.app.ability.abilityDelegatorRegistry';
import dataSharePredicates from '@ohos.data.dataSharePredicates';
import Logger from '../utils/Logger';
import userFileManager from '@ohos.filemanagement.userFileManager';
import { getString } from '../utils/ResourceUtil';
import fileAccess from '@ohos.file.fileAccess';
import common from '@ohos.app.ability.common';
const TAG: string = 'abilityTest';
const driver = Driver.create();
const DOMAIN = 0xF811;
const BUNDLE = 'MultiMedia_';
let abilityDelegatorRegistry = AbilityDelegatorRegistry.getAbilityDelegator();
enum FileType {
IMAGE = 1,
VIDEO = 2,
AUDIO = 3,
FILE= 4
}
interface FileDetail {
albumName : string;
count : number,
mediaType : number;
}
async function getFileAssetsFromType(mediaTest: userFileManager.UserFileManager, mediaType: number): Promise<userFileManager.FileAsset[]> {
Logger.info(TAG, `getFileAssetsFromType,mediaType = ${mediaType}`);
let fileAssets: Array<userFileManager.FileAsset> = [];
try {
let predicates: dataSharePredicates.DataSharePredicates = new dataSharePredicates.DataSharePredicates();
let fetchOptions: userFileManager.FetchOptions = {
fetchColumns: ['duration', 'date_added'],
predicates: predicates
}
let fetchFileResult: userFileManager.FetchResult<userFileManager.FileAsset> | undefined = undefined;
// 获取音频资源
if (mediaType === FileType.AUDIO) {
fetchFileResult = await mediaTest.getAudioAssets(fetchOptions);
fileAssets = await fetchFileResult.getAllObject();
} else {
// 获取图片/视频资源
fetchFileResult = await mediaTest.getPhotoAssets(fetchOptions);
fileAssets = await fetchFileResult.getAllObject();
// 过滤资源
fileAssets = fileAssets.filter(item => item.fileType === mediaType)
}
} catch (err) {
Logger.info(TAG, `err ${JSON.stringify(err)}`);
}
Logger.info(TAG, `getFileAssetsFromType = ${mediaType},fileAssets.count = ${fileAssets.length}`);
return fileAssets
}
async function getFileAssets(context: common.UIAbilityContext): Promise<fileAccess.FileInfo[]> {
let isDone: boolean = false;
let fileInfos: Array<fileAccess.FileInfo> = [];
try {
let fileAccessHelper = fileAccess.createFileAccessHelper(context);
let rootIterator: fileAccess.RootIterator = await fileAccessHelper.getRoots();
// 获取目录url
let catalogueUrl: string = rootIterator.next().value.uri;
let fileInfo: fileAccess.FileInfo = await fileAccessHelper.getFileInfoFromUri(catalogueUrl);
let fileIterator = fileInfo.scanFile();
while (!isDone) {
let result = fileIterator.next();
isDone = result.done;
if (!isDone) {
fileInfos.push(result.value);
}
}
} catch (error) {
Logger.info(TAG, "getRoots failed, errCode:" + error.code + ", errMessage:" + error.message);
}
return fileInfos;
}
async function getAlbums() {
Logger.info(TAG, `getAlbums start`);
// 获取当前应用的ability
let currentAbility = await abilityDelegatorRegistry.getCurrentTopAbility();
let mediaTest: userFileManager.UserFileManager = userFileManager.getUserFileMgr(currentAbility.context);
const files = await getFileAssets(currentAbility.context);
const images = await getFileAssetsFromType(mediaTest, FileType.IMAGE);
const videos = await getFileAssetsFromType(mediaTest, FileType.VIDEO);
const audios = await getFileAssetsFromType(mediaTest, FileType.AUDIO);
let albums: FileDetail[] = [];
const document: FileDetail = { albumName: 'Documents', count: files.length, mediaType: FileType.FILE };
albums.push(document);
const Pictures: FileDetail = { albumName: 'Pictures', count: images.length, mediaType: FileType.IMAGE };
albums.push(Pictures);
const Videos: FileDetail = { albumName: 'Videos', count: videos.length, mediaType: FileType.VIDEO };
albums.push(Videos)
const Audios: FileDetail = { albumName: 'Audios', count: audios.length, mediaType: FileType.AUDIO };
albums.push(Audios);
Logger.info(TAG, `getAlbums end`);
return albums;
}
export default function abilityTest() {
describe('ActsAbilityTest', () => {
/**
* 拉起应用
*/
it('StartAbility_001', 0, async (done : () => void) => {
hilog.info(DOMAIN, TAG, BUNDLE + 'StartAbility_001 begin');
try {
await abilityDelegatorRegistry.startAbility({
bundleName: 'ohos.samples.multimedia',
abilityName: 'MainAbility'
})
} catch (err) {
expect(0).assertEqual(err.code);
}
await driver.delayMs(3000);
done();
hilog.info(DOMAIN, TAG, BUNDLE + 'StartAbility_001 end');
})
/**
* 获取权限
*/
it('RequestEnableNotification', 0, async (done: Function) => {
Logger.info(TAG, BUNDLE + 'RequestEnableNotification begin');
for (let i = 0;i < 4; i++) {
await driver.assertComponentExist(ON.text(getString($r('app.string.allow'))));
let agreeNotication: Component = await driver.findComponent(ON.text(getString($r('app.string.allow'))));
await agreeNotication.click();
await driver.delayMs(1000);
}
done();
Logger.info(TAG, BUNDLE + 'RequestEnableNotification end');
});
/**
* 显示相册、录音、文件入口
*/
it('PageEntry_001', 0, async (done: Function) => {
Logger.info(TAG, BUNDLE + 'PageEntry_001 begin');
let driver: Driver = Driver.create();
await driver.delayMs(1000);
// 点击加号按钮,弹出相机、录音、文档页面入口
await driver.assertComponentExist(ON.id('addBtn'));
let addBtn: Component = await driver.findComponent(ON.id('addBtn'));
await addBtn.click();
await driver.delayMs(1000);
done()
Logger.info(TAG, BUNDLE + 'PageEntry_001 end');
});
/**
* 照相功能
*/
it('Camera_001', 0, async (done: Function) => {
Logger.info(TAG, BUNDLE + 'Camera_001 begin');
let driver: Driver = Driver.create();
await driver.delayMs(1000);
// 点击进入相机页面
await driver.assertComponentExist(ON.id('camera'));
let camera: Component = await driver.findComponent(ON.id('camera'));
await camera.click();
await driver.delayMs(1000);
// 启动照相按钮
await driver.assertComponentExist(ON.id('cameraIcon'));
let cameraIcon: Component = await driver.findComponent(ON.id('cameraIcon'));
await cameraIcon.click();
await driver.delayMs(1000);
done()
Logger.info(TAG, BUNDLE + 'Camera_001 end');
});
/**
* 录像功能
*/
it('Video_001', 0, async (done: Function) => {
Logger.info(TAG, BUNDLE + 'Video_001 begin');
let driver: Driver = Driver.create();
await driver.delayMs(1000);
// 点击切换录像功能
await driver.assertComponentExist(ON.id('video'));
let camera: Component = await driver.findComponent(ON.id('video'));
await camera.click();
await driver.delayMs(1000);
// 点击进行录像
await driver.assertComponentExist(ON.id('cameraIcon'));
let cameraIcon: Component = await driver.findComponent(ON.id('cameraIcon'));
await cameraIcon.click();
// 5s之后再次点击保存录像
await driver.delayMs(5000);
await cameraIcon.click();
await driver.delayMs(1000);
await driver.pressBack();
await driver.delayMs(1000);
await driver.assertComponentExist(ON.id('mediaType2'));
let mediaType: Component = await driver.findComponent(ON.id('mediaType2'));
await mediaType.click();
await driver.delayMs(1000);
await driver.assertComponentExist(ON.id('mediaId0'));
let medieItem: Component = await driver.findComponent(ON.id('mediaId0'));
await medieItem.click();
await driver.delayMs(2000);
await driver.pressBack();
await driver.delayMs(1000);
await driver.pressBack();
await driver.delayMs(1000);
done()
Logger.info(TAG, BUNDLE + 'Video_001 end');
});
/**
* 录音功能
*/
it('Record_001', 0, async (done: Function) => {
Logger.info(TAG, BUNDLE + 'Record_001 begin');
let driver: Driver = Driver.create();
await driver.delayMs(1000);
await driver.assertComponentExist(ON.id('addBtn'));
let addBtn: Component = await driver.findComponent(ON.id('addBtn'));
await addBtn.click();
await driver.delayMs(1000);
// 进入录音页面
await driver.assertComponentExist(ON.id('record'));
let record: Component = await driver.findComponent(ON.id('record'));
await record.click();
await driver.delayMs(1000);
// 开始录音
await driver.assertComponentExist(ON.id('startBtn'));
let startBtn: Component = await driver.findComponent(ON.id('startBtn'));
await startBtn.click();
// 启动3s之后结束
await driver.delayMs(3000);
await driver.assertComponentExist(ON.id('pauseBtn'));
let pauseBtn: Component = await driver.findComponent(ON.id('pauseBtn'));
await pauseBtn.click();
await driver.delayMs(1000);
// 返回主页
await driver.assertComponentExist(ON.id('back'));
let backIndex: Component = await driver.findComponent(ON.id('back'));
await backIndex.click();
await driver.delayMs(1000);
done()
Logger.info(TAG, BUNDLE + 'Record_001 end');
});
/**
* 文本编辑功能
*/
it('TxtEdit_001', 0, async (done: Function) => {
Logger.info(TAG, BUNDLE + 'TxtEdit_001 begin');
let driver: Driver = Driver.create();
await driver.delayMs(1000);
// 添加文件
await driver.assertComponentExist(ON.id('addBtn'));
let addBtn: Component = await driver.findComponent(ON.id('addBtn'));
await addBtn.click();
await driver.delayMs(1000);
// 进入文本编辑页面
await driver.assertComponentExist(ON.id('document'));
let document: Component = await driver.findComponent(ON.id('document'));
await document.click();
await driver.delayMs(1000);
await driver.assertComponentExist(ON.id('textArea'));
let textArea: Component = await driver.findComponent(ON.id('textArea'));
await textArea.inputText(`mst`);
// 保存文本
await driver.delayMs(1000);
await driver.assertComponentExist(ON.id('saveBtn'));
let saveBtn: Component = await driver.findComponent(ON.id('saveBtn'));
await saveBtn.click();
await driver.delayMs(1000);
await driver.delayMs(1000);
done()
Logger.info(TAG, BUNDLE + 'TxtEdit_001 end');
});
/**
* 执行数据重命名以及删除操作
*/
it('BaseFeature_001', 0, async (done: Function) => {
Logger.info(TAG, BUNDLE + 'BaseFeature_001 begin');
// 校验数据是否添加成功,每次操作添加一次数据,成功数据为非空
let mediaAlbums = await getAlbums();
mediaAlbums.forEach((item) => {
if (item.count === 0) {
Logger.info(TAG, `${item.albumName} obtaining data error, item.albumName: ${item.count}`);
expect().assertFail();
}
});
await driver.delayMs(1000);
await driver.assertComponentExist(ON.id('mediaType0'));
let mediaType: Component = await driver.findComponent(ON.id('mediaType0'));
await mediaType.click();
await driver.delayMs(1000);
// 点击重命名
await driver.assertComponentExist(ON.id('rename0'));
let rename: Component = await driver.findComponent(ON.id('rename0'));
await rename.click();
await driver.delayMs(1000);
await driver.assertComponentExist(ON.id('inputRename'));
let inputRename: Component = await driver.findComponent(ON.id('inputRename'));
await inputRename.clearText();
// 输入文本
await inputRename.inputText('mst');
await driver.delayMs(1000);
// 点击收起软键盘
await driver.click(670, 700);
await driver.delayMs(1000);
await driver.assertComponentExist(ON.text(getString($r('app.string.agree'))));
let confirm: Component = await driver.findComponent(ON.text(getString($r('app.string.agree'))));
await confirm.click();
await driver.delayMs(1000);
// 校验文本
await driver.assertComponentExist(ON.id('fileName0'));
await driver.assertComponentExist(ON.text('mst'));
await driver.delayMs(1000);
// 删除数据
await driver.assertComponentExist(ON.id('delete0'));
await driver.delayMs(1000);
let deleteData: Component = await driver.findComponent(ON.id('delete0'));
await deleteData.click();
await driver.delayMs(1000);
await driver.assertComponentExist(ON.text(getString($r('app.string.agree'))));
let confirmBtn: Component = await driver.findComponent(ON.text(getString($r('app.string.agree'))));
await confirmBtn.click();
await driver.delayMs(1000);
// 校验是否删除成功
let mediaAblumsDeleted = await getAlbums();
if (mediaAblumsDeleted[0].count !== mediaAlbums[0].count - 1) {
Logger.info(TAG, `fileType deletion failed`)
expect().assertFail();
}
await driver.assertComponentExist(ON.id('back'));
let backIndex: Component = await driver.findComponent(ON.id('back'));
await backIndex.click();
await driver.delayMs(1000);
done()
Logger.info(TAG, BUNDLE + 'BaseFeature_001 end');
});
/**
* 删除多条数据操作
*/
it('DeleteMultipleData_001', 0, async (done: Function) => {
Logger.info(TAG, BUNDLE + 'DeleteMultipleData_001 begin');
await driver.delayMs(1000);
// 校验数据是否添加成功,每次操作添加一次数据,成功数据为非空
let mediaAlbums = await getAlbums();
await driver.assertComponentExist(ON.id('mediaType0'));
let mediaType: Component = await driver.findComponent(ON.id('mediaType0'));
await mediaType.click();
await driver.delayMs(1000);
// 获取当前文件数据的个数,并依次删除
for (let i = 0; i < mediaAlbums[0].count; i++) {
let medias = await getAlbums();
await driver.delayMs(1000);
// 删除数据
await driver.assertComponentExist(ON.id(`delete${i}`));
let deleteData: Component = await driver.findComponent(ON.id(`delete${i}`));
await deleteData.click();
await driver.delayMs(1000);
await driver.assertComponentExist(ON.text(getString($r('app.string.agree'))));
let confirmBtn: Component = await driver.findComponent(ON.text(getString($r('app.string.agree'))));
await confirmBtn.click();
await driver.delayMs(1000);
// 校验是否删除成功
let mediaAblumsDeleted = await getAlbums();
if (mediaAblumsDeleted[0].count !== medias[0].count - 1) {
Logger.info(TAG, `Type deletion failed`)
expect().assertFail();
}
}
done()
Logger.info(TAG, BUNDLE + 'DeleteMultipleData_001 end');
});
})
}

View File

@ -13,8 +13,8 @@
* limitations under the License.
*/
import appTest from './app.test';
import abilityTest from './Ability.test'
export default function testsuite() {
appTest()
}
abilityTest()
}

View File

@ -1,359 +0,0 @@
/*
* Copyright (c) 2022-2023 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { describe, it, expect } from '@ohos/hypium';
import { Driver, ON, Component } from '@ohos.UiTest';
import UIAbility from '@ohos.app.ability.UIAbility';
import mediaLibrary from '@ohos.multimedia.mediaLibrary';
import AbilityDelegatorRegistry from '@ohos.app.ability.abilityDelegatorRegistry';
import Logger from '../util/Logger';
const BUNDLE = 'MultiMedia_';
const TAG = 'MultiMediaAppTestPage';
const TIME_OUT = 1000;
let ability: UIAbility;
let driver: Driver = Driver.create();
let mediaTest: mediaLibrary.MediaLibrary = undefined;
let uiAbility: UIAbility;
async function getFileAssetsFromType(mediaType: number) {
Logger.info(TAG, `getFileAssetsFromType,mediaType = ${mediaType}`);
let fileKeyObj = mediaLibrary.FileKey;
let fileAssets = [];
let fetchOp = {
selections: `${fileKeyObj.MEDIA_TYPE}=?`,
selectionArgs: [`${mediaType}`],
};
let fetchFileResult = await mediaTest.getFileAssets(fetchOp);
Logger.info(TAG, `getFileAssetsFromType,fetchFileResult.count = ${fetchFileResult.getCount()}`);
if (fetchFileResult.getCount() > 0) {
fileAssets = await fetchFileResult.getAllObject();
}
return fileAssets;
}
async function getAlbums() {
Logger.info(TAG, `getAlbums start`);
let albums = [];
let [ files, images, videos, audios ] = await Promise.all([
getFileAssetsFromType(mediaLibrary.MediaType.FILE),
getFileAssetsFromType(mediaLibrary.MediaType.IMAGE),
getFileAssetsFromType(mediaLibrary.MediaType.VIDEO),
getFileAssetsFromType(mediaLibrary.MediaType.AUDIO)
]);
albums.push({
albumName: 'Documents', count: files.length, mediaType: mediaLibrary.MediaType.FILE
});
albums.push({
albumName: 'Pictures', count: images.length, mediaType: mediaLibrary.MediaType.IMAGE
});
albums.push({
albumName: 'Videos', count: videos.length, mediaType: mediaLibrary.MediaType.VIDEO
});
albums.push({
albumName: 'Audios', count: audios.length, mediaType: mediaLibrary.MediaType.AUDIO
});
Logger.info(TAG, `getAlbums end`);
return albums;
}
export default function appTest() {
describe('appTest', function () {
// 打开应用
it(BUNDLE + 'StartAbility', 0, async function (done) {
Logger.info(TAG, 'StartAbility start')
let want = {
bundleName: 'ohos.samples.multimedia',
abilityName: 'MainAbility'
};
let abilityDelegator: AbilityDelegatorRegistry.AbilityDelegator = AbilityDelegatorRegistry.getAbilityDelegator();
abilityDelegator.startAbility(want, (err) => {
Logger.info(TAG, `_startAbility get err ${JSON.stringify(err)}`);
done();
Logger.info(TAG, '_startAbility end');
});
function onAbilityCreateCallback() {
Logger.info(TAG, 'onAbilityCreateCallback');
}
let monitor: AbilityDelegatorRegistry.AbilityMonitor = {
abilityName: 'MainAbility',
onAbilityCreate: onAbilityCreateCallback
}
uiAbility = await abilityDelegator.waitAbilityMonitor(monitor, TIME_OUT);
ability = await abilityDelegator.getCurrentTopAbility();
mediaTest = mediaLibrary.getMediaLibrary(uiAbility.context);
Logger.info(TAG, 'StartAbility end');
});
/**
* 获取权限
*/
it(`${BUNDLE}RequestEnableNotification`, 0, async () => {
Logger.info(TAG, BUNDLE + 'RequestEnableNotification begin');
await driver.delayMs(1000);
let resourceManager = ability.context.resourceManager;
for (let i = 0;i < 4; i++) {
await driver.assertComponentExist(ON.text(await resourceManager.getStringValue($r('app.string.allow'))));
let agreeNotication: Component = await driver.findComponent(ON.text(await resourceManager.getStringValue($r('app.string.allow'))));
await agreeNotication.click();
await driver.delayMs(1000);
}
Logger.info(TAG, BUNDLE + 'RequestEnableNotification end');
});
/**
* 显示相册、录音、文件入口
*/
it(`${BUNDLE}PageEntry_001`, 0, async () => {
Logger.info(TAG, BUNDLE + 'PageEntry_001 begin');
let driver: Driver = Driver.create();
await driver.delayMs(1000);
// 点击加号按钮,弹出相机、录音、文档页面入口
await driver.assertComponentExist(ON.id('addBtn'));
let addBtn: Component = await driver.findComponent(ON.id('addBtn'));
await addBtn.click();
await driver.delayMs(1000);
Logger.info(TAG, BUNDLE + 'PageEntry_001 end');
});
/**
* 照相功能
*/
it(`${BUNDLE}Camera_001`, 0, async () => {
Logger.info(TAG, BUNDLE + 'Camera_001 begin');
let driver: Driver = Driver.create();
await driver.delayMs(1000);
// 点击进入相机页面
await driver.assertComponentExist(ON.id('camera'));
let camera: Component = await driver.findComponent(ON.id('camera'));
await camera.click();
await driver.delayMs(1000);
// 启动照相按钮
await driver.assertComponentExist(ON.id('cameraIcon'));
let cameraIcon: Component = await driver.findComponent(ON.id('cameraIcon'));
await cameraIcon.click();
await driver.delayMs(1000);
Logger.info(TAG, BUNDLE + 'Camera_001 end');
});
/**
* 录像功能
*/
it(`${BUNDLE}Video_001`, 0, async () => {
Logger.info(TAG, BUNDLE + 'Video_001 begin');
let driver: Driver = Driver.create();
await driver.delayMs(1000);
// 点击切换录像功能
await driver.assertComponentExist(ON.id('video'));
let camera: Component = await driver.findComponent(ON.id('video'));
await camera.click();
await driver.delayMs(1000);
// 点击进行录像
await driver.assertComponentExist(ON.id('cameraIcon'));
let cameraIcon: Component = await driver.findComponent(ON.id('cameraIcon'));
await cameraIcon.click();
// 5s之后再次点击保存录像
await driver.delayMs(5000);
await cameraIcon.click();
await driver.delayMs(1000);
await driver.pressBack();
await driver.delayMs(1000);
await driver.assertComponentExist(ON.id('mediaType2'));
let mediaType: Component = await driver.findComponent(ON.id('mediaType2'));
await mediaType.click();
await driver.delayMs(1000);
await driver.assertComponentExist(ON.id('mediaId0'));
let medieItem: Component = await driver.findComponent(ON.id('mediaId0'));
await medieItem.click();
await driver.delayMs(2000);
let resourceManager = ability.context.resourceManager;
for (let i = 0;i < 2; i++) {
await driver.assertComponentExist(ON.text(await resourceManager.getStringValue($r('app.string.allow'))));
let agreeNotication: Component = await driver.findComponent(ON.text(await resourceManager.getStringValue($r('app.string.allow'))));
await agreeNotication.click();
await driver.delayMs(1000);
}
await driver.delayMs(2000);
await driver.pressBack();
await driver.delayMs(1000);
await driver.pressBack();
Logger.info(TAG, BUNDLE + 'Video_001 end');
});
/**
* 录音功能
*/
it(`${BUNDLE}Record_001`, 0, async () => {
Logger.info(TAG, BUNDLE + 'Record_001 begin');
let driver: Driver = Driver.create();
await driver.delayMs(1000);
await driver.assertComponentExist(ON.id('addBtn'));
let addBtn: Component = await driver.findComponent(ON.id('addBtn'));
await addBtn.click();
await driver.delayMs(1000);
// 进入录音页面
await driver.assertComponentExist(ON.id('record'));
let record: Component = await driver.findComponent(ON.id('record'));
await record.click();
await driver.delayMs(1000);
// 开始录音
await driver.assertComponentExist(ON.id('startBtn'));
let startBtn: Component = await driver.findComponent(ON.id('startBtn'));
await startBtn.click();
// 启动3s之后结束
await driver.delayMs(3000);
await driver.assertComponentExist(ON.id('pauseBtn'));
let pauseBtn: Component = await driver.findComponent(ON.id('pauseBtn'));
await pauseBtn.click();
await driver.delayMs(1000);
// 返回主页
await driver.assertComponentExist(ON.id('back'));
let backIndex: Component = await driver.findComponent(ON.id('back'));
await backIndex.click();
Logger.info(TAG, BUNDLE + 'Record_001 end');
});
/**
* 文本编辑功能
*/
it(`${BUNDLE}TxtEdit_001`, 0, async () => {
Logger.info(TAG, BUNDLE + 'TxtEdit_001 begin');
let driver: Driver = Driver.create();
await driver.delayMs(1000);
// 添加五个文件
for (let i = 0; i < 5; i++) {
await driver.assertComponentExist(ON.id('addBtn'));
let addBtn: Component = await driver.findComponent(ON.id('addBtn'));
await addBtn.click();
await driver.delayMs(1000);
// 进入文本编辑页面
await driver.assertComponentExist(ON.id('document'));
let document: Component = await driver.findComponent(ON.id('document'));
await document.click();
await driver.delayMs(1000);
await driver.assertComponentExist(ON.id('textArea'));
let textArea: Component = await driver.findComponent(ON.id('textArea'));
await textArea.inputText(`mst`);
// 保存文本
await driver.delayMs(1000);
await driver.assertComponentExist(ON.id('saveBtn'));
let saveBtn: Component = await driver.findComponent(ON.id('saveBtn'));
await saveBtn.click();
await driver.delayMs(1000);
}
Logger.info(TAG, BUNDLE + 'TxtEdit_001 end');
});
/**
* 执行数据重命名以及删除操作
*/
it(`${BUNDLE}BaseFeature_001`, 0, async () => {
Logger.info(TAG, BUNDLE + 'BaseFeature_001 begin');
await driver.delayMs(1000);
// 校验数据是否添加成功,每次操作添加一次数据,成功数据为非空
let mediaAlbums = await getAlbums();
let resourceManager = ability.context.resourceManager;
mediaAlbums.forEach((item) => {
if (item.count === 0) {
Logger.info(TAG, `${item.albumName} obtaining data error`);
expect().assertFail();
}
});
// 循环4次分别对文档、图片、视频、音频进行重名和删除操作
for (let i = 0;i < 4; i++) {
await driver.delayMs(1000);
await driver.assertComponentExist(ON.id(`mediaType${i}`));
let mediaType: Component = await driver.findComponent(ON.id(`mediaType${i}`));
await mediaType.click();
await driver.delayMs(1000);
// 重命名
await driver.assertComponentExist(ON.id('rename0'));
let rename: Component = await driver.findComponent(ON.id('rename0'));
await rename.click();
await driver.delayMs(1000);
await driver.assertComponentExist(ON.id('inputRename'));
let inputRename: Component = await driver.findComponent(ON.id('inputRename'));
await inputRename.clearText();
await driver.delayMs(1000);
// 输入文本
await inputRename.inputText('mst');
await driver.delayMs(1000);
await driver.assertComponentExist(ON.text(await resourceManager.getStringValue($r('app.string.agree'))));
let confirm: Component = await driver.findComponent(ON.text(await resourceManager.getStringValue($r('app.string.agree'))));
await driver.delayMs(1000);
await confirm.click();
await driver.delayMs(1000);
// 校验文本
await driver.assertComponentExist(ON.id('fileName'));
let fileName: Component = await driver.findComponent(ON.id('fileName'));
await driver.delayMs(1000);
expect('mst').assertEqual(await fileName.getText());
// 删除数据
await driver.assertComponentExist(ON.id('delete0'));
await driver.delayMs(1000);
let deleteData: Component = await driver.findComponent(ON.id('delete0'));
await driver.delayMs(1000);
await deleteData.click();
await driver.delayMs(1000);
await driver.assertComponentExist(ON.text(await resourceManager.getStringValue($r('app.string.agree'))));
let confirmBtn: Component = await driver.findComponent(ON.text(await resourceManager.getStringValue($r('app.string.agree'))));
await driver.delayMs(1000);
await confirmBtn.click();
await driver.delayMs(1000);
// 校验是否删除成功
let mediaAblumsDeleted = await getAlbums();
if (mediaAblumsDeleted[i].count !== mediaAlbums[i].count - 1) {
Logger.info(TAG, `Type ${i} deletion failed`)
expect().assertFail();
}
await driver.assertComponentExist(ON.id('back'));
let backIndex: Component = await driver.findComponent(ON.id('back'));
await backIndex.click();
}
Logger.info(TAG, BUNDLE + 'BaseFeature_001 end');
});
/**
* 删除多条数据操作
*/
it(`${BUNDLE}DeleteMultipleData_001`, 0, async () => {
Logger.info(TAG, BUNDLE + 'DeleteMultipleData_001 begin');
await driver.delayMs(1000);
// 校验数据是否添加成功,每次操作添加一次数据,成功数据为非空
let mediaAlbums = await getAlbums();
let resourceManager = ability.context.resourceManager;
await driver.assertComponentExist(ON.id(`mediaType0`));
let mediaType: Component = await driver.findComponent(ON.id(`mediaType0`));
await mediaType.click();
await driver.delayMs(1000);
// 获取当前文件数据的个数,并依次删除
for (let i = 0; i < mediaAlbums[0].count; i++) {
let medias = await getAlbums();
await driver.delayMs(1000);
// 删除数据
await driver.assertComponentExist(ON.id(`delete${i}`));
let deleteData: Component = await driver.findComponent(ON.id(`delete${i}`));
await deleteData.click();
await driver.delayMs(1000);
await driver.assertComponentExist(ON.text(await resourceManager.getStringValue($r('app.string.agree'))));
let confirmBtn: Component = await driver.findComponent(ON.text(await resourceManager.getStringValue($r('app.string.agree'))));
await confirmBtn.click();
await driver.delayMs(1000);
// 校验是否删除成功
let mediaAblumsDeleted = await getAlbums();
if (mediaAblumsDeleted[0].count !== medias[0].count - 1) {
Logger.info(TAG, `Type deletion failed`)
expect().assertFail();
}
}
Logger.info(TAG, BUNDLE + 'DeleteMultipleData_001 end');
});
});
}

View File

@ -0,0 +1,72 @@
/*
* Copyright (c) 2022-2023 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import hilog from '@ohos.hilog';
import Ability from '@ohos.app.ability.UIAbility';
import AbilityDelegatorRegistry from '@ohos.app.ability.abilityDelegatorRegistry'
import { Hypium } from '@ohos/hypium'
import testsuite from '../test/List.test'
import Window from '@ohos.window'
import Want from '@ohos.app.ability.Want';
import AbilityConstant from '@ohos.app.ability.AbilityConstant';
export default class TestAbility extends Ability {
onCreate(want: Want, launchParam: AbilityConstant.LaunchParam) {
hilog.isLoggable(0x0000, 'testTag', hilog.LogLevel.INFO);
hilog.info(0x0000, 'testTag', '%{public}s', 'TestAbility onCreate');
hilog.info(0x0000, 'testTag', '%{public}s', 'want param:' + JSON.stringify(want) ?? '');
hilog.info(0x0000, 'testTag', '%{public}s', 'launchParam:'+ JSON.stringify(launchParam) ?? '');
let abilityDelegator = AbilityDelegatorRegistry.getAbilityDelegator();
let abilityDelegatorArguments = AbilityDelegatorRegistry.getArguments();
hilog.isLoggable(0x0000, 'testTag', hilog.LogLevel.INFO);
hilog.info(0x0000, 'testTag', '%{public}s', 'start run testcase!!!');
Hypium.hypiumTest(abilityDelegator, abilityDelegatorArguments, testsuite)
}
onDestroy() {
hilog.isLoggable(0x0000, 'testTag', hilog.LogLevel.INFO);
hilog.info(0x0000, 'testTag', '%{public}s', 'TestAbility onDestroy');
}
onWindowStageCreate(windowStage: Window.WindowStage) {
hilog.isLoggable(0x0000, 'testTag', hilog.LogLevel.INFO);
hilog.info(0x0000, 'testTag', '%{public}s', 'TestAbility onWindowStageCreate');
windowStage.loadContent('testability/pages/Index', (err, data) => {
if (err.code) {
hilog.isLoggable(0x0000, 'testTag', hilog.LogLevel.ERROR);
hilog.error(0x0000, 'testTag', 'Failed to load the content. Cause: %{public}s', JSON.stringify(err) ?? '');
return;
}
hilog.isLoggable(0x0000, 'testTag', hilog.LogLevel.INFO);
hilog.info(0x0000, 'testTag', 'Succeeded in loading the content. Data: %{public}s',
JSON.stringify(data) ?? '');
});
}
onWindowStageDestroy() {
hilog.isLoggable(0x0000, 'testTag', hilog.LogLevel.INFO);
hilog.info(0x0000, 'testTag', '%{public}s', 'TestAbility onWindowStageDestroy');
}
onForeground() {
hilog.isLoggable(0x0000, 'testTag', hilog.LogLevel.INFO);
hilog.info(0x0000, 'testTag', '%{public}s', 'TestAbility onForeground');
}
onBackground() {
hilog.isLoggable(0x0000, 'testTag', hilog.LogLevel.INFO);
hilog.info(0x0000, 'testTag', '%{public}s', 'TestAbility onBackground');
}
}

View File

@ -1,60 +0,0 @@
/*
* Copyright (c) 2022 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import UIAbility from '@ohos.app.ability.UIAbility'
import AbilityDelegatorRegistry from '@ohos.application.abilityDelegatorRegistry'
import { Hypium } from '@ohos/hypium'
import testsuite from '../test/List.test'
export default class TestAbility extends UIAbility {
onCreate(want, launchParam) {
console.log('TestAbility onCreate')
}
onDestroy() {
console.log('TestAbility onDestroy')
}
onWindowStageCreate(windowStage) {
console.log('TestAbility onWindowStageCreate')
windowStage.loadContent('testability/pages/Index', (err, data) => {
if (err.code) {
console.error('Failed to load the content. Cause:' + JSON.stringify(err))
return
}
console.info('Succeeded in loading the content. Data: ' + JSON.stringify(data))
})
globalThis.abilityContext = this.context
var abilityDelegator: any
abilityDelegator = AbilityDelegatorRegistry.getAbilityDelegator()
var abilityDelegatorArguments: any
abilityDelegatorArguments = AbilityDelegatorRegistry.getArguments()
console.info('start run testcase!!!')
Hypium.hypiumTest(abilityDelegator, abilityDelegatorArguments, testsuite)
}
onWindowStageDestroy() {
console.log('TestAbility onWindowStageDestroy')
}
onForeground() {
console.log('TestAbility onForeground')
}
onBackground() {
console.log('TestAbility onBackground')
}
}

View File

@ -13,40 +13,38 @@
* limitations under the License.
*/
import router from '@ohos.router'
import router from '@ohos.router';
import Logger from '../../utils/Logger';
const TAG: string = 'Index'
@Entry
@Component
struct Index {
aboutToAppear() {
console.info('TestAbility index aboutToAppear')
Logger.info(TAG, `TestAbility index aboutToAppear`)
}
@State message: string = 'Hello World'
build() {
Row() {
Column() {
Text(this.message)
.fontSize(50)
.fontWeight(FontWeight.Bold)
Button() {
Text('next page')
.fontSize(20)
.fontWeight(FontWeight.Bold)
}
.type(ButtonType.Capsule)
.margin({
top: 20
})
.backgroundColor('#0D9FFB')
.width('35%')
.height('5%')
.onClick(() => {
})
}
.width('100%')
}
.height('100%')
}
}
@State message: string = 'Hello World'
build() {
Row() {
Column() {
Text(this.message)
.fontSize(50)
.fontWeight(FontWeight.Bold)
Button() {
Text('next page')
.fontSize(20)
.fontWeight(FontWeight.Bold)
}.type(ButtonType.Capsule)
.margin({
top: 20
})
.backgroundColor('#0D9FFB')
.width('35%')
.height('5%')
.onClick(()=>{
})
}
.width('100%')
}
.height('100%')
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2023 Huawei Device Co., Ltd.
* Copyright (c) 2022-2024 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at

View File

@ -0,0 +1,29 @@
/*
* Copyright (c) 2022-2024 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import AbilityDelegatorRegistry from '@ohos.app.ability.abilityDelegatorRegistry';
const delegator = AbilityDelegatorRegistry.getAbilityDelegator();
export function getString(resource: Resource): string {
let manage = delegator.getAppContext().resourceManager
return manage.getStringSync(resource)
}
export async function getStringArray(resource: Resource): Promise<Array<string>> {
let manage = delegator.getAppContext().resourceManager
let menuList: Array<string> = await manage.getStringArrayValue(resource);
return menuList;
}

View File

@ -17,7 +17,6 @@
"module": {
"name": "entry_test",
"type": "feature",
"srcEntrance": "./ets/testability/TestAbility.ts",
"description": "$string:entry_test_desc",
"mainElement": "TestAbility",
"deviceTypes": [
@ -27,17 +26,16 @@
"deliveryWithInstall": true,
"installationFree": false,
"pages": "$profile:test_pages",
"uiSyntax": "ets",
"abilities": [
{
"name": "TestAbility",
"srcEntrance": "./ets/testability/TestAbility.ts",
"srcEntry": "./ets/testability/TestAbility.ets",
"description": "$string:TestAbility_desc",
"icon": "$media:icon",
"label": "$string:TestAbility_label",
"exported": true,
"startWindowIcon": "$media:icon",
"startWindowBackground": "$color:white",
"visible": true,
"skills": [
{
"actions": [

View File

@ -13,8 +13,8 @@
* limitations under the License.
*/
{
"hvigorVersion": "2.0.0",
"hvigorVersion": "4.0.2",
"dependencies": {
"@ohos/hvigor-ohos-plugin": "2.0.0"
"@ohos/hvigor-ohos-plugin": "4.0.2"
}
}
}

Binary file not shown.

Binary file not shown.

View File

@ -139,7 +139,7 @@ entry/src/main/ets/
```
git init
git config core.sparsecheckout true
echo code/BasicFeature/FileManagement/MediaCollections/ > .git/info/sparse-checkout
echo code/SystemFeature/FileManagement/MediaCollections/ > .git/info/sparse-checkout
git remote add origin https://gitee.com/openharmony/applications_app_samples.git
git pull origin master
```