HarmonyOS上传文件以及权限授权

这篇具有很好参考价值的文章主要介绍了HarmonyOS上传文件以及权限授权。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

搞了一天,差不多搞完了,记录下,目前官方还有一些问题 会在下一个next版本修复

0、实现效果

鸿蒙实现图片上传

1、准备页面

build() {
    Row() {
      Column() {
        Button('选择图片28')
          .onClick(this.onChooseImage)
        // 显示选中的图片(本地地址 非http)
        ForEach(this.showChooseImage, (item, idnex) => {
          Image(item).width(80).height(80).margin({bottom: 20})
        })
        // 为了方便展示选中的图片信息
        ForEach(this.showListData, (item, idnex) => {
          Text(item.path)
        })
      }
      .width('100%')
    }
    .height('100%')
  }

2、授权逻辑

点击“选中图片28”之后,需要先判断是否有读写图片的权限。如果有走后面的流程,如果没有,需要系统弹窗让用户去授权。如果用户授权了,走后面的逻辑;如果用户不授权需要提示用户去系统里面的应用列表去授权(也可以不做这个操作)。

官方文档:文档中心

3、判断是否授权媒体

import abilityAccessCtrl, { Permissions } from '@ohos.abilityAccessCtrl';
let atManager = abilityAccessCtrl.createAtManager();
import bundleManager from '@ohos.bundle.bundleManager';
// let bundleFlags = bundleManager.BundleFlag.GET_BUNDLE_INFO_DEFAULT;
let bundleFlags = bundleManager.BundleFlag.GET_BUNDLE_INFO_WITH_APPLICATION;
// let tokenID = bundleFlags;
let tokenID
import common from '@ohos.app.ability.common';
import picker from '@ohos.file.picker';
import request from '@ohos.request';
let context = getContext(this) as common.UIAbilityContext;
/**
 * 对应用权限进行校验封装 我这边默认只能一个一个授权,多个授权自己封装
 */
export const permissionsIsAllow = async (type: Permissions, cb:Function) => {
  let bundleInfo: bundleManager.BundleInfo = await bundleManager.getBundleInfoForSelf(bundleFlags);
  let appInfo: bundleManager.ApplicationInfo = bundleInfo.appInfo;
  tokenID = appInfo.accessTokenId;
  console.log('tokenID', tokenID)
  try {
      atManager.checkAccessToken(tokenID, type).then((data) => {
      console.log(`${type} success, data->${JSON.stringify(data)}`);
      if (data === 0) { // 已授权
        cb()
      } else { // 未授权
        AlertDialog.show(
          {
            title: '温馨提示',
            message: '您还没有授权',
            autoCancel: false,
            alignment: DialogAlignment.Bottom,
            gridCount: 4,
            primaryButton: {
              value: '取消授权',
              action: () => {
                console.info('Callback when the first button is clicked')
                AlertDialog.show(
                  {
                    title: '温馨提示',
                    message: '必须要授权才能使用,是否前往应用进行授权',
                    autoCancel: false,
                    alignment: DialogAlignment.Bottom,
                    gridCount: 4,
                    primaryButton: {
                      value: '取消',
                      action: () => {
                        console.warn('用户再次取消授权')
                      }
                    },
                    secondaryButton: {
                      value: '前往授权',
                      action: () => {
                        let wantInfo = {
                          action: 'action.settings.app.info',
                          parameters: {
                            settingsParamBundleName: 'com.example.medicaltreatment' // 打开指定应用的详情页面
                          }
                        }
                        context.startAbility(wantInfo).then((data) => {
                          // ...
                          console.info('前往授权页面成功', JSON.stringify(data))
                        }).catch((err) => {
                          // ...
                          console.error('前往授权页面失败', JSON.stringify(err))
                        })
                      }
                    }
                  }
                )
              }
            },
            secondaryButton: {
              value: '确认授权',
              action: () => {
                atManager.requestPermissionsFromUser(context, [type]).then((data) => {
                  console.info("data:" + JSON.stringify(data));
                  console.info("data permissions:" + data.permissions);
                  console.info("data authResults:", JSON.stringify(data.authResults));
                  let length: number = data.authResults.length;
                  for (let i = 0; i < length; i++) {
                    if (data.authResults[i] === 0) {
                      // 用户授权,可以继续访问目标操作
                      cb()
                    } else {
                      // 用户拒绝授权,提示用户必须授权才能访问当前页面的功能,并引导用户到系统设置中打开相应的权限
                      return;
                    }
                  }
                }).catch((err) => {
                  console.info("data:" + JSON.stringify(err));
                })
              }
            },
            cancel: () => {
              console.info('Closed callbacks')
            }
          }
        )
      }
    }).catch((err) => {
      console.warn(`${type} fail, err->${JSON.stringify(err)}`);
    });
  } catch(err) {
    console.log(`catch err->${JSON.stringify(err)}`);
  }
}

效果:

harmonyos中axios上传文件,HarmonyOS,harmonyos,华为

harmonyos中axios上传文件,HarmonyOS,harmonyos,华为

4、选择图片

/**
 * 选择图片 单/多
 */
export const chooseImage = (cb: Function, number: number) => {
  try {
    let PhotoSelectOptions = new picker.PhotoSelectOptions();
    PhotoSelectOptions.MIMEType = picker.PhotoViewMIMETypes.IMAGE_TYPE;
    PhotoSelectOptions.maxSelectNumber = number;
    let photoPicker = new picker.PhotoViewPicker();
    photoPicker.select(PhotoSelectOptions).then((PhotoSelectResult) => {
      console.info('PhotoViewPicker.select successfully, PhotoSelectResult uri: ' + JSON.stringify(PhotoSelectResult));
      console.log('PhotoSelectResult111', PhotoSelectResult)
      if (PhotoSelectResult && PhotoSelectResult.photoUris) {
        const imgList = PhotoSelectResult.photoUris;
        cb(imgList)
      }
    }).catch((err) => {
      console.error('PhotoViewPicker.select failed with err: ' + err);
    });
  } catch (err) {
    console.error('PhotoViewPicker failed with err: ' + err);
  }
}

选中的图片的路径是这样的:

harmonyos中axios上传文件,HarmonyOS,harmonyos,华为

5、将datashare的路径进行转换

为什么要转换: 看官方文档:文档中心

private onDealWithData = (fileUris: string[]) => {
    console.log('appLog:fileUris:', JSON.stringify(fileUris));
    this.showChooseImage = fileUris
    this.onUploadImageFileList = []
    const promises = fileUris.map(async item => await this.onPromiseTask(item));
    Promise.all(promises)
      .then(() => {
        console.log("All tasks completed. Proceed to the next step.");
        if (this.onUploadImageFileList.length > 0) {
          this.onUploadFile(this.onUploadImageFileList);
        } else {
          console.log('onUploadImageFileList的长度为0')
        }
        // 在这里执行下一步操作
      })
      .catch(error => {
        console.error("Error occurred:", error);
      });
  }
  private onPromiseTask = (v) => {
    return new Promise((resolve, reject) => {
      fs.open(v, fs.OpenMode.READ_ONLY).then((file) => { // READ_ONLY READ_WRITE
        const dateStr = (new Date().getTime()).toString()
        let newPath = context.cacheDir + `/${dateStr}.png`;
        fs.copyFile(file.fd, newPath).then(() => {
          console.info("applog:copy file succeed");
          let realUri = "internal://cache/"+newPath.split("cache/")[1];
          const obj = {
            filename: `${dateStr}.png`,
            name: "files",
            uri: realUri,
            type: "png"
          }
          this.onUploadImageFileList.push(obj);
          resolve(true)
        }).catch((err) => {
          console.info("applog:copy file failed with error message: " + err.message + ", error code: " + err.code);
        });
      }).catch((err) => {
        console.info("applog:open file failed with error message: " + err.message + ", error code: " + err.code);
      });
    })
  }

转换好之后的文件路径是这样的:

harmonyos中axios上传文件,HarmonyOS,harmonyos,华为

6、上传到服务器

/**
 * 上传图片
 */
export const uploadImageListOrSingle = async (files, cb:Function) => {
  const token = await PreferenceModel.getPreference('tokenInfo', 'token')
  const uploadConfigData = []
  console.info('转换之后的files', JSON.stringify(files))
  files.forEach(v => {
    const uploadConfig = {
      url: 'https://xxx.xxx.xxx/api/v1.0/oss/upload',
      header: {
        'Hwkj-Custom-Client': 'PlatformOfWeb',
        "Authorization": token ? 'Bearer ' + token : '',
      },
      method: "POST",
      files: [v],
      data: [{ name: "files", value: "files"}],
    }
    uploadConfigData.push(uploadConfig)
  })
  const promises = uploadConfigData.map(async item => await onGetImageUploadBackUrl(item));
  Promise.all(promises)
    .then((data) => {
      const showList = []
      data.forEach(v => {
        showList.push(v[0])
      })
      cb(showList)
    })
    .catch(error => {
      console.error("Error occurred1:", error);
    });
}
const onGetImageUploadBackUrl = (uploadConfig) => {
  let uploadTask;
  return new Promise((resolve, reject) => {
    try {
      request.uploadFile( getContext(this), uploadConfig).then((data) => {
        console.info('JSON.stringify(data)', JSON.stringify(data))
        uploadTask = data;
        let upProgressCallback = (data) => {
          console.info("data1111:" + JSON.stringify(data));
          resolve(data)
        };
        uploadTask.on('complete', upProgressCallback);
      }).catch((err) => {
        console.error('Failed to request the upload. Cause: ' + JSON.stringify(err));
      });
    } catch (err) {
      console.error('applog:', JSON.stringify(err));
      console.error('err.code : ' + err.code + ', err.message : ' + err.message);
    }
  })
}

6、显示选中的和上传接口返回的数据信息(效果图)

harmonyos中axios上传文件,HarmonyOS,harmonyos,华为

注意事项:

1、不知道为什么checkAccessToken永远走的.catch,不知道是代码原因还是本来这个api的原因。导致用户同意授权之后,下一次仍然是未授权。目前还未解决,还在等官方的回答(已解决 上方的代码已经解决了)

2、大家可以看到 当通过上传接口返回的数据并不是服务器返回的数据而是官方返回的图片信息

harmonyos中axios上传文件,HarmonyOS,harmonyos,华为

我已经对这个问题给官方说了:

“我们这个上传接口会返回一个图片的url 但是现在执行complete之后 返回的并不是服务器返回的数据 这种情况怎么办呢?”

官方的回答是:

harmonyos中axios上传文件,HarmonyOS,harmonyos,华为

7、完整代码

1、页面ui代码

import fs from '@ohos.file.fs';
import common from '@ohos.app.ability.common';
let context = getContext(this) as common.UIAbilityContext;
import { permissionsIsAllow, chooseImage, uploadImageListOrSingle } from '../../utils'
@Entry
@Component
struct AccountSettingIndex {
  @State showListData: any[] = []
  @State showChooseImage: any[] = []
  @State onUploadImageFileList: any[] = []
  private onChooseImage = () => {
    permissionsIsAllow('ohos.permission.WRITE_MEDIA', () => { // READ_MEDIA
      this.onChooseImageFin()
    })
  }
  private onChooseImageFin = () => {
    chooseImage((imgList) => {
      this.onDealWithData(imgList)
    }, 2)
  }
  private onDealWithData = (fileUris: string[]) => {
    console.log('appLog:fileUris:', JSON.stringify(fileUris));
    this.showChooseImage = fileUris
    this.onUploadImageFileList = []
    const promises = fileUris.map(async item => await this.onPromiseTask(item));
    Promise.all(promises)
      .then(() => {
        console.log("All tasks completed. Proceed to the next step.");
        if (this.onUploadImageFileList.length > 0) {
          this.onUploadFile(this.onUploadImageFileList);
        } else {
          console.log('onUploadImageFileList的长度为0')
        }
        // 在这里执行下一步操作
      })
      .catch(error => {
        console.error("Error occurred:", error);
      });
  }
  private onPromiseTask = (v) => {
    return new Promise((resolve, reject) => {
      fs.open(v, fs.OpenMode.READ_ONLY).then((file) => { // READ_ONLY READ_WRITE
        const dateStr = (new Date().getTime()).toString()
        let newPath = context.cacheDir + `/${dateStr}.png`;
        fs.copyFile(file.fd, newPath).then(() => {
          console.info("applog:copy file succeed");
          let realUri = "internal://cache/"+newPath.split("cache/")[1];
          const obj = {
            filename: `${dateStr}.png`,
            name: "files",
            uri: realUri,
            type: "png"
          }
          this.onUploadImageFileList.push(obj);
          resolve(true)
        }).catch((err) => {
          console.info("applog:copy file failed with error message: " + err.message + ", error code: " + err.code);
        });
      }).catch((err) => {
        console.info("applog:open file failed with error message: " + err.message + ", error code: " + err.code);
      });
    })
  }
  private onUploadFile = async (fileUri) => {
    uploadImageListOrSingle(fileUri, (data) => {
      console.log('获取到的url是', typeof data ,data)
      this.showListData = data
    })
  }
  build() {
    Row() {
      Column() {
        Button('选择图片28')
          .onClick(this.onChooseImage)
        // 显示选中的图片
        ForEach(this.showChooseImage, (item, idnex) => {
          Image(item).width(80).height(80).margin({bottom: 20})
        })
        // 为了方便展示选中的图片信息
        ForEach(this.showListData, (item, idnex) => {
          Text(item.path)
        })
      }
      .width('100%')
    }
    .height('100%')
  }
}

2、utils文件下面的三个方法

import abilityAccessCtrl, { Permissions } from '@ohos.abilityAccessCtrl';
let atManager = abilityAccessCtrl.createAtManager();
import bundleManager from '@ohos.bundle.bundleManager';
// let bundleFlags = bundleManager.BundleFlag.GET_BUNDLE_INFO_DEFAULT;
let bundleFlags = bundleManager.BundleFlag.GET_BUNDLE_INFO_WITH_APPLICATION;
// let tokenID = bundleFlags;
let tokenID
import common from '@ohos.app.ability.common';
import picker from '@ohos.file.picker';
import request from '@ohos.request';
let context = getContext(this) as common.UIAbilityContext;
/**
 * 对应用权限进行校验封装 我这边默认只能一个一个授权,多个授权自己封装
 */
export const permissionsIsAllow = async (type: Permissions, cb:Function) => {
  let bundleInfo: bundleManager.BundleInfo = await bundleManager.getBundleInfoForSelf(bundleFlags);
  let appInfo: bundleManager.ApplicationInfo = bundleInfo.appInfo;
  tokenID = appInfo.accessTokenId;
  console.log('tokenID', tokenID)
  try {
      atManager.checkAccessToken(tokenID, type).then((data) => {
      console.log(`${type} success, data->${JSON.stringify(data)}`);
      if (data === 0) { // 已授权
        cb()
      } else { // 未授权
        AlertDialog.show(
          {
            title: '温馨提示',
            message: '您还没有授权',
            autoCancel: false,
            alignment: DialogAlignment.Bottom,
            gridCount: 4,
            primaryButton: {
              value: '取消授权',
              action: () => {
                console.info('Callback when the first button is clicked')
                AlertDialog.show(
                  {
                    title: '温馨提示',
                    message: '必须要授权才能使用,是否前往应用进行授权',
                    autoCancel: false,
                    alignment: DialogAlignment.Bottom,
                    gridCount: 4,
                    primaryButton: {
                      value: '取消',
                      action: () => {
                        console.warn('用户再次取消授权')
                      }
                    },
                    secondaryButton: {
                      value: '前往授权',
                      action: () => {
                        let wantInfo = {
                          action: 'action.settings.app.info',
                          parameters: {
                            settingsParamBundleName: 'com.example.medicaltreatment' // 打开指定应用的详情页面
                          }
                        }
                        context.startAbility(wantInfo).then((data) => {
                          // ...
                          console.info('前往授权页面成功', JSON.stringify(data))
                        }).catch((err) => {
                          // ...
                          console.error('前往授权页面失败', JSON.stringify(err))
                        })
                      }
                    }
                  }
                )
              }
            },
            secondaryButton: {
              value: '确认授权',
              action: () => {
                atManager.requestPermissionsFromUser(context, [type]).then((data) => {
                  console.info("data:" + JSON.stringify(data));
                  console.info("data permissions:" + data.permissions);
                  console.info("data authResults:", JSON.stringify(data.authResults));
                  let length: number = data.authResults.length;
                  for (let i = 0; i < length; i++) {
                    if (data.authResults[i] === 0) {
                      // 用户授权,可以继续访问目标操作
                      cb()
                    } else {
                      // 用户拒绝授权,提示用户必须授权才能访问当前页面的功能,并引导用户到系统设置中打开相应的权限
                      return;
                    }
                  }
                }).catch((err) => {
                  console.info("data:" + JSON.stringify(err));
                })
              }
            },
            cancel: () => {
              console.info('Closed callbacks')
            }
          }
        )
      }
    }).catch((err) => {
      console.warn(`${type} fail, err->${JSON.stringify(err)}`);
    });
  } catch(err) {
    console.log(`catch err->${JSON.stringify(err)}`);
  }
}
/**
 * 选择图片 单/多
 */
export const chooseImage = (cb: Function, number: number) => {
  try {
    let PhotoSelectOptions = new picker.PhotoSelectOptions();
    PhotoSelectOptions.MIMEType = picker.PhotoViewMIMETypes.IMAGE_TYPE;
    PhotoSelectOptions.maxSelectNumber = number;
    let photoPicker = new picker.PhotoViewPicker();
    photoPicker.select(PhotoSelectOptions).then((PhotoSelectResult) => {
      console.info('PhotoViewPicker.select successfully, PhotoSelectResult uri: ' + JSON.stringify(PhotoSelectResult));
      console.log('PhotoSelectResult111', PhotoSelectResult)
      if (PhotoSelectResult && PhotoSelectResult.photoUris) {
        const imgList = PhotoSelectResult.photoUris;
        cb(imgList)
      }
    }).catch((err) => {
      console.error('PhotoViewPicker.select failed with err: ' + err);
    });
  } catch (err) {
    console.error('PhotoViewPicker failed with err: ' + err);
  }
}
/**
 * 上传图片
 */
export const uploadImageListOrSingle = async (files, cb:Function) => {
  const token = await PreferenceModel.getPreference('tokenInfo', 'token')
  const uploadConfigData = []
  console.info('转换之后的files', JSON.stringify(files))
  files.forEach(v => {
    const uploadConfig = {
      url: 'https://xxx.xxx.com/api/v1.0/oss/upload',
      header: {
        'Hwkj-Custom-Client': 'PlatformOfWeb',
        "Authorization": token ? 'Bearer ' + token : '',
      },
      method: "POST",
      files: [v],
      data: [{ name: "files", value: "files"}],
    }
    uploadConfigData.push(uploadConfig)
  })
  const promises = uploadConfigData.map(async item => await onGetImageUploadBackUrl(item));
  Promise.all(promises)
    .then((data) => {
      const showList = []
      data.forEach(v => {
        showList.push(v[0])
      })
      cb(showList)
    })
    .catch(error => {
      console.error("Error occurred1:", error);
    });
}
const onGetImageUploadBackUrl = (uploadConfig) => {
  let uploadTask;
  return new Promise((resolve, reject) => {
    try {
      request.uploadFile( getContext(this), uploadConfig).then((data) => {
        console.info('JSON.stringify(data)', JSON.stringify(data))
        uploadTask = data;
        let upProgressCallback = (data) => {
          console.info("data1111:" + JSON.stringify(data));
          resolve(data)
        };
        uploadTask.on('complete', upProgressCallback);
      }).catch((err) => {
        console.error('Failed to request the upload. Cause: ' + JSON.stringify(err));
      });
    } catch (err) {
      console.error('applog:', JSON.stringify(err));
      console.error('err.code : ' + err.code + ', err.message : ' + err.message);
    }
  })
}

上一章:HarmonyOS自定义标题栏-CSDN博客

下一章:HarmonyOS文件下载以及消息通知-CSDN博客文章来源地址https://www.toymoban.com/news/detail-831477.html

到了这里,关于HarmonyOS上传文件以及权限授权的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 非华为机型如何体验HarmonyOS鸿蒙系统 刷写HarmonyOS鸿蒙GSI系统以及一些初步的bug修复

    最近很多视频网站有非华为机型使用HarmonyOS鸿蒙系统的演示。其实大都是刷了HarmonyOS鸿蒙系统gsi系统。体验还可以。有些刷入后bug较多。那么这些机型是如何刷写gsi?可以参考我以往帖子 安卓玩机搞机-----没有第三方包 刷写第三方各种GSI系统 体验非官方系统_gsi刷机包_安卓机

    2024年02月09日
    浏览(47)
  • HarmonyOS引导页登陆页以及tabbar的代码说明 登陆页2

    代码:这里的prompt.showToast是弹出提示,@Extend(TextInput) 的功能是对TextInput做了公用的样式。isShowProgress是用来控制isShowProgress,出来一个等待效果 ` import prompt from ‘@ohos.promptAction’; import router from ‘@ohos.router’; import CommonConstants from ‘…/common/constants/CommonConstants’; /** 样式Te

    2024年02月03日
    浏览(34)
  • HarmonyOS4.0 系列——06、渲染之条件渲染、循环渲染以及懒加载渲染

    ArkTS 提供了渲染控制的能力。条件渲染可根据应用的不同状态,使用 if、else 和 else if 渲染对应状态下的 UI 内容。 写法和 TS 的一样,简单看一下即可 效果: 另外,@State 定义的变量归父组件所有。因此,当 子组件 实例被删除时,该变量不会被销毁。 子组件 通过 @Link装饰器

    2024年01月16日
    浏览(48)
  • HarmonyOS4.0系列——07、自定义组件的生命周期、路由以及路由传参

    允许在生命周期函数中使用 Promise 和异步回调函数,比如网络资源获取,定时器设置等; 即被@Entry 装饰的组件生命周期,提供以下生命周期接口: onPageShow 页面加载时触发,页面每次显示时触发一次,包括路由过程、应用进入前台等场景。 onPageHide 从第一个页面跳转第二个

    2024年01月21日
    浏览(42)
  • HarmonyOS鸿蒙学习基础篇 - 项目目录和文件介绍

    ├── hvigor //存储购置信息的文件,主要用于发布打包 ├── idea  //开发工具相关配置可忽略 ├── AppScope //工程目录 全局公共资源存放路径  │   └── resources   │   │   └── base │   │   │   └── element //常亮存放 │   │   │       └── string.json //保

    2024年01月21日
    浏览(40)
  • 鸿蒙HarmonyOS应用开发:扫描仪文件扫描

    华为鸿蒙HarmonyOS已经发展到4.0,使用ArkTS作为开发语言。这篇文章结合Dynamsoft Service开发一个简单的鸿蒙应用,用来获取办公室里连接PC的扫描仪( 惠普,富士通,爱普生,等 ),把文档扫描到手机里。 Dynamsoft Service 在连接着扫描仪的电脑上安装Dynamsoft Service。安装包可以满足各

    2024年02月07日
    浏览(76)
  • ArkUI框架之声明式 UI 条件渲染&声明周期以及案例美化实战运用【OpenHarmony/HarmonyOS】

    1.1.1 用户名位数判断 实现用户名位数判断可以直接在build方法函数里进行写if语句的条件判断。 我们把用户名改到超出五位查看效果如下:

    2024年02月06日
    浏览(43)
  • HarmonyOS/OpenHarmony元服务开发-配置卡片的配置文件

    卡片相关的配置文件主要包含FormExtensionAbility的配置和卡片的配置两部分: 1.卡片需要在module.json5配置文件中的extensionAbilities标签下,配置FormExtensionAbility相关信息。FormExtensionAbility需要填写metadata元信息标签,其中键名称为固定字符串“ohos.extension.form”,资源为卡片的具体配

    2024年02月14日
    浏览(35)
  • HarmonyOS鸿蒙基于Java开发:Java UI 资源文件的分类

    目录 resources目录 限定词目录 限定词目录的命名要求 限定词目录与设备状态的匹配规则 资源组目录 创建资源文件 应用的资源文件(字符串、图片、音频等)统一存放于resources目录下,便于开发者使用和维护。resources目录包括三类目录,一类为base目录与限定词目录,二类为

    2024年01月16日
    浏览(37)
  • 【HarmonyOS】实现将pcm音频文件进行编码并写入文件(API6 Java)

     【】 音频编码、管道模式、createEncoder 【写在前面】 在使用API6开发HarmonyOS应用时,如何将pcm源文件进行编码并写入文件,最后生成aac文件,本文直接附上主要代码开发步骤供大家参考。 【主要功能代码】 【说明和注意事项】 1、AAC文件有两种添加头文件方式:ADIF与

    2024年02月11日
    浏览(37)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包