chenjun1_wd

图片下载过时方法替换

... ... @@ -91,6 +91,8 @@ export { OperRowListView } from './src/main/ets/components/view/OperRowListView'
export { LiveOperRowListView } from './src/main/ets/components/view/LiveOperRowListView';
export { SaveNetWorkPictures } from './src/main/ets/components/SaveNetWorkPictures';
export { ImageDownloadComponent } from './src/main/ets/components/ImageDownloadComponent';
export { PageRepository } from './src/main/ets/repository/PageRepository';
... ... @@ -107,6 +109,6 @@ export { MorningEveningViewModel } from './src/main/ets/viewmodel/MorningEvening
export { GrayManageModel } from './src/main/ets/viewmodel/GrayManageModel'
export { VoiceInputView } from './src/main/ets/components/comment/view/VoiceInputView'
export { VoiceInputView } from './src/main/ets/components/comment/view/VoiceInputView'
// export {voicese}
\ No newline at end of file
... ...
/*
* Copyright (c) 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 http from '@ohos.net.http';
import ResponseCode from '@ohos.net.http';
import { image } from '@kit.ImageKit';
import { BusinessError } from '@ohos.base';
import common from '@ohos.app.ability.common';
import photoAccessHelper from '@ohos.file.photoAccessHelper';
import fs from '@ohos.file.fs';
import promptAction from '@ohos.promptAction';
import picker from '@ohos.file.picker';
import { taskpool } from '@kit.ArkTS';
import { httpRequest } from '../utils/httpRequest';
/**
* 实现步骤:
* 点击上部“下载”按钮进入”下载网络图片到手机相册”场景示例;点击下部“下载到指定路径”按钮进入”下载文件到指定用户目录”场景示例,
* 从而实现手机相册并进行网络图片的下载和保存。
* photoAccessHelper参考文档:
* https://developer.huawei.com/consumer/cn/doc/harmonyos-references/js-apis-photoaccesshelper
* saveButton参考文档
* https://developer.huawei.com/consumer/cn/doc/harmonyos-guides/savebutton-0000001820999677
*/
@Concurrent
async function getPicture(imageUrl: string): Promise<ArrayBuffer> {
let ret: ArrayBuffer = await new Promise((resolve, reject) => {
httpRequest.httpRequestInStream(imageUrl, (res: ArrayBuffer) => {
resolve(res); // 成功时解析Promise
}, () => {
// 下载失败时弹窗提示检查网络
promptAction.showToast({
message: $r('app.string.image_request_fail'),
duration: 2000
});
reject(new Error('Image download failed')); // 失败时拒绝Promise
});
});
return ret
}
@Component
export struct SaveNetWorkPictures {
@State image: PixelMap | undefined = undefined;
@State photoAccessHelper: photoAccessHelper.PhotoAccessHelper | undefined = undefined; // 相册模块管理实例
@State imageBuffer: ArrayBuffer | undefined = undefined; // 图片ArrayBuffer
// @Prop @Watch('onChangeUrl') url: string = ''
@State url: string = ''
/**
* 通过http的request方法从网络下载图片资源
*/
async getPicture() {
http.createHttp()// 显示网络图片的地址
// .request('https://gitee.com/harmonyos-cases/cases/raw/master/CommonAppDevelopment/feature/variablewatch/src/main/resources/base/media/variablewatch_grape.png',
// .request('https://cdnjdphoto.aikan.pdnews.cn/zhbj-20240830/image/content/4d61839662044ac796ec7331a90da5d8.jpg',
.request(this.url,
(error: BusinessError, data: http.HttpResponse) => {
if (error) {
// 下载失败时弹窗提示检查网络,不执行后续逻辑
promptAction.showToast({
message: '下载失败',
duration: 2000
})
return;
}
this.transcodePixelMap(data);
// 判断网络获取到的资源是否为ArrayBuffer类型
if (data.result instanceof ArrayBuffer) {
this.imageBuffer = data.result as ArrayBuffer;
}
}
)
}
/**
* 使用createPixelMap将ArrayBuffer类型的图片装换为PixelMap类型
* @param data:网络获取到的资源
*/
transcodePixelMap(data: http.HttpResponse) {
if (ResponseCode.ResponseCode.OK === data.responseCode) {
const imageData: ArrayBuffer = data.result as ArrayBuffer;
// 通过ArrayBuffer创建图片源实例。
const imageSource: image.ImageSource = image.createImageSource(imageData);
const options: image.InitializationOptions = {
'alphaType': 0, // 透明度
'editable': false, // 是否可编辑
'pixelFormat': 3, // 像素格式
'scaleMode': 1, // 缩略值
'size': { height: 50, width: 50 }
}; // 创建图片大小
// 通过属性创建PixelMap
imageSource.createPixelMap(options).then((pixelMap: PixelMap) => {
this.image = pixelMap;
});
}
}
/**
* 保存ArrayBuffer到图库
* @param buffer:图片ArrayBuffer
* @returns
*/
async saveImage(buffer: ArrayBuffer | string): Promise<void> {
const context = getContext(this) as common.UIAbilityContext; // 获取getPhotoAccessHelper需要的context
const helper = photoAccessHelper.getPhotoAccessHelper(context); // 获取相册管理模块的实例
const uri = await helper.createAsset(photoAccessHelper.PhotoType.IMAGE, 'jpg'); // 指定待创建的文件类型、后缀和创建选项,创建图片或视频资源
const file = await fs.open(uri, fs.OpenMode.READ_WRITE | fs.OpenMode.CREATE);
await fs.write(file.fd, buffer);
await fs.close(file.fd);
}
/**
* 保存ArrayBuffer到用户选择的路径
* @param buffer:图片ArrayBuffer
* @returns
*/
async pickerSave(buffer: ArrayBuffer | string): Promise<void> {
const photoSaveOptions = new picker.PhotoSaveOptions(); // 创建文件管理器保存选项实例
photoSaveOptions.newFileNames = ['PhotoViewPicker ' + new Date().getTime() + '.jpg']; // 保存文件名(可选)
const photoViewPicker = new picker.PhotoViewPicker;
photoViewPicker.save(photoSaveOptions)
.then(async (photoSvaeResult) => {
const uri = photoSvaeResult[0];
const file = await fs.open(uri, fs.OpenMode.READ_WRITE | fs.OpenMode.CREATE);
await fs.write(file.fd, buffer);
await fs.close(file.fd);
promptAction.showToast({
message: '保存成功',
duration: 2000
})
});
}
async aboutToAppear(): Promise<void> {
// this.getPicture();
this.onChangeUrl()
}
build() {
Stack({ alignContent: Alignment.Center }) {
// Column() {
// Text('下载')
// .fontWeight(FontWeight.Medium)
// }
Image(this.image)
.objectFit(ImageFit.Contain)
.width('50%')
.height(28)
SaveButton({ icon: SaveIconStyle.FULL_FILLED, buttonType: ButtonType.Capsule })
.iconSize(24)
.backgroundColor(Color.Transparent)
.iconColor(Color.White)// .markAnchor({ x: '100%' })
.position({ x: '25%' })
.onClick(async () => {
if (this.imageBuffer !== undefined) {
await this.saveImage(this.imageBuffer);
promptAction.showToast({
message: '成功',
duration: 2000
})
}
})
}
// .alignSelf(ItemAlign.Center)
// .align(Alignment.Center)
// .backgroundColor(Color.Red)
}
async onChangeUrl(): Promise<void> {
console.info(`cj2024 图片下载 ${this.url}`)
// const context = getContext(this) as common.UIAbilityContext;
// const atManager = abilityAccessCtrl.createAtManager();
// await atManager.requestPermissionsFromUser(context, PERMISSIONS);
// 通过任务池(taskpool)从网络下载图片资源
taskpool.execute(getPicture, this.url).then((res) => {
const imgBuffer = res as ArrayBuffer
this.imageBuffer = imgBuffer;
})
}
}
... ...
import { PhotoListBean } from 'wdBean/Index';
import { display, router } from '@kit.ArkUI';
import { ImageDownloadComponent } from '../components/ImageDownloadComponent';
import { MultiPictureDetailItemComponent } from '../components/MultiPictureDetailItemComponent';
import { Action } from 'wdBean';
import { WindowModel } from 'wdKit/Index';
import { SaveNetWorkPictures } from '../components/SaveNetWorkPictures';
const TAG = 'MultiPictureListPage';
... ... @@ -28,10 +28,9 @@ export struct MultiPictureListPage {
pageTransition() {
// PageTransitionEnter({ duration: this.noAnimation ? 0 : 300 })
PageTransitionExit({ duration: !this.noAnimation ? 0 : 300 })
PageTransitionExit({ duration: !this.noAnimation ? 0 : 300 })
}
aboutToAppear(): void {
//获取宽高尺寸
this.screenWidth = this.displayTool.width
... ... @@ -47,17 +46,17 @@ export struct MultiPictureListPage {
onPageShow(): void {
console.log(TAG, 'onPageShow')
WindowModel.shared.setWindowSystemBarProperties({ statusBarContentColor: '#ffffff'})
WindowModel.shared.setWindowSystemBarProperties({ statusBarContentColor: '#ffffff' })
}
onPageHide(): void {
console.log(TAG, 'onPageHide')
WindowModel.shared.setWindowSystemBarProperties({ statusBarContentColor: '#000000'})
WindowModel.shared.setWindowSystemBarProperties({ statusBarContentColor: '#000000' })
}
build() {
RelativeContainer() {
Row(){
Row() {
Image($r('app.media.icon_arrow_left_white'))
.width(24)
.height(24)
... ... @@ -121,7 +120,9 @@ export struct MultiPictureListPage {
}
.alignSelf(ItemAlign.Center)
.fontColor(Color.White)
ImageDownloadComponent({ url: this.currentUrl })
// ImageDownloadComponent({ url: this.currentUrl })
SaveNetWorkPictures({ url: this.currentUrl })
}
.margin({
top: 14,
... ... @@ -129,6 +130,7 @@ export struct MultiPictureListPage {
bottom: 14,
right: 0
})
// .backgroundColor(Color.Blue)
.id('e_swiper_titles')
.alignRules({
bottom: { anchor: "__container__", align: VerticalAlign.Bottom },
... ...
import { NetworkUtil, Logger, SPHelper, StringUtils } from 'wdKit';
import { Logger, NetworkUtil, SPHelper, StringUtils } from 'wdKit';
import { ResponseDTO } from 'wdNetwork';
import {
ContentDetailDTO,
InteractDataDTO,
Params,
PhotoListBean,
postInteractBrowsOperateParams,
postBatchAttentionStatusParams,
postInteractAccentionOperateParams,
Params,
InteractDataDTO
postInteractBrowsOperateParams
} from 'wdBean';
import { DateTimeUtils } from 'wdKit/Index';
import { WDRouterPage, WDRouterRule } from 'wdRouter/Index';
import { SpConstants } from 'wdConstant/Index';
import { common } from '@kit.AbilityKit';
import { CommentDialogView } from 'wdDetailPlayShortVideo/Index';
import { EmptyComponent,
ImageDownloadComponent,
import {
EmptyComponent,
MultiPictureDetailItemComponent,
MultiPictureDetailViewModel,
OperRowListView,
PageRepository,
publishCommentModel,
viewBlogItemInsightIntentShare} from 'wdComponent/Index';
import { ParamType, TrackConstants, TrackingButton, TrackingContent } from 'wdTracking/Index';
SaveNetWorkPictures,
viewBlogItemInsightIntentShare
} from 'wdComponent/Index';
import { ParamType, TrackConstants, TrackingContent } from 'wdTracking/Index';
const TAG = 'MultiPictureDetailPageComponent';
/**
* 多图(图集详情页)UI
*/
... ... @@ -96,7 +99,7 @@ export struct MultiPictureDetailPageComponent {
this.contentTrackingDict()
}
contentTrackingDict(){
contentTrackingDict() {
this.pageParam = {
'contentType': `${this.contentDetailData.newsType}`,
'contentId': `${this.contentDetailData.newsId}`,
... ... @@ -138,6 +141,7 @@ export struct MultiPictureDetailPageComponent {
bottom: { anchor: "__container__", align: VerticalAlign.Bottom },
middle: { anchor: "__container__", align: HorizontalAlign.Center }
})
CommentDialogView({
index: $index,
currentIndex: $currentIndex,
... ... @@ -156,7 +160,7 @@ export struct MultiPictureDetailPageComponent {
@Builder
rmh() {
if (!this.showDownload) {
Row(){
Row() {
Row() {
Row({ space: 8 }) {
if (this.getImgUrl()) {
... ... @@ -257,7 +261,7 @@ export struct MultiPictureDetailPageComponent {
Image($r('app.media.add'))
.width(12)
.height(12)
.margin({right: 3})
.margin({ right: 3 })
Text('关注').fontSize(12).fontColor(0xffffff)
}.alignItems(VerticalAlign.Center)
... ... @@ -268,7 +272,8 @@ export struct MultiPictureDetailPageComponent {
.height(24)
.onClick(() => {
this.handleAccention()
}).visibility(this.isShowButton ? Visibility.Visible : Visibility.None)
})
.visibility(this.isShowButton ? Visibility.Visible : Visibility.None)
} else {
Button({ type: ButtonType.Normal, stateEffect: true }) {
Row() {
... ... @@ -281,7 +286,8 @@ export struct MultiPictureDetailPageComponent {
.height(24)
.onClick(() => {
this.handleAccention()
}).visibility(this.isShowButton ? Visibility.Visible : Visibility.None)
})
.visibility(this.isShowButton ? Visibility.Visible : Visibility.None)
}
}
... ... @@ -429,6 +435,7 @@ export struct MultiPictureDetailPageComponent {
ListItem() {
this.ListItemTitle()
}
ListItem() {
this.ListItemDescription()
}
... ... @@ -499,11 +506,18 @@ export struct MultiPictureDetailPageComponent {
}
if (this.contentDetailData.photoList?.[this.swiperIndex].picPath) {
ImageDownloadComponent({ url: this.contentDetailData.photoList?.[this.swiperIndex].picPath })
// ImageDownloadComponent({ url: this.contentDetailData.photoList?.[this.swiperIndex].picPath })
// .parallelGesture(
// TapGesture()
// .onAction((event: GestureEvent) => {
// TrackingContent.download(1,TrackConstants.PageName.Atlas_Detail,TrackConstants.PageName.Atlas_Detail,this.pageParam)
// }))
SaveNetWorkPictures({ url: this.contentDetailData.photoList?.[this.swiperIndex].picPath })
.parallelGesture(
TapGesture()
.onAction((event: GestureEvent) => {
TrackingContent.download(1,TrackConstants.PageName.Atlas_Detail,TrackConstants.PageName.Atlas_Detail,this.pageParam)
TrackingContent.download(1, TrackConstants.PageName.Atlas_Detail, TrackConstants.PageName.Atlas_Detail,
this.pageParam)
}))
}
}
... ... @@ -521,7 +535,10 @@ export struct MultiPictureDetailPageComponent {
@Builder
noNet() {
EmptyComponent({
emptyType: 1, emptyButton: true, isBlack: true, retry: () => {
emptyType: 1,
emptyButton: true,
isBlack: true,
retry: () => {
this.getDetail()
}
})
... ... @@ -659,10 +676,12 @@ export struct MultiPictureDetailPageComponent {
// console.log(TAG, '关注号主==', JSON.stringify(res.data))
if (this.followStatus == '1') {
this.followStatus = '0'
TrackingContent.follow(true,this.followUserId,this.followUserName,TrackConstants.PageName.Atlas_Detail,TrackConstants.PageName.Atlas_Detail,this.pageParam)
TrackingContent.follow(true, this.followUserId, this.followUserName, TrackConstants.PageName.Atlas_Detail,
TrackConstants.PageName.Atlas_Detail, this.pageParam)
} else {
this.followStatus = '1'
TrackingContent.follow(false,this.followUserId,this.followUserName,TrackConstants.PageName.Atlas_Detail,TrackConstants.PageName.Atlas_Detail,this.pageParam)
TrackingContent.follow(false, this.followUserId, this.followUserName, TrackConstants.PageName.Atlas_Detail,
TrackConstants.PageName.Atlas_Detail, this.pageParam)
}
})
}
... ...