鸿蒙上架提审驳回理由常见解决方案
本文用于采集应用上架驳回理由,定期汇总到 uniapp 鸿蒙文档中。常见的问题可在 https://uniapp.dcloud.net.cn/tutorial/harmony/runbuild.html 进行查询。如果你遇到了除此之外的驳回理由,可留言。
tab 走焦
近期有用户反馈,应用无法响应键盘 tab 按键
> 应用/元服务中的走焦事件能够响应tab键或方向键切换。https://developer.huawei.com/consumer/cn/doc/harmonyos-guides/device-compatible
在电脑、平台、折叠电脑上属于规则级别,也就是强制要求。
临时规避方案1,自行明确当前是否需要支持平板,如果目前不需要可在代码中搜索 devicetype,保持为 phone ,在 uniapp 后台、agc 后台表格里只勾选手机,也就是避免支持平板。
解决方案2:你可在指定的组件中,添加 tabindex,从而让功能区支持 tab 切换。目前规则中未明确要求支持回车按键,可忽略处理,也可在组件中,使用 renderjs ,在 renderjs 的 mounted/unmounted 里监听、取消监听 addEventListener keydown 相关事件,主动触发 click
可参考来自社区热心用户的方案,请参考 https://ask.dcloud.net.cn/question/215693 评论区。
后续会针对性优化。
本文用于采集应用上架驳回理由,定期汇总到 uniapp 鸿蒙文档中。常见的问题可在 https://uniapp.dcloud.net.cn/tutorial/harmony/runbuild.html 进行查询。如果你遇到了除此之外的驳回理由,可留言。
tab 走焦
近期有用户反馈,应用无法响应键盘 tab 按键
> 应用/元服务中的走焦事件能够响应tab键或方向键切换。https://developer.huawei.com/consumer/cn/doc/harmonyos-guides/device-compatible
在电脑、平台、折叠电脑上属于规则级别,也就是强制要求。
临时规避方案1,自行明确当前是否需要支持平板,如果目前不需要可在代码中搜索 devicetype,保持为 phone ,在 uniapp 后台、agc 后台表格里只勾选手机,也就是避免支持平板。
解决方案2:你可在指定的组件中,添加 tabindex,从而让功能区支持 tab 切换。目前规则中未明确要求支持回车按键,可忽略处理,也可在组件中,使用 renderjs ,在 renderjs 的 mounted/unmounted 里监听、取消监听 addEventListener keydown 相关事件,主动触发 click
可参考来自社区热心用户的方案,请参考 https://ask.dcloud.net.cn/question/215693 评论区。
后续会针对性优化。
收起阅读 »阿里退役程序猿,十年全栈经验全职开发,欢迎老板来咨询~
我的优势
1、精通 Java 、 PHP 、 Go 、 Vue全家桶 、 React 、 UniApp 、 UniAppX 等技术栈,熟练使用 前后端分离开发 、 微服务架构 、容器化部署 等技术,拥有丰富的项目开发经验。
2、能够独立完成从项目的 分析 、设计 、 开发 、测试 、部署 到 维护与优化 的全过程,能 快速的对需求进行梳理并制定开发计划。
3、注重代码可维护性、可扩展性、性能优化等方面的工作。
4、汇聚多行业100+成熟项目案例 可供复用,效率倍增,快人一步。
如果您正在寻找一位高效、专业的开发者来完成您的项目,我非常愿意为您提供优质的服务,共同推动项目顺利进行。
如果您对我的技能与工作经验感兴趣,请通过微信联系我,我们可以进一步探讨您的具体项目需求,并且开展合作。
V:TombaughWechat
我的优势
1、精通 Java 、 PHP 、 Go 、 Vue全家桶 、 React 、 UniApp 、 UniAppX 等技术栈,熟练使用 前后端分离开发 、 微服务架构 、容器化部署 等技术,拥有丰富的项目开发经验。
2、能够独立完成从项目的 分析 、设计 、 开发 、测试 、部署 到 维护与优化 的全过程,能 快速的对需求进行梳理并制定开发计划。
3、注重代码可维护性、可扩展性、性能优化等方面的工作。
4、汇聚多行业100+成熟项目案例 可供复用,效率倍增,快人一步。
如果您正在寻找一位高效、专业的开发者来完成您的项目,我非常愿意为您提供优质的服务,共同推动项目顺利进行。
如果您对我的技能与工作经验感兴趣,请通过微信联系我,我们可以进一步探讨您的具体项目需求,并且开展合作。
V:TombaughWechat
Uni-Grid二次进入样式问题深度解析与解决方案
Uni-Grid二次进入样式问题深度解析与解决方案
一、uni-grid组件概述
uni-grid是uni-app框架中用于实现网格布局的UI组件,特别适用于展示多个项目或产品的场景。它可以将子元素按照行和列的网格方式进行自动排列,保持布局的整齐和一致性。uni-grid组件提供灵活的布局选项,包括网格大小的设定、行列的对齐方式、间距调整等,使开发者能够在设计UI时保持美观性
1
2
。
主要应用场景:
电商分类商品列表展示
功能入口按钮布局
新闻资讯卡片展示
多项目对比展示
二、二次进入样式问题表现
uni-grid在二次进入页面时常见的样式问题主要包括:
少一列现象:第二次进入页面时,网格布局的最后一列可能消失或显示不全
7
样式闪烁:页面切换时出现短暂的布局错乱或闪烁现象
字节小程序嵌套问题:在字节跳动小程序中,由于自定义组件多一层嵌套,可能导致布局失效
8
边框显示异常:二次进入时边框可能错位或消失
间距变化:网格项之间的间距在二次进入时可能不一致
三、问题原因分析
- 布局计算机制
uni-grid在首次渲染时会根据当前容器尺寸计算布局,但二次进入时可能由于以下原因导致计算不准确:
容器尺寸变化未被正确检测
缓存了错误的布局参数
响应式更新机制延迟
-
平台差异
不同平台对CSS Grid布局的支持程度不同,特别是小程序环境存在额外的渲染层,可能导致样式表现不一致
8
。 -
组件内部实现
uni-grid组件在某些版本中存在以下问题:
列数计算逻辑缺陷
状态管理不完善
样式重置不彻底
四、解决方案与最佳实践
- 基础解决方案
方案一:去除边框
html
Copy Code
<column="4" :highlight="true" :show-border="false">
<!-- 网格项内容 -->
</uni-grid>`` 通过设置show-border="false"`可以避免边框相关的问题:ml-citation{ref="7" data="citationList"}。
方案二:固定外层容器宽度
<view style="width: 100%;">
<uni-grid :column="4">
<!-- 网格项内容 -->
</uni-grid>
</view>
2. 字节小程序特殊处理
对于字节小程序中的嵌套问题,可以使用以下方案:
方案一:使用customStyle属性
BbS.rasyi45.cn/PoSt/1118_19299.HtM
BbS.by00ez4.cn/PoSt/1118_37172.HtM
BbS.azlqul5.cn/PoSt/1118_18151.HtM
BbS.z5tiiyy.cn/PoSt/1118_83137.HtM
BbS.n9trnzh.cn/PoSt/1118_20556.HtM
BbS.38zp1cm.cn/PoSt/1118_67206.HtM
BbS.na2xy0k.cn/PoSt/1118_48017.HtM
BbS.vb5kftl.cn/PoSt/1118_70297.HtM
BbS.cjn8dgi.cn/PoSt/1118_41500.HtM
BbS.bhkgwzx.cn/PoSt/1118_03535.HtM
BbS.rasyi45.cn/PoSt/1118_69627.HtM
BbS.by00ez4.cn/PoSt/1118_51140.HtM
BbS.azlqul5.cn/PoSt/1118_24675.HtM
BbS.z5tiiyy.cn/PoSt/1118_48794.HtM
BbS.n9trnzh.cn/PoSt/1118_05781.HtM
BbS.38zp1cm.cn/PoSt/1118_78901.HtM
BbS.na2xy0k.cn/PoSt/1118_14040.HtM
BbS.vb5kftl.cn/PoSt/1118_77932.HtM
BbS.cjn8dgi.cn/PoSt/1118_08901.HtM
BbS.bhkgwzx.cn/PoSt/1118_11627.HtM
BbS.rasyi45.cn/PoSt/1118_25034.HtM
BbS.by00ez4.cn/PoSt/1118_40190.HtM
BbS.azlqul5.cn/PoSt/1118_52596.HtM
BbS.z5tiiyy.cn/PoSt/1118_95405.HtM
BbS.n9trnzh.cn/PoSt/1118_58926.HtM
BbS.38zp1cm.cn/PoSt/1118_55895.HtM
BbS.na2xy0k.cn/PoSt/1118_60516.HtM
BbS.vb5kftl.cn/PoSt/1118_83011.HtM
BbS.cjn8dgi.cn/PoSt/1118_65087.HtM
BbS.bhkgwzx.cn/PoSt/1118_11916.HtM
BbS.rasyi45.cn/PoSt/1118_50730.HtM
BbS.by00ez4.cn/PoSt/1118_87660.HtM
BbS.azlqul5.cn/PoSt/1118_98032.HtM
BbS.z5tiiyy.cn/PoSt/1118_57044.HtM
BbS.n9trnzh.cn/PoSt/1118_11285.HtM
BbS.38zp1cm.cn/PoSt/1118_65869.HtM
BbS.na2xy0k.cn/PoSt/1118_77049.HtM
BbS.vb5kftl.cn/PoSt/1118_28621.HtM
BbS.cjn8dgi.cn/PoSt/1118_07305.HtM
BbS.bhkgwzx.cn/PoSt/1118_50869.HtM
BbS.rasyi45.cn/PoSt/1118_63530.HtM
BbS.by00ez4.cn/PoSt/1118_55851.HtM
BbS.azlqul5.cn/PoSt/1118_33005.HtM
BbS.z5tiiyy.cn/PoSt/1118_64993.HtM
BbS.n9trnzh.cn/PoSt/1118_35153.HtM
BbS.38zp1cm.cn/PoSt/1118_18891.HtM
BbS.na2xy0k.cn/PoSt/1118_17872.HtM
BbS.vb5kftl.cn/PoSt/1118_94456.HtM
BbS.cjn8dgi.cn/PoSt/1118_91569.HtM
BbS.bhkgwzx.cn/PoSt/1118_83731.HtM
BbS.rasyi45.cn/PoSt/1118_08124.HtM
BbS.by00ez4.cn/PoSt/1118_96290.HtM
BbS.azlqul5.cn/PoSt/1118_95198.HtM
BbS.z5tiiyy.cn/PoSt/1118_45924.HtM
BbS.n9trnzh.cn/PoSt/1118_42449.HtM
BbS.38zp1cm.cn/PoSt/1118_35483.HtM
BbS.na2xy0k.cn/PoSt/1118_88432.HtM
BbS.vb5kftl.cn/PoSt/1118_73893.HtM
BbS.cjn8dgi.cn/PoSt/1118_49010.HtM
BbS.bhkgwzx.cn/PoSt/1118_57819.HtM
BbS.rasyi45.cn/PoSt/1118_97562.HtM
BbS.by00ez4.cn/PoSt/1118_28059.HtM
BbS.azlqul5.cn/PoSt/1118_34118.HtM
BbS.z5tiiyy.cn/PoSt/1118_36384.HtM
BbS.n9trnzh.cn/PoSt/1118_90347.HtM
BbS.38zp1cm.cn/PoSt/1118_34379.HtM
BbS.na2xy0k.cn/PoSt/1118_41241.HtM
BbS.vb5kftl.cn/PoSt/1118_42674.HtM
BbS.cjn8dgi.cn/PoSt/1118_62028.HtM
BbS.bhkgwzx.cn/PoSt/1118_53898.HtM
BbS.rasyi45.cn/PoSt/1118_98630.HtM
BbS.by00ez4.cn/PoSt/1118_90659.HtM
BbS.azlqul5.cn/PoSt/1118_02696.HtM
BbS.z5tiiyy.cn/PoSt/1118_41148.HtM
BbS.n9trnzh.cn/PoSt/1118_40116.HtM
BbS.38zp1cm.cn/PoSt/1118_06465.HtM
BbS.na2xy0k.cn/PoSt/1118_59674.HtM
BbS.vb5kftl.cn/PoSt/1118_48963.HtM
BbS.cjn8dgi.cn/PoSt/1118_98155.HtM
BbS.bhkgwzx.cn/PoSt/1118_51029.HtM
BbS.rasyi45.cn/PoSt/1118_69314.HtM
BbS.by00ez4.cn/PoSt/1118_49963.HtM
BbS.azlqul5.cn/PoSt/1118_89278.HtM
BbS.z5tiiyy.cn/PoSt/1118_36703.HtM
BbS.n9trnzh.cn/PoSt/1118_88376.HtM
BbS.38zp1cm.cn/PoSt/1118_03169.HtM
BbS.na2xy0k.cn/PoSt/1118_07021.HtM
BbS.vb5kftl.cn/PoSt/1118_35500.HtM
BbS.cjn8dgi.cn/PoSt/1118_55419.HtM
BbS.bhkgwzx.cn/PoSt/1118_77222.HtM
BbS.rasyi45.cn/PoSt/1118_40900.HtM
BbS.by00ez4.cn/PoSt/1118_37648.HtM
BbS.azlqul5.cn/PoSt/1118_11859.HtM
BbS.z5tiiyy.cn/PoSt/1118_90260.HtM
BbS.n9trnzh.cn/PoSt/1118_62521.HtM
BbS.38zp1cm.cn/PoSt/1118_68146.HtM
BbS.na2xy0k.cn/PoSt/1118_31363.HtM
BbS.vb5kftl.cn/PoSt/1118_38681.HtM
BbS.cjn8dgi.cn/PoSt/1118_71651.HtM
BbS.bhkgwzx.cn/PoSt/1118_56266.HtM
BbS.l718213.cn/PoSt/1118_76575.HtM
BbS.epfsrpr.cn/PoSt/1118_76972.HtM
BbS.oduz1qq.cn/PoSt/1118_45901.HtM
BbS.ddtirdr.cn/PoSt/1118_07782.HtM
BbS.lmq3hz3.cn/PoSt/1118_69345.HtM
BbS.f7c4rbn.cn/PoSt/1118_12542.HtM
BbS.c7jt2qk.cn/PoSt/1118_11716.HtM
BbS.41gi32y.cn/PoSt/1118_40553.HtM
BbS.xk7ehlo.cn/PoSt/1118_18905.HtM
BbS.kq762s8.cn/PoSt/1118_33956.HtM
BbS.l718213.cn/PoSt/1118_46747.HtM
BbS.epfsrpr.cn/PoSt/1118_36572.HtM
BbS.oduz1qq.cn/PoSt/1118_78843.HtM
BbS.ddtirdr.cn/PoSt/1118_29709.HtM
BbS.lmq3hz3.cn/PoSt/1118_92419.HtM
BbS.f7c4rbn.cn/PoSt/1118_74738.HtM
BbS.c7jt2qk.cn/PoSt/1118_25708.HtM
BbS.41gi32y.cn/PoSt/1118_47655.HtM
BbS.xk7ehlo.cn/PoSt/1118_71516.HtM
BbS.kq762s8.cn/PoSt/1118_35833.HtM
BbS.l718213.cn/PoSt/1118_34632.HtM
BbS.epfsrpr.cn/PoSt/1118_83859.HtM
BbS.oduz1qq.cn/PoSt/1118_69403.HtM
BbS.ddtirdr.cn/PoSt/1118_83844.HtM
BbS.lmq3hz3.cn/PoSt/1118_76641.HtM
BbS.f7c4rbn.cn/PoSt/1118_18984.HtM
BbS.c7jt2qk.cn/PoSt/1118_20607.HtM
BbS.41gi32y.cn/PoSt/1118_80898.HtM
BbS.xk7ehlo.cn/PoSt/1118_29387.HtM
BbS.kq762s8.cn/PoSt/1118_08148.HtM
BbS.l718213.cn/PoSt/1118_75732.HtM
BbS.epfsrpr.cn/PoSt/1118_87415.HtM
BbS.oduz1qq.cn/PoSt/1118_57533.HtM
BbS.ddtirdr.cn/PoSt/1118_47368.HtM
BbS.lmq3hz3.cn/PoSt/1118_32119.HtM
BbS.f7c4rbn.cn/PoSt/1118_95661.HtM
BbS.c7jt2qk.cn/PoSt/1118_38416.HtM
BbS.41gi32y.cn/PoSt/1118_28348.HtM
BbS.xk7ehlo.cn/PoSt/1118_72894.HtM
BbS.kq762s8.cn/PoSt/1118_72739.HtM
BbS.l718213.cn/PoSt/1118_42117.HtM
BbS.epfsrpr.cn/PoSt/1118_91418.HtM
BbS.oduz1qq.cn/PoSt/1118_79382.HtM
BbS.ddtirdr.cn/PoSt/1118_37447.HtM
BbS.lmq3hz3.cn/PoSt/1118_64596.HtM
BbS.f7c4rbn.cn/PoSt/1118_47359.HtM
BbS.c7jt2qk.cn/PoSt/1118_71352.HtM
BbS.41gi32y.cn/PoSt/1118_45878.HtM
BbS.xk7ehlo.cn/PoSt/1118_01078.HtM
BbS.kq762s8.cn/PoSt/1118_94488.HtM
BbS.l718213.cn/PoSt/1118_05292.HtM
BbS.epfsrpr.cn/PoSt/1118_85236.HtM
BbS.oduz1qq.cn/PoSt/1118_56228.HtM
BbS.ddtirdr.cn/PoSt/1118_10063.HtM
BbS.lmq3hz3.cn/PoSt/1118_16992.HtM
BbS.f7c4rbn.cn/PoSt/1118_40583.HtM
BbS.c7jt2qk.cn/PoSt/1118_09714.HtM
BbS.41gi32y.cn/PoSt/1118_10041.HtM
BbS.xk7ehlo.cn/PoSt/1118_74710.HtM
BbS.kq762s8.cn/PoSt/1118_46159.HtM
BbS.l718213.cn/PoSt/1118_07596.HtM
BbS.epfsrpr.cn/PoSt/1118_72800.HtM
BbS.oduz1qq.cn/PoSt/1118_46078.HtM
BbS.ddtirdr.cn/PoSt/1118_75708.HtM
BbS.lmq3hz3.cn/PoSt/1118_15390.HtM
BbS.f7c4rbn.cn/PoSt/1118_89008.HtM
BbS.c7jt2qk.cn/PoSt/1118_54597.HtM
BbS.41gi32y.cn/PoSt/1118_03033.HtM
BbS.xk7ehlo.cn/PoSt/1118_85233.HtM
BbS.kq762s8.cn/PoSt/1118_82028.HtM
BbS.l718213.cn/PoSt/1118_15939.HtM
BbS.epfsrpr.cn/PoSt/1118_25712.HtM
BbS.oduz1qq.cn/PoSt/1118_60693.HtM
BbS.ddtirdr.cn/PoSt/1118_19654.HtM
BbS.lmq3hz3.cn/PoSt/1118_14853.HtM
BbS.f7c4rbn.cn/PoSt/1118_13399.HtM
BbS.c7jt2qk.cn/PoSt/1118_79278.HtM
BbS.41gi32y.cn/PoSt/1118_82193.HtM
BbS.xk7ehlo.cn/PoSt/1118_19920.HtM
BbS.kq762s8.cn/PoSt/1118_36536.HtM
BbS.l718213.cn/PoSt/1118_72931.HtM
BbS.epfsrpr.cn/PoSt/1118_95034.HtM
BbS.oduz1qq.cn/PoSt/1118_76802.HtM
BbS.ddtirdr.cn/PoSt/1118_65608.HtM
BbS.lmq3hz3.cn/PoSt/1118_91495.HtM
BbS.f7c4rbn.cn/PoSt/1118_97804.HtM
BbS.c7jt2qk.cn/PoSt/1118_22200.HtM
BbS.41gi32y.cn/PoSt/1118_13489.HtM
BbS.xk7ehlo.cn/PoSt/1118_06426.HtM
BbS.kq762s8.cn/PoSt/1118_02860.HtM
BbS.l718213.cn/PoSt/1118_46136.HtM
BbS.epfsrpr.cn/PoSt/1118_62996.HtM
BbS.oduz1qq.cn/PoSt/1118_08819.HtM
BbS.ddtirdr.cn/PoSt/1118_90072.HtM
BbS.lmq3hz3.cn/PoSt/1118_33256.HtM
BbS.f7c4rbn.cn/PoSt/1118_79468.HtM
BbS.c7jt2qk.cn/PoSt/1118_29864.HtM
BbS.41gi32y.cn/PoSt/1118_46301.HtM
BbS.xk7ehlo.cn/PoSt/1118_25723.HtM
BbS.kq762s8.cn/PoSt/1118_75784.HtM Uni-Grid二次进入样式问题深度解析与解决方案
一、uni-grid组件概述
uni-grid是uni-app框架中用于实现网格布局的UI组件,特别适用于展示多个项目或产品的场景。它可以将子元素按照行和列的网格方式进行自动排列,保持布局的整齐和一致性。uni-grid组件提供灵活的布局选项,包括网格大小的设定、行列的对齐方式、间距调整等,使开发者能够在设计UI时保持美观性
1
2
。
主要应用场景:
电商分类商品列表展示
功能入口按钮布局
新闻资讯卡片展示
多项目对比展示
二、二次进入样式问题表现
uni-grid在二次进入页面时常见的样式问题主要包括:
少一列现象:第二次进入页面时,网格布局的最后一列可能消失或显示不全
7
样式闪烁:页面切换时出现短暂的布局错乱或闪烁现象
字节小程序嵌套问题:在字节跳动小程序中,由于自定义组件多一层嵌套,可能导致布局失效
8
边框显示异常:二次进入时边框可能错位或消失
间距变化:网格项之间的间距在二次进入时可能不一致
三、问题原因分析
- 布局计算机制
uni-grid在首次渲染时会根据当前容器尺寸计算布局,但二次进入时可能由于以下原因导致计算不准确:
容器尺寸变化未被正确检测
缓存了错误的布局参数
响应式更新机制延迟
-
平台差异
不同平台对CSS Grid布局的支持程度不同,特别是小程序环境存在额外的渲染层,可能导致样式表现不一致
8
。 -
组件内部实现
uni-grid组件在某些版本中存在以下问题:
列数计算逻辑缺陷
状态管理不完善
样式重置不彻底
四、解决方案与最佳实践
- 基础解决方案
方案一:去除边框
html
Copy Code
<column="4" :highlight="true" :show-border="false">
<!-- 网格项内容 -->
</uni-grid>`` 通过设置show-border="false"`可以避免边框相关的问题:ml-citation{ref="7" data="citationList"}。
方案二:固定外层容器宽度
<view style="width: 100%;">
<uni-grid :column="4">
<!-- 网格项内容 -->
</uni-grid>
</view>
2. 字节小程序特殊处理
对于字节小程序中的嵌套问题,可以使用以下方案:
方案一:使用customStyle属性
BbS.rasyi45.cn/PoSt/1118_19299.HtM
BbS.by00ez4.cn/PoSt/1118_37172.HtM
BbS.azlqul5.cn/PoSt/1118_18151.HtM
BbS.z5tiiyy.cn/PoSt/1118_83137.HtM
BbS.n9trnzh.cn/PoSt/1118_20556.HtM
BbS.38zp1cm.cn/PoSt/1118_67206.HtM
BbS.na2xy0k.cn/PoSt/1118_48017.HtM
BbS.vb5kftl.cn/PoSt/1118_70297.HtM
BbS.cjn8dgi.cn/PoSt/1118_41500.HtM
BbS.bhkgwzx.cn/PoSt/1118_03535.HtM
BbS.rasyi45.cn/PoSt/1118_69627.HtM
BbS.by00ez4.cn/PoSt/1118_51140.HtM
BbS.azlqul5.cn/PoSt/1118_24675.HtM
BbS.z5tiiyy.cn/PoSt/1118_48794.HtM
BbS.n9trnzh.cn/PoSt/1118_05781.HtM
BbS.38zp1cm.cn/PoSt/1118_78901.HtM
BbS.na2xy0k.cn/PoSt/1118_14040.HtM
BbS.vb5kftl.cn/PoSt/1118_77932.HtM
BbS.cjn8dgi.cn/PoSt/1118_08901.HtM
BbS.bhkgwzx.cn/PoSt/1118_11627.HtM
BbS.rasyi45.cn/PoSt/1118_25034.HtM
BbS.by00ez4.cn/PoSt/1118_40190.HtM
BbS.azlqul5.cn/PoSt/1118_52596.HtM
BbS.z5tiiyy.cn/PoSt/1118_95405.HtM
BbS.n9trnzh.cn/PoSt/1118_58926.HtM
BbS.38zp1cm.cn/PoSt/1118_55895.HtM
BbS.na2xy0k.cn/PoSt/1118_60516.HtM
BbS.vb5kftl.cn/PoSt/1118_83011.HtM
BbS.cjn8dgi.cn/PoSt/1118_65087.HtM
BbS.bhkgwzx.cn/PoSt/1118_11916.HtM
BbS.rasyi45.cn/PoSt/1118_50730.HtM
BbS.by00ez4.cn/PoSt/1118_87660.HtM
BbS.azlqul5.cn/PoSt/1118_98032.HtM
BbS.z5tiiyy.cn/PoSt/1118_57044.HtM
BbS.n9trnzh.cn/PoSt/1118_11285.HtM
BbS.38zp1cm.cn/PoSt/1118_65869.HtM
BbS.na2xy0k.cn/PoSt/1118_77049.HtM
BbS.vb5kftl.cn/PoSt/1118_28621.HtM
BbS.cjn8dgi.cn/PoSt/1118_07305.HtM
BbS.bhkgwzx.cn/PoSt/1118_50869.HtM
BbS.rasyi45.cn/PoSt/1118_63530.HtM
BbS.by00ez4.cn/PoSt/1118_55851.HtM
BbS.azlqul5.cn/PoSt/1118_33005.HtM
BbS.z5tiiyy.cn/PoSt/1118_64993.HtM
BbS.n9trnzh.cn/PoSt/1118_35153.HtM
BbS.38zp1cm.cn/PoSt/1118_18891.HtM
BbS.na2xy0k.cn/PoSt/1118_17872.HtM
BbS.vb5kftl.cn/PoSt/1118_94456.HtM
BbS.cjn8dgi.cn/PoSt/1118_91569.HtM
BbS.bhkgwzx.cn/PoSt/1118_83731.HtM
BbS.rasyi45.cn/PoSt/1118_08124.HtM
BbS.by00ez4.cn/PoSt/1118_96290.HtM
BbS.azlqul5.cn/PoSt/1118_95198.HtM
BbS.z5tiiyy.cn/PoSt/1118_45924.HtM
BbS.n9trnzh.cn/PoSt/1118_42449.HtM
BbS.38zp1cm.cn/PoSt/1118_35483.HtM
BbS.na2xy0k.cn/PoSt/1118_88432.HtM
BbS.vb5kftl.cn/PoSt/1118_73893.HtM
BbS.cjn8dgi.cn/PoSt/1118_49010.HtM
BbS.bhkgwzx.cn/PoSt/1118_57819.HtM
BbS.rasyi45.cn/PoSt/1118_97562.HtM
BbS.by00ez4.cn/PoSt/1118_28059.HtM
BbS.azlqul5.cn/PoSt/1118_34118.HtM
BbS.z5tiiyy.cn/PoSt/1118_36384.HtM
BbS.n9trnzh.cn/PoSt/1118_90347.HtM
BbS.38zp1cm.cn/PoSt/1118_34379.HtM
BbS.na2xy0k.cn/PoSt/1118_41241.HtM
BbS.vb5kftl.cn/PoSt/1118_42674.HtM
BbS.cjn8dgi.cn/PoSt/1118_62028.HtM
BbS.bhkgwzx.cn/PoSt/1118_53898.HtM
BbS.rasyi45.cn/PoSt/1118_98630.HtM
BbS.by00ez4.cn/PoSt/1118_90659.HtM
BbS.azlqul5.cn/PoSt/1118_02696.HtM
BbS.z5tiiyy.cn/PoSt/1118_41148.HtM
BbS.n9trnzh.cn/PoSt/1118_40116.HtM
BbS.38zp1cm.cn/PoSt/1118_06465.HtM
BbS.na2xy0k.cn/PoSt/1118_59674.HtM
BbS.vb5kftl.cn/PoSt/1118_48963.HtM
BbS.cjn8dgi.cn/PoSt/1118_98155.HtM
BbS.bhkgwzx.cn/PoSt/1118_51029.HtM
BbS.rasyi45.cn/PoSt/1118_69314.HtM
BbS.by00ez4.cn/PoSt/1118_49963.HtM
BbS.azlqul5.cn/PoSt/1118_89278.HtM
BbS.z5tiiyy.cn/PoSt/1118_36703.HtM
BbS.n9trnzh.cn/PoSt/1118_88376.HtM
BbS.38zp1cm.cn/PoSt/1118_03169.HtM
BbS.na2xy0k.cn/PoSt/1118_07021.HtM
BbS.vb5kftl.cn/PoSt/1118_35500.HtM
BbS.cjn8dgi.cn/PoSt/1118_55419.HtM
BbS.bhkgwzx.cn/PoSt/1118_77222.HtM
BbS.rasyi45.cn/PoSt/1118_40900.HtM
BbS.by00ez4.cn/PoSt/1118_37648.HtM
BbS.azlqul5.cn/PoSt/1118_11859.HtM
BbS.z5tiiyy.cn/PoSt/1118_90260.HtM
BbS.n9trnzh.cn/PoSt/1118_62521.HtM
BbS.38zp1cm.cn/PoSt/1118_68146.HtM
BbS.na2xy0k.cn/PoSt/1118_31363.HtM
BbS.vb5kftl.cn/PoSt/1118_38681.HtM
BbS.cjn8dgi.cn/PoSt/1118_71651.HtM
BbS.bhkgwzx.cn/PoSt/1118_56266.HtM
BbS.l718213.cn/PoSt/1118_76575.HtM
BbS.epfsrpr.cn/PoSt/1118_76972.HtM
BbS.oduz1qq.cn/PoSt/1118_45901.HtM
BbS.ddtirdr.cn/PoSt/1118_07782.HtM
BbS.lmq3hz3.cn/PoSt/1118_69345.HtM
BbS.f7c4rbn.cn/PoSt/1118_12542.HtM
BbS.c7jt2qk.cn/PoSt/1118_11716.HtM
BbS.41gi32y.cn/PoSt/1118_40553.HtM
BbS.xk7ehlo.cn/PoSt/1118_18905.HtM
BbS.kq762s8.cn/PoSt/1118_33956.HtM
BbS.l718213.cn/PoSt/1118_46747.HtM
BbS.epfsrpr.cn/PoSt/1118_36572.HtM
BbS.oduz1qq.cn/PoSt/1118_78843.HtM
BbS.ddtirdr.cn/PoSt/1118_29709.HtM
BbS.lmq3hz3.cn/PoSt/1118_92419.HtM
BbS.f7c4rbn.cn/PoSt/1118_74738.HtM
BbS.c7jt2qk.cn/PoSt/1118_25708.HtM
BbS.41gi32y.cn/PoSt/1118_47655.HtM
BbS.xk7ehlo.cn/PoSt/1118_71516.HtM
BbS.kq762s8.cn/PoSt/1118_35833.HtM
BbS.l718213.cn/PoSt/1118_34632.HtM
BbS.epfsrpr.cn/PoSt/1118_83859.HtM
BbS.oduz1qq.cn/PoSt/1118_69403.HtM
BbS.ddtirdr.cn/PoSt/1118_83844.HtM
BbS.lmq3hz3.cn/PoSt/1118_76641.HtM
BbS.f7c4rbn.cn/PoSt/1118_18984.HtM
BbS.c7jt2qk.cn/PoSt/1118_20607.HtM
BbS.41gi32y.cn/PoSt/1118_80898.HtM
BbS.xk7ehlo.cn/PoSt/1118_29387.HtM
BbS.kq762s8.cn/PoSt/1118_08148.HtM
BbS.l718213.cn/PoSt/1118_75732.HtM
BbS.epfsrpr.cn/PoSt/1118_87415.HtM
BbS.oduz1qq.cn/PoSt/1118_57533.HtM
BbS.ddtirdr.cn/PoSt/1118_47368.HtM
BbS.lmq3hz3.cn/PoSt/1118_32119.HtM
BbS.f7c4rbn.cn/PoSt/1118_95661.HtM
BbS.c7jt2qk.cn/PoSt/1118_38416.HtM
BbS.41gi32y.cn/PoSt/1118_28348.HtM
BbS.xk7ehlo.cn/PoSt/1118_72894.HtM
BbS.kq762s8.cn/PoSt/1118_72739.HtM
BbS.l718213.cn/PoSt/1118_42117.HtM
BbS.epfsrpr.cn/PoSt/1118_91418.HtM
BbS.oduz1qq.cn/PoSt/1118_79382.HtM
BbS.ddtirdr.cn/PoSt/1118_37447.HtM
BbS.lmq3hz3.cn/PoSt/1118_64596.HtM
BbS.f7c4rbn.cn/PoSt/1118_47359.HtM
BbS.c7jt2qk.cn/PoSt/1118_71352.HtM
BbS.41gi32y.cn/PoSt/1118_45878.HtM
BbS.xk7ehlo.cn/PoSt/1118_01078.HtM
BbS.kq762s8.cn/PoSt/1118_94488.HtM
BbS.l718213.cn/PoSt/1118_05292.HtM
BbS.epfsrpr.cn/PoSt/1118_85236.HtM
BbS.oduz1qq.cn/PoSt/1118_56228.HtM
BbS.ddtirdr.cn/PoSt/1118_10063.HtM
BbS.lmq3hz3.cn/PoSt/1118_16992.HtM
BbS.f7c4rbn.cn/PoSt/1118_40583.HtM
BbS.c7jt2qk.cn/PoSt/1118_09714.HtM
BbS.41gi32y.cn/PoSt/1118_10041.HtM
BbS.xk7ehlo.cn/PoSt/1118_74710.HtM
BbS.kq762s8.cn/PoSt/1118_46159.HtM
BbS.l718213.cn/PoSt/1118_07596.HtM
BbS.epfsrpr.cn/PoSt/1118_72800.HtM
BbS.oduz1qq.cn/PoSt/1118_46078.HtM
BbS.ddtirdr.cn/PoSt/1118_75708.HtM
BbS.lmq3hz3.cn/PoSt/1118_15390.HtM
BbS.f7c4rbn.cn/PoSt/1118_89008.HtM
BbS.c7jt2qk.cn/PoSt/1118_54597.HtM
BbS.41gi32y.cn/PoSt/1118_03033.HtM
BbS.xk7ehlo.cn/PoSt/1118_85233.HtM
BbS.kq762s8.cn/PoSt/1118_82028.HtM
BbS.l718213.cn/PoSt/1118_15939.HtM
BbS.epfsrpr.cn/PoSt/1118_25712.HtM
BbS.oduz1qq.cn/PoSt/1118_60693.HtM
BbS.ddtirdr.cn/PoSt/1118_19654.HtM
BbS.lmq3hz3.cn/PoSt/1118_14853.HtM
BbS.f7c4rbn.cn/PoSt/1118_13399.HtM
BbS.c7jt2qk.cn/PoSt/1118_79278.HtM
BbS.41gi32y.cn/PoSt/1118_82193.HtM
BbS.xk7ehlo.cn/PoSt/1118_19920.HtM
BbS.kq762s8.cn/PoSt/1118_36536.HtM
BbS.l718213.cn/PoSt/1118_72931.HtM
BbS.epfsrpr.cn/PoSt/1118_95034.HtM
BbS.oduz1qq.cn/PoSt/1118_76802.HtM
BbS.ddtirdr.cn/PoSt/1118_65608.HtM
BbS.lmq3hz3.cn/PoSt/1118_91495.HtM
BbS.f7c4rbn.cn/PoSt/1118_97804.HtM
BbS.c7jt2qk.cn/PoSt/1118_22200.HtM
BbS.41gi32y.cn/PoSt/1118_13489.HtM
BbS.xk7ehlo.cn/PoSt/1118_06426.HtM
BbS.kq762s8.cn/PoSt/1118_02860.HtM
BbS.l718213.cn/PoSt/1118_46136.HtM
BbS.epfsrpr.cn/PoSt/1118_62996.HtM
BbS.oduz1qq.cn/PoSt/1118_08819.HtM
BbS.ddtirdr.cn/PoSt/1118_90072.HtM
BbS.lmq3hz3.cn/PoSt/1118_33256.HtM
BbS.f7c4rbn.cn/PoSt/1118_79468.HtM
BbS.c7jt2qk.cn/PoSt/1118_29864.HtM
BbS.41gi32y.cn/PoSt/1118_46301.HtM
BbS.xk7ehlo.cn/PoSt/1118_25723.HtM
BbS.kq762s8.cn/PoSt/1118_75784.HtM 收起阅读 »
自定义通知铃声设置时效全攻略:从基础操作到智能场景应用
自定义通知铃声设置时效全攻略:从基础操作到智能场景应用
在个性化手机使用体验中,自定义通知铃声不仅能提升辨识度,还能通过时效设置实现不同场景下的智能切换。本文将全面解析Android和iOS系统下自定义通知铃声的设置方法、时效功能实现技巧以及常见问题解决方案,助您打造专属的听觉标识系统。
一、主流系统自定义铃声设置方法
- Android系统设置指南
华为、小米等Android设备提供多层级铃声定制方案:
基础设置路径:
进入"设置"→"声音和振动"→选择"通知铃声"
系统内置多款风格铃声,支持试听预览
点击"从存储设备选择"可导入本地MP3/WAV格式音频文件
2
进阶个性化设置:
联系人专属铃声:在通讯录中编辑联系人→"铃声"选项→分配独立铃声
应用分类铃声:部分系统支持为微信、邮件等不同应用设置独立提示音
视频铃声功能:华为等品牌支持将短视频设为来电显示
2
小米设备特殊设置:
日历应用内可单独设置日程提醒铃声
通过"更多设置→日程提醒设置→铃声"路径完成配置
1
- iOS系统设置方案
苹果设备通过系统级整合实现深度定制:
标准设置流程:
前往"设置"→"声音与触感"→选择"通知铃声"
系统铃声自动播放预览,点击即可应用
4
自定义铃声制作:
使用库乐队(GarageBand)应用裁剪音频(≤40秒)
导出时选择"电话铃声"格式(.m4r)
通过iTunes同步至设备铃声库
5
情景化铃声分配:
为联系人设置专属铃声:通讯录→编辑→"电话铃声"
微信等第三方应用支持独立提示音设置
6
二、时效设置与智能场景应用
- Android时效功能实现方案
第三方工具辅助:
使用Tasker等自动化工具设置定时铃声更换
可配置工作日/节假日自动切换不同铃声
闹钟功能变通应用:
通过AlarmManager设置定时任务
触发时自动切换预设铃声(需系统权限)
7
9
情景模式联动:
部分厂商系统支持"驾驶模式"等自动切换
连接蓝牙设备时可触发特定铃声配置
- iOS时效管理方案
专注模式智能切换:
创建"工作/睡眠/健身"等专注模式
为不同模式分配专属通知铃声
10
12
时间自动化设置:
通过快捷指令创建时间触发规则
例如工作日8:00-18:00使用商务铃声,其余时间使用休闲铃声
地理位置触发:
到达公司/家庭等特定位置时自动切换铃声
需配合"到达时"自动化条件设置
三、专业使用技巧与注意事项
- 音频优化建议
格式与时长规范:
Android:推荐MP3/WAV格式,时长≤30秒
iOS:必须为.m4r格式,来电铃声≤40秒
5
音量平衡技巧:
避免过大的动态范围导致部分片段听不清
可使用Audacity等工具进行标准化处理
多设备同步方案:
华为等品牌支持云同步铃声库
iOS通过iCloud实现铃声跨设备共享
- 常见问题排查
铃声不响的解决方法:
检查静音开关和勿扰模式状态
确认"铃声与提醒"音量已调高
验证铃声文件是否损坏
17
自定义铃声无法识别:
Android需将文件放入Ringtones文件夹
iOS需通过库乐队正确导出.m4r格式
15
微信专属铃声设置:
在微信"我→设置→新消息通知"中配置
支持为特定好友设置独立提示音
18
四、创意应用场景示例
时间感知铃声:
早晨使用轻快铃声唤醒
午后切换为柔和提示音
晚间启用低音量夜间模式
工作生活分离方案:
工作日:简洁专业的提示音
周末:个性化音乐片段
假期:特殊节日音效
健康管理应用:
久坐提醒使用渐进式铃声
服药时间设置独特提示音
运动时段匹配节奏感强的铃声
通过合理规划通知铃声的时效设置,不仅能提升手机使用的个性化体验,还能在不同场景下实现高效的信息管理。建议定期更新铃声库,避免听觉疲劳,同时注意遵守版权法规,使用合法授权的音频素材。
自定义通知铃声设置时效全攻略:从基础操作到智能场景应用
在个性化手机使用体验中,自定义通知铃声不仅能提升辨识度,还能通过时效设置实现不同场景下的智能切换。本文将全面解析Android和iOS系统下自定义通知铃声的设置方法、时效功能实现技巧以及常见问题解决方案,助您打造专属的听觉标识系统。
一、主流系统自定义铃声设置方法
- Android系统设置指南
华为、小米等Android设备提供多层级铃声定制方案:
基础设置路径:
进入"设置"→"声音和振动"→选择"通知铃声"
系统内置多款风格铃声,支持试听预览
点击"从存储设备选择"可导入本地MP3/WAV格式音频文件
2
进阶个性化设置:
联系人专属铃声:在通讯录中编辑联系人→"铃声"选项→分配独立铃声
应用分类铃声:部分系统支持为微信、邮件等不同应用设置独立提示音
视频铃声功能:华为等品牌支持将短视频设为来电显示
2
小米设备特殊设置:
日历应用内可单独设置日程提醒铃声
通过"更多设置→日程提醒设置→铃声"路径完成配置
1
- iOS系统设置方案
苹果设备通过系统级整合实现深度定制:
标准设置流程:
前往"设置"→"声音与触感"→选择"通知铃声"
系统铃声自动播放预览,点击即可应用
4
自定义铃声制作:
使用库乐队(GarageBand)应用裁剪音频(≤40秒)
导出时选择"电话铃声"格式(.m4r)
通过iTunes同步至设备铃声库
5
情景化铃声分配:
为联系人设置专属铃声:通讯录→编辑→"电话铃声"
微信等第三方应用支持独立提示音设置
6
二、时效设置与智能场景应用
- Android时效功能实现方案
第三方工具辅助:
使用Tasker等自动化工具设置定时铃声更换
可配置工作日/节假日自动切换不同铃声
闹钟功能变通应用:
通过AlarmManager设置定时任务
触发时自动切换预设铃声(需系统权限)
7
9
情景模式联动:
部分厂商系统支持"驾驶模式"等自动切换
连接蓝牙设备时可触发特定铃声配置
- iOS时效管理方案
专注模式智能切换:
创建"工作/睡眠/健身"等专注模式
为不同模式分配专属通知铃声
10
12
时间自动化设置:
通过快捷指令创建时间触发规则
例如工作日8:00-18:00使用商务铃声,其余时间使用休闲铃声
地理位置触发:
到达公司/家庭等特定位置时自动切换铃声
需配合"到达时"自动化条件设置
三、专业使用技巧与注意事项
- 音频优化建议
格式与时长规范:
Android:推荐MP3/WAV格式,时长≤30秒
iOS:必须为.m4r格式,来电铃声≤40秒
5
音量平衡技巧:
避免过大的动态范围导致部分片段听不清
可使用Audacity等工具进行标准化处理
多设备同步方案:
华为等品牌支持云同步铃声库
iOS通过iCloud实现铃声跨设备共享
- 常见问题排查
铃声不响的解决方法:
检查静音开关和勿扰模式状态
确认"铃声与提醒"音量已调高
验证铃声文件是否损坏
17
自定义铃声无法识别:
Android需将文件放入Ringtones文件夹
iOS需通过库乐队正确导出.m4r格式
15
微信专属铃声设置:
在微信"我→设置→新消息通知"中配置
支持为特定好友设置独立提示音
18
四、创意应用场景示例
时间感知铃声:
早晨使用轻快铃声唤醒
午后切换为柔和提示音
晚间启用低音量夜间模式
工作生活分离方案:
工作日:简洁专业的提示音
周末:个性化音乐片段
假期:特殊节日音效
健康管理应用:
久坐提醒使用渐进式铃声
服药时间设置独特提示音
运动时段匹配节奏感强的铃声
通过合理规划通知铃声的时效设置,不仅能提升手机使用的个性化体验,还能在不同场景下实现高效的信息管理。建议定期更新铃声库,避免听觉疲劳,同时注意遵守版权法规,使用合法授权的音频素材。
【急招】智能家居App开发大神!uni-app开发平台,杭州本地/滨江区办公,远程兼职亦可
「万物互联时代,让智能走进千万家」—— 我们是一家深耕智能家居领域的创新团队,正全力打造一款体验顶尖的智能生活控制终端App。现急需技术大牛加入,共筑智慧生活新生态!无论你是杭州本地想就近办公,还是偏爱远程项目制兼职,只要你有实力,我们都虚位以待!
🔥 我们要找这样的你(核心岗位职责)
1.主导智能家居App(Android/iOS双端)的全流程技术落地,从需求分析、架构设计到核心模块编码与迭代优化,把控技术方向。
2.攻克设备核心交互难题,实现App与智能设备的快速配网、稳定连接、精准控制及实时状态同步,打造丝滑控制体验。
3.负责音视频核心功能开发,包括直播对讲、录像回放、云存储播放等,持续优化流畅度与清晰度,提升用户视听体验。
4.牵头移动端技术选型与架构升级,推进组件化、模块化开发,让代码更具可维护性,大幅提升团队开发效率。
5.死磕App性能与稳定性,监控并优化启动速度、内存占用、功耗及网络流量,精准解决Crash和ANR问题,保障千万用户稳定使用。
6.紧跟移动平台技术前沿,将合适的新技术、新框架融入产品,让我们的App始终保持行业竞争力。
🎯 我们希望你具备(任职要求)
1.计算机相关专业本科及以上学历,3年以上Android或iOS开发经验,有智能家居、物联网或音视频类App开发经验者优先,加分项拉满!
2.满足以下任一技术栈深耕要求,多栈掌握者优先:
精通uniapp开发,能高效实现双端适配;
3.Android方向:精通Java/Kotlin,熟悉Android SDK/NDK,对性能优化、内存管理有深刻理解;
4.iOS方向:精通Swift/Objective-C,熟悉Cocoa Touch框架,深入理解内存管理机制和运行时;
5.熟悉TCP/IP、HTTP/HTTPS、WebSocket等协议,具备扎实的移动端网络编程能力;
6.有音视频开发经验者狂喜!熟悉FFmpeg、MediaCodec、AudioTrack(Android)或AVFoundation(iOS)等技术者优先;
7.掌握Flutter、React Native等跨端技术,或理解设计模式、具备优秀架构设计能力者优先;
8.熟练使用Git、Maven/Cocoapods等开发工具,会用性能分析工具排查问题。
9.对用户体验有极致追求,学习能力拉满,团队协作意识强,能独立啃下复杂技术难题。
📍 工作模式&地点说明
•地点要求:优先杭州本地居民,可接受在滨江区核心商圈办公(交通便利,配套齐全);
•灵活选项:支持远程项目制兼职,只要能高效交付成果,工作地点由你定!
✨ 我们能提供
•极具竞争力的薪酬回报:全职薪资对标行业Top30%,兼职按项目难度及交付质量核算,酬劳丰厚不拖欠;
•技术成长沃土:接触智能家居+音视频双赛道核心技术,团队定期技术分享,和大牛并肩成长;
•灵活工作氛围:扁平化组织架构,注重效率与成果,远程兼职也能享受完整项目协作支持;
•额外福利:全职员工享五险一金、节日福利、定期团建,兼职伙伴享项目奖金!
📩 如何加入我们?
请将你的个人简历(附项目经历及技术栈说明)发送至邮箱:jessixu32@163.com,邮件主题注明「智能家居App开发+姓名+工作模式(全职/兼职)」。
我们会在3个工作日内筛选简历并联系面试,合则约聊!杭州本地候选人可安排线下办公场地参观,远程候选人支持线上面试。
期待热爱技术、向往智能生活的你,和我们一起用代码点亮千万家庭的智慧未来!
「万物互联时代,让智能走进千万家」—— 我们是一家深耕智能家居领域的创新团队,正全力打造一款体验顶尖的智能生活控制终端App。现急需技术大牛加入,共筑智慧生活新生态!无论你是杭州本地想就近办公,还是偏爱远程项目制兼职,只要你有实力,我们都虚位以待!
🔥 我们要找这样的你(核心岗位职责)
1.主导智能家居App(Android/iOS双端)的全流程技术落地,从需求分析、架构设计到核心模块编码与迭代优化,把控技术方向。
2.攻克设备核心交互难题,实现App与智能设备的快速配网、稳定连接、精准控制及实时状态同步,打造丝滑控制体验。
3.负责音视频核心功能开发,包括直播对讲、录像回放、云存储播放等,持续优化流畅度与清晰度,提升用户视听体验。
4.牵头移动端技术选型与架构升级,推进组件化、模块化开发,让代码更具可维护性,大幅提升团队开发效率。
5.死磕App性能与稳定性,监控并优化启动速度、内存占用、功耗及网络流量,精准解决Crash和ANR问题,保障千万用户稳定使用。
6.紧跟移动平台技术前沿,将合适的新技术、新框架融入产品,让我们的App始终保持行业竞争力。
🎯 我们希望你具备(任职要求)
1.计算机相关专业本科及以上学历,3年以上Android或iOS开发经验,有智能家居、物联网或音视频类App开发经验者优先,加分项拉满!
2.满足以下任一技术栈深耕要求,多栈掌握者优先:
精通uniapp开发,能高效实现双端适配;
3.Android方向:精通Java/Kotlin,熟悉Android SDK/NDK,对性能优化、内存管理有深刻理解;
4.iOS方向:精通Swift/Objective-C,熟悉Cocoa Touch框架,深入理解内存管理机制和运行时;
5.熟悉TCP/IP、HTTP/HTTPS、WebSocket等协议,具备扎实的移动端网络编程能力;
6.有音视频开发经验者狂喜!熟悉FFmpeg、MediaCodec、AudioTrack(Android)或AVFoundation(iOS)等技术者优先;
7.掌握Flutter、React Native等跨端技术,或理解设计模式、具备优秀架构设计能力者优先;
8.熟练使用Git、Maven/Cocoapods等开发工具,会用性能分析工具排查问题。
9.对用户体验有极致追求,学习能力拉满,团队协作意识强,能独立啃下复杂技术难题。
📍 工作模式&地点说明
•地点要求:优先杭州本地居民,可接受在滨江区核心商圈办公(交通便利,配套齐全);
•灵活选项:支持远程项目制兼职,只要能高效交付成果,工作地点由你定!
✨ 我们能提供
•极具竞争力的薪酬回报:全职薪资对标行业Top30%,兼职按项目难度及交付质量核算,酬劳丰厚不拖欠;
•技术成长沃土:接触智能家居+音视频双赛道核心技术,团队定期技术分享,和大牛并肩成长;
•灵活工作氛围:扁平化组织架构,注重效率与成果,远程兼职也能享受完整项目协作支持;
•额外福利:全职员工享五险一金、节日福利、定期团建,兼职伙伴享项目奖金!
📩 如何加入我们?
请将你的个人简历(附项目经历及技术栈说明)发送至邮箱:jessixu32@163.com,邮件主题注明「智能家居App开发+姓名+工作模式(全职/兼职)」。
我们会在3个工作日内筛选简历并联系面试,合则约聊!杭州本地候选人可安排线下办公场地参观,远程候选人支持线上面试。
期待热爱技术、向往智能生活的你,和我们一起用代码点亮千万家庭的智慧未来!
经验分享 鸿蒙隐私弹窗如何处理
基本背景
鸿蒙元服务不需要自己处理隐私弹窗,鸿蒙强制要求结束隐私协议托管,关联 client_id 之后会自动弹窗隐私协议,下面内容主要针对鸿蒙应用开发用户。
鸿蒙应用上架需要配置隐私协议、用户协议。这部分内容可参考 鸿蒙如何设置隐私协议弹窗
这里做技术实现说明。
内容已迁移到 鸿蒙如何设置隐私协议弹窗
补充:编写 uts 插件
如果应用需要提供不同意隐私协议也要提供基础内容浏览服务,可参考下面 uts 代码单独处理用户动态接受、拒绝隐私协议,主动唤起隐私协议相关逻辑。
编写 uts 插件,完成弹窗,这里提供代码片段。
新建 uts 插件,比如 hamrony-privacy-dialog ,编辑 uni_modules/harmony-privacy-dialog/utssdk/app-harmony/index.uts
填写下面代码,这段代码导出了三个方法,和官方的 ets 代码完全一致,检查隐私协议信息、获取签署状态、主动唤起隐私弹窗。页面中引入代码调用即可。
import { privacyManager } from '@kit.AppGalleryKit';
// import { hilog } from '@kit.PerformanceAnalysisKit';
import { BusinessError } from '@kit.BasicServicesKit';
export const getInfo = () => {
let err = ''
try {
let appPrivacyManageInfo : privacyManager.AppPrivacyMgmtInfo = privacyManager.getAppPrivacyMgmtInfo();
console.info(0, 'TAG', "Succeeded in getting AppPrivacyManageInfo type: " + appPrivacyManageInfo["type"]);
let privacyLinkInfoArray : privacyManager.AppPrivacyLink[] = appPrivacyManageInfo.privacyInfo;
console.info(0, 'TAG', "Succeeded in getting AppPrivacyManageInfo size = " + privacyLinkInfoArray.length);
for (let i = 0; i < privacyLinkInfoArray.length; i++) {
console.info(0, 'TAG', "Succeeded in getting AppPrivacyManageInfo type = " + privacyLinkInfoArray[i]["type"] + ", version = " + privacyLinkInfoArray[i]["versionCode"] + ", url = " + privacyLinkInfoArray[i]["url"]);
}
} catch (error) {
err = error.message
console.error(0, 'TAG', "GetAppPrivacyManageInfoPublic exception code: " + error.code + ", exception message: " + error.message);
}
return err
}
export const getStatus = () => {
try {
let appPrivacyResults : privacyManager.AppPrivacyResult[] = privacyManager.getAppPrivacyResult();
console.info(0, 'TAG', "Succeeded in getting AppPrivacyResult size = " + appPrivacyResults.length);
for (let i = 0; i < appPrivacyResults.length; i++) {
console.info(0, 'TAG', "Succeeded in getting AppPrivacyResult type = " + appPrivacyResults[i]["type"] + ", version = " + appPrivacyResults[i]["versionCode"] + ", result = " + appPrivacyResults[i]["result"]);
}
} catch (error) {
console.error(0, 'TAG', "GetAppPrivacyResultPublic exception code: " + error.code + ", exception message: " + error.message);
}
}
export const requestPrivacy = () => {
try {
const uiContext = UTSHarmony.getUIAbilityContext()
// const uiContext = this.getUIContext().getHostContext() as common.UIAbilityContext;
privacyManager.requestAppPrivacyConsent(uiContext).then((consentResult : privacyManager.ConsentResult) => {
let appPrivacyResults : privacyManager.AppPrivacyResult[] = consentResult["results"];
for (let i = 0; i < appPrivacyResults.length; i++) {
console.info(0, 'TAG', "GetAppPrivacyResult type = " + appPrivacyResults[i]["type"] + ", version = " + appPrivacyResults[i]["versionCode"] + ", result = " + appPrivacyResults[i]["result"] + ", signingTimeStamp = " + appPrivacyResults[i]["signingTimeStamp"]);
}
}).catch((error : BusinessError<Object>) => {
console.error(0, 'TAG', `requestAppPrivacyConsent failed, Code: ${error.code}, message: ${error.message}`);
});
} catch (error) {
console.error(0, 'TAG', "requestAppPrivacyConsent exception code: " + error.code + ", exception message: " + error.message);
}
}
4 页面中引入
import {
getInfo,
getStatus,requestPrivacy
} from '@/uni_modules/harmony-privacy-dialog' 基本背景
鸿蒙元服务不需要自己处理隐私弹窗,鸿蒙强制要求结束隐私协议托管,关联 client_id 之后会自动弹窗隐私协议,下面内容主要针对鸿蒙应用开发用户。
鸿蒙应用上架需要配置隐私协议、用户协议。这部分内容可参考 鸿蒙如何设置隐私协议弹窗
这里做技术实现说明。
内容已迁移到 鸿蒙如何设置隐私协议弹窗
补充:编写 uts 插件
如果应用需要提供不同意隐私协议也要提供基础内容浏览服务,可参考下面 uts 代码单独处理用户动态接受、拒绝隐私协议,主动唤起隐私协议相关逻辑。
编写 uts 插件,完成弹窗,这里提供代码片段。
新建 uts 插件,比如 hamrony-privacy-dialog ,编辑 uni_modules/harmony-privacy-dialog/utssdk/app-harmony/index.uts
填写下面代码,这段代码导出了三个方法,和官方的 ets 代码完全一致,检查隐私协议信息、获取签署状态、主动唤起隐私弹窗。页面中引入代码调用即可。
import { privacyManager } from '@kit.AppGalleryKit';
// import { hilog } from '@kit.PerformanceAnalysisKit';
import { BusinessError } from '@kit.BasicServicesKit';
export const getInfo = () => {
let err = ''
try {
let appPrivacyManageInfo : privacyManager.AppPrivacyMgmtInfo = privacyManager.getAppPrivacyMgmtInfo();
console.info(0, 'TAG', "Succeeded in getting AppPrivacyManageInfo type: " + appPrivacyManageInfo["type"]);
let privacyLinkInfoArray : privacyManager.AppPrivacyLink[] = appPrivacyManageInfo.privacyInfo;
console.info(0, 'TAG', "Succeeded in getting AppPrivacyManageInfo size = " + privacyLinkInfoArray.length);
for (let i = 0; i < privacyLinkInfoArray.length; i++) {
console.info(0, 'TAG', "Succeeded in getting AppPrivacyManageInfo type = " + privacyLinkInfoArray[i]["type"] + ", version = " + privacyLinkInfoArray[i]["versionCode"] + ", url = " + privacyLinkInfoArray[i]["url"]);
}
} catch (error) {
err = error.message
console.error(0, 'TAG', "GetAppPrivacyManageInfoPublic exception code: " + error.code + ", exception message: " + error.message);
}
return err
}
export const getStatus = () => {
try {
let appPrivacyResults : privacyManager.AppPrivacyResult[] = privacyManager.getAppPrivacyResult();
console.info(0, 'TAG', "Succeeded in getting AppPrivacyResult size = " + appPrivacyResults.length);
for (let i = 0; i < appPrivacyResults.length; i++) {
console.info(0, 'TAG', "Succeeded in getting AppPrivacyResult type = " + appPrivacyResults[i]["type"] + ", version = " + appPrivacyResults[i]["versionCode"] + ", result = " + appPrivacyResults[i]["result"]);
}
} catch (error) {
console.error(0, 'TAG', "GetAppPrivacyResultPublic exception code: " + error.code + ", exception message: " + error.message);
}
}
export const requestPrivacy = () => {
try {
const uiContext = UTSHarmony.getUIAbilityContext()
// const uiContext = this.getUIContext().getHostContext() as common.UIAbilityContext;
privacyManager.requestAppPrivacyConsent(uiContext).then((consentResult : privacyManager.ConsentResult) => {
let appPrivacyResults : privacyManager.AppPrivacyResult[] = consentResult["results"];
for (let i = 0; i < appPrivacyResults.length; i++) {
console.info(0, 'TAG', "GetAppPrivacyResult type = " + appPrivacyResults[i]["type"] + ", version = " + appPrivacyResults[i]["versionCode"] + ", result = " + appPrivacyResults[i]["result"] + ", signingTimeStamp = " + appPrivacyResults[i]["signingTimeStamp"]);
}
}).catch((error : BusinessError<Object>) => {
console.error(0, 'TAG', `requestAppPrivacyConsent failed, Code: ${error.code}, message: ${error.message}`);
});
} catch (error) {
console.error(0, 'TAG', "requestAppPrivacyConsent exception code: " + error.code + ", exception message: " + error.message);
}
}
4 页面中引入
import {
getInfo,
getStatus,requestPrivacy
} from '@/uni_modules/harmony-privacy-dialog' 收起阅读 »
个人开发者承接app、小程序、网页外包,全职外包接单
全职在家承接外包,多年外包经验,个人开发者,绝对实惠靠谱,有很多款线上应用(度是自己开发的,自己独立完成,可查)
可做商城类,社交类,工具类,任务平台类,mes 类,扫码收银/分账交易类 等,除了游戏和带颜色的,其他度可以开发
可承接安卓/IOS、各个端的小程序、H5网页、PC网页开发,从前端到后端,我全度会,一条龙服务
掌握技术
前端:uniapp 、uniappx、vue
后端:Golang 、php
uniapp 及 uniappx 开发的作品均有上架appstore
小程序方面也有很多
有需要开发的并能看得上我的请联系我哈
vx:wu1020yt
全职在家承接外包,多年外包经验,个人开发者,绝对实惠靠谱,有很多款线上应用(度是自己开发的,自己独立完成,可查)
可做商城类,社交类,工具类,任务平台类,mes 类,扫码收银/分账交易类 等,除了游戏和带颜色的,其他度可以开发
可承接安卓/IOS、各个端的小程序、H5网页、PC网页开发,从前端到后端,我全度会,一条龙服务
掌握技术
前端:uniapp 、uniappx、vue
后端:Golang 、php
uniapp 及 uniappx 开发的作品均有上架appstore
小程序方面也有很多
有需要开发的并能看得上我的请联系我哈
vx:wu1020yt
收起阅读 »FIRE计算器
我用它制定了一个“搞钱计划”。
比如我今年想多存五万块,
它能帮我倒推出每个月需要增加多少收入或者减少多少开支,目标特别清晰。
我用它制定了一个“搞钱计划”。
比如我今年想多存五万块,
它能帮我倒推出每个月需要增加多少收入或者减少多少开支,目标特别清晰。
https://iris.findtruman.io/web/fire_calculator?share=L
收起阅读 »APP扫码识别区是正方形怎么修改成长方形,微信小程序是长方形的
APP扫码识别区是正方形怎么修改成长方形,微信小程序是长方形的,扫码识别区太小了,很不方便
APP扫码识别区是正方形怎么修改成长方形,微信小程序是长方形的,扫码识别区太小了,很不方便
分享一下 在ios上 uni-app 通过oauth2登录遇到的一些阻碍和解决办法。
就当纪念一下抠了好几天的头。虽然实现了,也花了很多时间,但是没有什么成功了的实感,有种莫名其妙的感觉。
不论咋样,还是记录一下吧,百度之后竟然完全没有人用这个方式 在ios上登录,而ds和cursor一众ai费拉不堪,ds胡说八道的程度越来越严重了
oauth2的登录描述比较粗糙。
有一个最想知道的问题,想知道 ios中app和 webview 的 cookie传递。
过程:
1.根据文档设置 ios的schemes。注:urltypes 只能用string格式,不可用数组,否则打包 的link.info 中 没有 CFBundleURLTypes 的标签。
2.login接口后,后端会产生一个短暂的cookie会话,根据该会话证明过程中登录情况。若无法验证到该cookie会话,将直接跳回登录界面。
3.使用webview 打开 authorize 页面,如果验证成功,会通过schemes唤醒 app,接着验证获取token并跳转主页面。
其中遇到3个阻碍。
- 在login接口后的 cookie会话,没有 设置 domain 时,webview 打开 authorize页面,一直都是cookie验证会话失败,直接跳转回登录界面。在设置 domain后,第一次 登录 cookie会话验证失败,而第二次继续登录的验证都通过了。
询问了ds等ai,给出的解释是 在ios时,网络请求和Cookie存储与App本身不在同一进程,默认不共享NSHTTPCookieStorage。所以通过webview 后端会拿不到cookie从而导致失败。而安卓的cookie在uni-app底层已经同步过,所以不存在该问题。但问题是为什么设置了domain后,除了第一次失败,后续的登录都成功了?是不是底层也对ios同步过?但为什么第一次不成功?强制手动给webview注入cookie,没有一个方式成功。设置延时任务也没有用,设置多长也没有用,第一次就是不能通过。
后续与后端沟通,通过 生成token附带在 authorize的path后,后端使用token来验证会话解决该问题。
2.page.json中 设置过 // "condition": {
// //模式配置,仅开发期间生效
// "current": 0, //当前激活的模式(list 的索引项)
// "list": [{
// "name": "", //模式名称
// "path": "", //启动页面,必选
// "query": "" //启动参数,在页面的onLoad函数里面得到
// }]
// }。
从而导致 schemes唤醒后,无法获取schemes携带的数据。安卓无此问题。
3.后端schemes因为ios的安全机制是无法自动唤醒app,除非用户手动点。Universal Links 也没办法在同域名下进行唤醒。但是,实际上 传递数据已经触发,在plus.runtiem.arguments中是有数据的。所以直接搞了一个 定时任务监听这个数据,一旦有数据就可以直接后续的步骤,不需要用户手动点击。安卓可以直接通过schemes唤醒app并直接拿到数据,所以也不需要这个定时任务
就当纪念一下抠了好几天的头。虽然实现了,也花了很多时间,但是没有什么成功了的实感,有种莫名其妙的感觉。
不论咋样,还是记录一下吧,百度之后竟然完全没有人用这个方式 在ios上登录,而ds和cursor一众ai费拉不堪,ds胡说八道的程度越来越严重了
oauth2的登录描述比较粗糙。
有一个最想知道的问题,想知道 ios中app和 webview 的 cookie传递。
过程:
1.根据文档设置 ios的schemes。注:urltypes 只能用string格式,不可用数组,否则打包 的link.info 中 没有 CFBundleURLTypes 的标签。
2.login接口后,后端会产生一个短暂的cookie会话,根据该会话证明过程中登录情况。若无法验证到该cookie会话,将直接跳回登录界面。
3.使用webview 打开 authorize 页面,如果验证成功,会通过schemes唤醒 app,接着验证获取token并跳转主页面。
其中遇到3个阻碍。
- 在login接口后的 cookie会话,没有 设置 domain 时,webview 打开 authorize页面,一直都是cookie验证会话失败,直接跳转回登录界面。在设置 domain后,第一次 登录 cookie会话验证失败,而第二次继续登录的验证都通过了。
询问了ds等ai,给出的解释是 在ios时,网络请求和Cookie存储与App本身不在同一进程,默认不共享NSHTTPCookieStorage。所以通过webview 后端会拿不到cookie从而导致失败。而安卓的cookie在uni-app底层已经同步过,所以不存在该问题。但问题是为什么设置了domain后,除了第一次失败,后续的登录都成功了?是不是底层也对ios同步过?但为什么第一次不成功?强制手动给webview注入cookie,没有一个方式成功。设置延时任务也没有用,设置多长也没有用,第一次就是不能通过。
后续与后端沟通,通过 生成token附带在 authorize的path后,后端使用token来验证会话解决该问题。
2.page.json中 设置过 // "condition": {
// //模式配置,仅开发期间生效
// "current": 0, //当前激活的模式(list 的索引项)
// "list": [{
// "name": "", //模式名称
// "path": "", //启动页面,必选
// "query": "" //启动参数,在页面的onLoad函数里面得到
// }]
// }。
从而导致 schemes唤醒后,无法获取schemes携带的数据。安卓无此问题。
3.后端schemes因为ios的安全机制是无法自动唤醒app,除非用户手动点。Universal Links 也没办法在同域名下进行唤醒。但是,实际上 传递数据已经触发,在plus.runtiem.arguments中是有数据的。所以直接搞了一个 定时任务监听这个数据,一旦有数据就可以直接后续的步骤,不需要用户手动点击。安卓可以直接通过schemes唤醒app并直接拿到数据,所以也不需要这个定时任务
收起阅读 »【鸿蒙征文】重拾儿时趣味的古诗 App 的开发过程记录
一款无广告重拾儿时趣味的古诗 App 的开发过程记录
一、🌈缘起:让古诗 “活” 起来,而非躺在角落🌈
做这款 App 的初衷,藏在三个真实需求里:
一次偶然的寻找碰上鸿蒙的星光闪烁:翻找学生时代的语文诗词,想重拾那份诗词氛围时,书本早已不见踪影,此时便想在手机上寻找这类APP,市面古诗 App 要么广告扎堆,要么功能枯燥,实在感受不到当年的那种氛围;
身边朋友想重拾古诗,却缺合适的背诵工具,也没有专属交流渠道(总不能天天在朋友圈发古诗);
古诗的意境与字词之美,不该只靠 “死记硬背”—— 结合互动、朗读、释义,让大家 “懂了再背”,才是真正的文化传承。
所以核心需求很明确:做一款 “不枯燥、能互动、够纯粹” 的古诗工具。既要满足学习需求,又要兼顾趣味性,还得适配鸿蒙系统(毕竟鸿蒙用户越来越多,生态也日趋完善)。
二、💡技术选型:为啥 “锁死” UniAPP?💡
选技术栈时纠结了 3 天,最终敲定 UniAPP,全靠 “实用主义”:
排除鸿蒙原生开发:适配鸿蒙虽丝滑,但单人开发要重新学原生语法,还无法兼顾其他平台,效率太低;
排除其他跨平台框架:要么对鸿蒙适配不完善,要么插件生态薄弱,像诗词朗读、音频上传等功能得手动造轮子;
选择 UniAPP 的核心原因:
跨平台省心:一套代码可打包鸿蒙 App,后续扩展安卓、iOS 版本无需重构,对个人开发者极度友好;
- 鸿蒙适配 “自带 buff”:HBuilderX 提供现成打包模板和专属适配插件,不用手动修改大量配置;
- 生态够全:uniCloud 云开发、音频组件、数据库插件,刚好满足古诗存储、朗读上传、接龙匹配等核心需求;
- 学习成本低:有微信小程序开发基础,UniAPP 的 Vue 语法无缝衔接,1 周就能上手。
简单说:用 UniAPP 开发鸿蒙,就像 “站在巨人肩膀上”—— 不用从零学鸿蒙原生,又能享受鸿蒙系统特性,对非专业开发者太友好了!
三、⚠️踩坑实录:鸿蒙适配那些 “磨人的小妖精”⚠️
开发前以为 “跨平台 = 一路顺畅”,结果真正适配鸿蒙时,还是踩了不少坑,分享 3 个最印象深刻的:
权限申请:鸿蒙的 “规矩” 和其他平台不一样
做朗读广场时,需要调用手机麦克风录音、存储音频文件。一开始直接复用了其他平台的权限代码,结果在鸿蒙上直接报错 —— 录音功能打不开!
- 坑点:鸿蒙的 “媒体权限” 需要单独申请,而且必须配置ohos.permission.READ_MEDIA和ohos.permission.WRITE_MEDIA,还得在代码里动态弹窗说明 “为啥要要权限”(比如 “需要录音才能上传你的朗读作品”),光说 “需要权限” 会被系统拒绝;而且必须在鸿蒙的AGC后台进行同步申请该权限,因为该权限属于受限权限;而且!!!如果是使用的鸿蒙自家的隐私托管服务,必须要在隐私托管服务中同步该权限的声明
- 解决:使用uts插件配置权限;然后在AGC后台同步申请该受限权限通过率直接 100%。
// #ifdef APP-HARMONY import "@/uni_modules/harmony-permissions" // #endif
{
"module": {
"name": "uni_modules__harmony_permissions",
"type": "har",
"deviceTypes": [
"default",
"tablet",
"2in1"
],
"requestPermissions": [
{
"name": "ohos.permission.INTERNET"
},{
"name": "ohos.permission.WRITE_MEDIA",
"reason": "$string:media_desc",
"usedScene": {"when": "inuse"}
},{
"name": "ohos.permission.READ_MEDIA",
"reason": "$string:media_desc",
"usedScene": {"when": "inuse"}
}
]
}
}
服务卡片适配:桌面卡片让古诗 “触手可及”
鸿蒙的桌面卡片是个大亮点,我想做个 “每日一句” 卡片,用户不用打开 App,桌面就能看到古诗。
- 坑点:UniAPP 打包鸿蒙应用时,卡片的尺寸适配很麻烦,比如 3x2、2x2 的卡片布局会错乱,而且卡片数据刷新需要和主 App 同步;
- 解决:用 UniAPP 提供的uni-app x编译模式(专门优化鸿蒙适配),卡片布局用flex弹性盒,固定宽高比;数据同步用uniCloud实时数据库,主 App 更新 “每日一句” 后,卡片自动刷新,不用用户手动操作 —— 现在不少用户说 “每天解锁手机先看一眼古诗,感觉很治愈”。
音频播放:后台播放老是 “断档”
朗读广场的核心是 “听别人读古诗”,但一开始用户反馈 “退到后台就停了”,体验很差。
- 坑点:鸿蒙对后台音频播放有严格限制,普通的audio组件在后台会被系统暂停;
- 解决:集成了鸿蒙的AVPlayer SDK(UniAPP 可以直接调用鸿蒙原生 SDK),在manifest.json里配置 “后台音频权限”,同时用 UniAPP 的onBackground生命周期监听,退后台时自动切换到鸿蒙原生播放器,现在后台播放能稳定运行,用户还能边听古诗边刷微信~
四、📦功能落地:每个模块都是 “心头好”📦
结合古诗的核心需求,几个功能模块都是 “边踩坑边优化” 出来的,挑 3 个重点说:
-
背一背:用 “艾宾浩斯曲线” 让背诵不费脑
一开始只是简单做了 “列表 + 背诵打卡”,但用户反馈 “背了就忘”。后来用 UniAPP 的storage存储用户背诵记录,结合艾宾浩斯遗忘曲线,在对应时间点推送提醒(比如第 1 天、第 3 天、第 7 天),还加了 “遮字默写” 功能 —— 点击诗句能隐藏关键字,像考试一样检验效果。- 小技巧:用 UniAPP 的uni.createPushMessage调用鸿蒙的通知权限,提醒文案特意用古诗意境,比如 “床前明月光,今天该复习啦~”,比干巴巴的 “请背诵” 更讨喜。
<view class="poem-content"> <block v-if="poemStore.showFullContent"> <text v-for="(line, idx) in poemStore.currentPoem.content" :key="idx" class="full-line">{{ line }}</text> </block> <block v-else> <text v-for="(line, idx) in poemStore.currentPoem.content" :key="idx" class="hide-line">□□□□□□□</text> </block> </view> <button class="toggle-btn" @click="poemStore.toggleFullContent"> {{ poemStore.showFullContent ? '切换到背诵模式' : '查看完整诗句' }} </button><script setup lang="ts"> import { usePoemStore } from '@/stores/poemStore'; import { useRouter } from 'vue-router'; const poemStore = usePoemStore(); const router = useRouter(); const goBack = () => { router.back(); }; const handleCollect = () => { if (poemStore.currentPoem) { poemStore.toggleCollect(poemStore.currentPoem.id); } }; </script>
- 小技巧:用 UniAPP 的uni.createPushMessage调用鸿蒙的通知权限,提醒文案特意用古诗意境,比如 “床前明月光,今天该复习啦~”,比干巴巴的 “请背诵” 更讨喜。
-
诗词 / 成语接龙:云开发让匹配更流畅
接龙功能需要实时匹配用户输入的诗句 / 成语,还要校验是否正确、有没有重复。一开始用本地数据库,结果数据量太大(收录了 2 万 + 古诗、1 万 + 成语),App 启动变慢。export interface Poem { id: number; title: string; // 诗名 author: string; // 作者(含朝代) content: string[]; // 诗句数组 category: string; // 分类(如山水、边塞) isCollected: boolean; // 是否收藏 }- 优化:改用uniCloud云开发,把诗词库、成语库存到云端,用云函数做匹配校验(比如输入 “举头望明月”,云函数自动查询以 “月” 开头的诗句),App 端只负责展示和输入,启动速度从 3 秒降到 1 秒,接龙延迟也几乎感知不到。
-
主题颜色:贴合古风的 “颜值小心思”
考虑到用户可能在不同场景使用(比如晚上背古诗要护眼),做了 3 种古风主题:黛青(默认)、朱砂(暖调)、月白(护眼)。- 实现:用 UniAPP 的vuex管理主题状态,结合鸿蒙的 “系统深色模式”,用户切换系统主题时,App 自动适配对应的古风配色 —— 比如系统开深色模式,App 自动切月白主题,字体加粗,保护视力。
import { defineStore } from 'pinia'; import { Poem } from '@/types/poem'; const mockPoems: Poem[] = [ { id: 1, title: '望庐山瀑布', author: '唐·李白', content: ['日照香炉生紫烟', '遥看瀑布挂前川', '飞流直下三千尺', '疑是银河落九天'], category: '山水', isCollected: false }, { id: 2, title: '静夜思', author: '唐·李白', content: ['床前明月光', '疑是地上霜', '举头望明月', '低头思故乡'], category: '思乡', isCollected: false }, { id: 3, title: '春晓', author: '唐·孟浩然', content: ['春眠不觉晓', '处处闻啼鸟', '夜来风雨声', '花落知多少'], category: '春景', isCollected: false } ]; export const usePoemStore = defineStore('poem', { state: () => ({ poems: mockPoems as Poem[], // 古诗列表 currentPoem: null as Poem | null, // 当前选中古诗 showFullContent: false // 详情页是否显示完整诗句(背诵模式控制) }), actions: { // 选中古诗 selectPoem(poemId: number) { this.currentPoem = this.poems.find(poem => poem.id === poemId) || null; this.showFullContent = false; // 进入背诵模式,默认隐藏完整诗句 }, // 切换收藏状态 toggleCollect(poemId: number) { const poem = this.poems.find(poem => poem.id === poemId); if (poem) poem.isCollected = !poem.isCollected; }, // 切换完整诗句显示(背诵/查看模式) toggleFullContent() { this.showFullContent = !this.showFullContent; } } });
- 实现:用 UniAPP 的vuex管理主题状态,结合鸿蒙的 “系统深色模式”,用户切换系统主题时,App 自动适配对应的古风配色 —— 比如系统开深色模式,App 自动切月白主题,字体加粗,保护视力。
五、✅ 后续功能想法 ✅
- “想要更多主题颜色”→ 新增 “竹绿”“藤黄” 2 种配色;
- “朗读广场想给作品点赞”→ 加了点赞功能,用uniCloud存储互动数据;
- “背古诗想有奖励”→ 做了 “背诵勋章”,集齐 5 个勋章能解锁古诗插画壁纸。
虽然还未成功上架市场,但在开发中寻找用户体验过程中,最让我感动的是一条评论:“我家娃以前不爱背古诗,现在每天打卡接龙,还会给同学分享自己的朗读作品,谢谢开发者让传统文化变有趣~” 这种时候,觉得熬夜改 bug、反复适配都值了!
六、🌟星光不负:技术与文化的双向奔赴🌟
从一开始的 “想做个古诗工具”,到现在的 “让自己更了解古诗并爱上它”,用 UniAPP 开发鸿蒙 App 的这 3 个月,不仅让我摸清了跨平台开发的套路,更懂了 “技术是为需求服务”—— 不是堆功能,而是让应用真正有用起来、用得爽。
回头看,选择 UniAPP 是最正确的决定:它让我不用纠结原生语法,能把更多精力放在 “怎么让古诗更有趣” 上;而鸿蒙的开放能力(云开发、云调试、HarmonyOS SDK、云测试)等,又让 App 的体验更上一层楼。就像古诗里说的 “行则将至”,技术之路没有捷径,但只要朝着目标一步步走,星光总会照亮前路。
接下来,我还想加 AR 功能(用鸿蒙的 AR SDK,扫描实景生成古诗意境)、古诗合唱(朗读广场支持多人合拍),让传统文化通过技术 “活” 起来、“火” 起来。如果你也在做 UniAPP + 鸿蒙开发,或者对古诗 App 有更多想法,欢迎一起交流~ 毕竟,码向未来的路上,有人同行更精彩!
一款无广告重拾儿时趣味的古诗 App 的开发过程记录
一、🌈缘起:让古诗 “活” 起来,而非躺在角落🌈
做这款 App 的初衷,藏在三个真实需求里:
一次偶然的寻找碰上鸿蒙的星光闪烁:翻找学生时代的语文诗词,想重拾那份诗词氛围时,书本早已不见踪影,此时便想在手机上寻找这类APP,市面古诗 App 要么广告扎堆,要么功能枯燥,实在感受不到当年的那种氛围;
身边朋友想重拾古诗,却缺合适的背诵工具,也没有专属交流渠道(总不能天天在朋友圈发古诗);
古诗的意境与字词之美,不该只靠 “死记硬背”—— 结合互动、朗读、释义,让大家 “懂了再背”,才是真正的文化传承。
所以核心需求很明确:做一款 “不枯燥、能互动、够纯粹” 的古诗工具。既要满足学习需求,又要兼顾趣味性,还得适配鸿蒙系统(毕竟鸿蒙用户越来越多,生态也日趋完善)。
二、💡技术选型:为啥 “锁死” UniAPP?💡
选技术栈时纠结了 3 天,最终敲定 UniAPP,全靠 “实用主义”:
排除鸿蒙原生开发:适配鸿蒙虽丝滑,但单人开发要重新学原生语法,还无法兼顾其他平台,效率太低;
排除其他跨平台框架:要么对鸿蒙适配不完善,要么插件生态薄弱,像诗词朗读、音频上传等功能得手动造轮子;
选择 UniAPP 的核心原因:
跨平台省心:一套代码可打包鸿蒙 App,后续扩展安卓、iOS 版本无需重构,对个人开发者极度友好;
- 鸿蒙适配 “自带 buff”:HBuilderX 提供现成打包模板和专属适配插件,不用手动修改大量配置;
- 生态够全:uniCloud 云开发、音频组件、数据库插件,刚好满足古诗存储、朗读上传、接龙匹配等核心需求;
- 学习成本低:有微信小程序开发基础,UniAPP 的 Vue 语法无缝衔接,1 周就能上手。
简单说:用 UniAPP 开发鸿蒙,就像 “站在巨人肩膀上”—— 不用从零学鸿蒙原生,又能享受鸿蒙系统特性,对非专业开发者太友好了!
三、⚠️踩坑实录:鸿蒙适配那些 “磨人的小妖精”⚠️
开发前以为 “跨平台 = 一路顺畅”,结果真正适配鸿蒙时,还是踩了不少坑,分享 3 个最印象深刻的:
权限申请:鸿蒙的 “规矩” 和其他平台不一样
做朗读广场时,需要调用手机麦克风录音、存储音频文件。一开始直接复用了其他平台的权限代码,结果在鸿蒙上直接报错 —— 录音功能打不开!
- 坑点:鸿蒙的 “媒体权限” 需要单独申请,而且必须配置ohos.permission.READ_MEDIA和ohos.permission.WRITE_MEDIA,还得在代码里动态弹窗说明 “为啥要要权限”(比如 “需要录音才能上传你的朗读作品”),光说 “需要权限” 会被系统拒绝;而且必须在鸿蒙的AGC后台进行同步申请该权限,因为该权限属于受限权限;而且!!!如果是使用的鸿蒙自家的隐私托管服务,必须要在隐私托管服务中同步该权限的声明
- 解决:使用uts插件配置权限;然后在AGC后台同步申请该受限权限通过率直接 100%。
// #ifdef APP-HARMONY import "@/uni_modules/harmony-permissions" // #endif
{
"module": {
"name": "uni_modules__harmony_permissions",
"type": "har",
"deviceTypes": [
"default",
"tablet",
"2in1"
],
"requestPermissions": [
{
"name": "ohos.permission.INTERNET"
},{
"name": "ohos.permission.WRITE_MEDIA",
"reason": "$string:media_desc",
"usedScene": {"when": "inuse"}
},{
"name": "ohos.permission.READ_MEDIA",
"reason": "$string:media_desc",
"usedScene": {"when": "inuse"}
}
]
}
}
服务卡片适配:桌面卡片让古诗 “触手可及”
鸿蒙的桌面卡片是个大亮点,我想做个 “每日一句” 卡片,用户不用打开 App,桌面就能看到古诗。
- 坑点:UniAPP 打包鸿蒙应用时,卡片的尺寸适配很麻烦,比如 3x2、2x2 的卡片布局会错乱,而且卡片数据刷新需要和主 App 同步;
- 解决:用 UniAPP 提供的uni-app x编译模式(专门优化鸿蒙适配),卡片布局用flex弹性盒,固定宽高比;数据同步用uniCloud实时数据库,主 App 更新 “每日一句” 后,卡片自动刷新,不用用户手动操作 —— 现在不少用户说 “每天解锁手机先看一眼古诗,感觉很治愈”。
音频播放:后台播放老是 “断档”
朗读广场的核心是 “听别人读古诗”,但一开始用户反馈 “退到后台就停了”,体验很差。
- 坑点:鸿蒙对后台音频播放有严格限制,普通的audio组件在后台会被系统暂停;
- 解决:集成了鸿蒙的AVPlayer SDK(UniAPP 可以直接调用鸿蒙原生 SDK),在manifest.json里配置 “后台音频权限”,同时用 UniAPP 的onBackground生命周期监听,退后台时自动切换到鸿蒙原生播放器,现在后台播放能稳定运行,用户还能边听古诗边刷微信~
四、📦功能落地:每个模块都是 “心头好”📦
结合古诗的核心需求,几个功能模块都是 “边踩坑边优化” 出来的,挑 3 个重点说:
-
背一背:用 “艾宾浩斯曲线” 让背诵不费脑
一开始只是简单做了 “列表 + 背诵打卡”,但用户反馈 “背了就忘”。后来用 UniAPP 的storage存储用户背诵记录,结合艾宾浩斯遗忘曲线,在对应时间点推送提醒(比如第 1 天、第 3 天、第 7 天),还加了 “遮字默写” 功能 —— 点击诗句能隐藏关键字,像考试一样检验效果。- 小技巧:用 UniAPP 的uni.createPushMessage调用鸿蒙的通知权限,提醒文案特意用古诗意境,比如 “床前明月光,今天该复习啦~”,比干巴巴的 “请背诵” 更讨喜。
<view class="poem-content"> <block v-if="poemStore.showFullContent"> <text v-for="(line, idx) in poemStore.currentPoem.content" :key="idx" class="full-line">{{ line }}</text> </block> <block v-else> <text v-for="(line, idx) in poemStore.currentPoem.content" :key="idx" class="hide-line">□□□□□□□</text> </block> </view> <button class="toggle-btn" @click="poemStore.toggleFullContent"> {{ poemStore.showFullContent ? '切换到背诵模式' : '查看完整诗句' }} </button><script setup lang="ts"> import { usePoemStore } from '@/stores/poemStore'; import { useRouter } from 'vue-router'; const poemStore = usePoemStore(); const router = useRouter(); const goBack = () => { router.back(); }; const handleCollect = () => { if (poemStore.currentPoem) { poemStore.toggleCollect(poemStore.currentPoem.id); } }; </script>
- 小技巧:用 UniAPP 的uni.createPushMessage调用鸿蒙的通知权限,提醒文案特意用古诗意境,比如 “床前明月光,今天该复习啦~”,比干巴巴的 “请背诵” 更讨喜。
-
诗词 / 成语接龙:云开发让匹配更流畅
接龙功能需要实时匹配用户输入的诗句 / 成语,还要校验是否正确、有没有重复。一开始用本地数据库,结果数据量太大(收录了 2 万 + 古诗、1 万 + 成语),App 启动变慢。export interface Poem { id: number; title: string; // 诗名 author: string; // 作者(含朝代) content: string[]; // 诗句数组 category: string; // 分类(如山水、边塞) isCollected: boolean; // 是否收藏 }- 优化:改用uniCloud云开发,把诗词库、成语库存到云端,用云函数做匹配校验(比如输入 “举头望明月”,云函数自动查询以 “月” 开头的诗句),App 端只负责展示和输入,启动速度从 3 秒降到 1 秒,接龙延迟也几乎感知不到。
-
主题颜色:贴合古风的 “颜值小心思”
考虑到用户可能在不同场景使用(比如晚上背古诗要护眼),做了 3 种古风主题:黛青(默认)、朱砂(暖调)、月白(护眼)。- 实现:用 UniAPP 的vuex管理主题状态,结合鸿蒙的 “系统深色模式”,用户切换系统主题时,App 自动适配对应的古风配色 —— 比如系统开深色模式,App 自动切月白主题,字体加粗,保护视力。
import { defineStore } from 'pinia'; import { Poem } from '@/types/poem'; const mockPoems: Poem[] = [ { id: 1, title: '望庐山瀑布', author: '唐·李白', content: ['日照香炉生紫烟', '遥看瀑布挂前川', '飞流直下三千尺', '疑是银河落九天'], category: '山水', isCollected: false }, { id: 2, title: '静夜思', author: '唐·李白', content: ['床前明月光', '疑是地上霜', '举头望明月', '低头思故乡'], category: '思乡', isCollected: false }, { id: 3, title: '春晓', author: '唐·孟浩然', content: ['春眠不觉晓', '处处闻啼鸟', '夜来风雨声', '花落知多少'], category: '春景', isCollected: false } ]; export const usePoemStore = defineStore('poem', { state: () => ({ poems: mockPoems as Poem[], // 古诗列表 currentPoem: null as Poem | null, // 当前选中古诗 showFullContent: false // 详情页是否显示完整诗句(背诵模式控制) }), actions: { // 选中古诗 selectPoem(poemId: number) { this.currentPoem = this.poems.find(poem => poem.id === poemId) || null; this.showFullContent = false; // 进入背诵模式,默认隐藏完整诗句 }, // 切换收藏状态 toggleCollect(poemId: number) { const poem = this.poems.find(poem => poem.id === poemId); if (poem) poem.isCollected = !poem.isCollected; }, // 切换完整诗句显示(背诵/查看模式) toggleFullContent() { this.showFullContent = !this.showFullContent; } } });
- 实现:用 UniAPP 的vuex管理主题状态,结合鸿蒙的 “系统深色模式”,用户切换系统主题时,App 自动适配对应的古风配色 —— 比如系统开深色模式,App 自动切月白主题,字体加粗,保护视力。
五、✅ 后续功能想法 ✅
- “想要更多主题颜色”→ 新增 “竹绿”“藤黄” 2 种配色;
- “朗读广场想给作品点赞”→ 加了点赞功能,用uniCloud存储互动数据;
- “背古诗想有奖励”→ 做了 “背诵勋章”,集齐 5 个勋章能解锁古诗插画壁纸。
虽然还未成功上架市场,但在开发中寻找用户体验过程中,最让我感动的是一条评论:“我家娃以前不爱背古诗,现在每天打卡接龙,还会给同学分享自己的朗读作品,谢谢开发者让传统文化变有趣~” 这种时候,觉得熬夜改 bug、反复适配都值了!
六、🌟星光不负:技术与文化的双向奔赴🌟
从一开始的 “想做个古诗工具”,到现在的 “让自己更了解古诗并爱上它”,用 UniAPP 开发鸿蒙 App 的这 3 个月,不仅让我摸清了跨平台开发的套路,更懂了 “技术是为需求服务”—— 不是堆功能,而是让应用真正有用起来、用得爽。
回头看,选择 UniAPP 是最正确的决定:它让我不用纠结原生语法,能把更多精力放在 “怎么让古诗更有趣” 上;而鸿蒙的开放能力(云开发、云调试、HarmonyOS SDK、云测试)等,又让 App 的体验更上一层楼。就像古诗里说的 “行则将至”,技术之路没有捷径,但只要朝着目标一步步走,星光总会照亮前路。
接下来,我还想加 AR 功能(用鸿蒙的 AR SDK,扫描实景生成古诗意境)、古诗合唱(朗读广场支持多人合拍),让传统文化通过技术 “活” 起来、“火” 起来。如果你也在做 UniAPP + 鸿蒙开发,或者对古诗 App 有更多想法,欢迎一起交流~ 毕竟,码向未来的路上,有人同行更精彩!





