读取手机通讯录:用 TaoToken 统一 Key 打通权限申请与数据解析链路
1. 从一次真机崩溃说起读取手机通讯录到底难在哪很多人第一次写「读取手机通讯录」这个功能都是被产品经理一句「把联系人导进来」给带进坑的。代码写起来好像就几行申请权限、查 Cursor、循环读字段、塞进集合。但真机一跑问题全冒出来了——Android 13 以上READ_CONTACTS弹窗不出现、Cursor 忘记关导致内存泄漏、联系人头像读出来是 null、同一个号码重复出现好几条、华为和小米上字段名对不上。我试过在一个项目里把通讯录导入做成「一键同步」结果测试机跑得好好的用户机上直接 ANR。后来拆开看问题出在三件事上权限申请没做版本分支、Cursor 遍历时在主线程做了 Bitmap 解码、异常兜底只写了个空 catch。这三件事恰好就是「读取手机通讯录」这条链路上最容易翻车的地方。所以这篇不讲虚的就围绕一条完整链路来写运行时权限申请 → 联系人字段解析 → 异常兜底 → 把模型调用 endpoint 改到 TaoToken 做字段清洗与结构化输出。适合谁看正在做通讯录导入、联系人去重、CRM 同步、或者想把本地联系人喂给大模型做整理的移动端开发者。读完你能直接抄走权限声明、查询代码、字段映射表还有一份常见报错对照表。核心检索词先摆出来读取手机通讯录、运行时权限申请、联系人字段解析、Cursor 遍历、TaoToken 统一 Key。这几个词会贯穿全文你搜到的和这里写的应该是同一件事。先说清楚一个前提通讯录属于敏感个人数据读取前必须拿到用户明确授权且只能用于用户知情同意的用途。本文所有代码都建立在「用户主动点击导入按钮」这个场景上不做后台静默读取这一点在合规上是底线。2. 权限申请与字段解析Android 读取手机通讯录的完整链路2.1 权限声明Manifest 里到底要写几个先看AndroidManifest.xml。读取通讯录最基础的是READ_CONTACTS如果你还要写入比如合并重复联系人再加WRITE_CONTACTS。注意 Android 6.0API 23之后这两个都是危险权限必须运行时申请光在 Manifest 里声明没用。manifest xmlns:androidhttp://schemas.android.com/apk/res/android packagecom.example.contactimport uses-permission android:nameandroid.permission.READ_CONTACTS / uses-permission android:nameandroid.permission.WRITE_CONTACTS / application android:allowBackuptrue android:label联系人导入 !-- 你的 Activity / Service -- /application /manifest这里有个坑Android 13API 33开始部分权限被拆得更细但READ_CONTACTS本身没有被拆分所以不用像读媒体文件那样去处理READ_MEDIA_IMAGES。真正需要版本分支的是「申请方式」和「用户拒绝后的引导」。2.2 运行时权限申请用 ActivityResultLauncher 替代旧 API老代码里常见onRequestPermissionsResultrequestPermissions这套在 AndroidX 里已经过时。现在推荐registerForActivityResult代码更短回调更清晰。class ContactImportActivity : AppCompatActivity() { private val requestPermission registerForActivityResult(ActivityResultContracts.RequestPermission()) { granted - if (granted) { loadContacts() } else { // 用户拒绝给出解释并引导去设置页 showPermissionDeniedDialog() } } private fun ensurePermissionAndLoad() { when { ContextCompat.checkSelfPermission( this, Manifest.permission.READ_CONTACTS ) PackageManager.PERMISSION_GRANTED - { loadContacts() } shouldShowRequestPermissionRationale(Manifest.permission.READ_CONTACTS) - { // 用户之前拒绝过先解释为什么需要 showRationaleDialog { requestPermission.launch(Manifest.permission.READ_CONTACTS) } } else - { requestPermission.launch(Manifest.permission.READ_CONTACTS) } } } }shouldShowRequestPermissionRationale返回 true说明用户拒绝过一次但没勾「不再询问」这时候先弹一个说明框通过率会高很多。如果返回 false 且权限没给多半是勾了「不再询问」只能引导去系统设置页手动开。2.3 字段解析Cursor 遍历的正确姿势通讯录数据在ContactsContract里联系人、电话、邮箱、头像分散在不同表。最省事的做法是用ContactsContract.Contacts.CONTENT_URI查主表再用_ID去查子表。但这样会有 N1 查询问题联系人一多就慢。更好的方式是直接查Phone.CONTENT_URI或Data.CONTENT_URI一次拿到需要的字段。下面这段是查「有电话号码的联系人」包含姓名、电话、头像 IDprivate fun loadContacts(): ListContact { val contacts mutableListOfContact() val projection arrayOf( ContactsContract.CommonDataKinds.Phone.CONTACT_ID, ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME, ContactsContract.CommonDataKinds.Phone.NUMBER, ContactsContract.CommonDataKinds.Phone.PHOTO_ID ) val selection ${ContactsContract.CommonDataKinds.Phone.NUMBER} IS NOT NULL val sortOrder ${ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME} ASC contentResolver.query( ContactsContract.CommonDataKinds.Phone.CONTENT_URI, projection, selection, null, sortOrder )?.use { cursor - val idIdx cursor.getColumnIndexOrThrow( ContactsContract.CommonDataKinds.Phone.CONTACT_ID) val nameIdx cursor.getColumnIndexOrThrow( ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME) val numberIdx cursor.getColumnIndexOrThrow( ContactsContract.CommonDataKinds.Phone.NUMBER) val photoIdx cursor.getColumnIndexOrThrow( ContactsContract.CommonDataKinds.Phone.PHOTO_ID) while (cursor.moveToNext()) { val contact Contact( contactId cursor.getLong(idIdx), name cursor.getString(nameIdx) ?: , phone cursor.getString(numberIdx) ?: , photoId cursor.getLong(photoIdx) ) contacts.add(contact) } } return contacts }几个关键点use {}是 Kotlin 的扩展函数等价于 try-finally保证 Cursor 一定关闭。老代码里手动cursor.close()一旦中间抛异常就漏了这是内存泄漏的常见来源。getColumnIndexOrThrow比getColumnIndex好字段不存在时直接抛异常而不是返回 -1 让你在后面越界。字段名对不上时能第一时间发现。PHOTO_ID拿到的是头像的 ID不是二进制。要真正拿到图片得用这个 ID 去查Data表再解码。这一步千万别在主线程做。2.4 头像解码放到子线程别在主线程碰 Bitmap头像二进制存在ContactsContract.Data表里字段是PHOTO。解码用BitmapFactory.decodeStreamsuspend fun loadAvatar(photoId: Long): Bitmap? withContext(Dispatchers.IO) { if (photoId 0L) returnwithContext null val uri ContentUris.withAppendedId( ContactsContract.Data.CONTENT_URI, photoId) contentResolver.openInputStream(uri)?.use { input - BitmapFactory.decodeStream(input) } }withContext(Dispatchers.IO)把它切到 IO 线程。如果你用协程记得在 Activity 销毁时取消否则回调回来 View 已经没了。2.5 异常兜底别写空 catch通讯录读取的异常主要有三类权限被撤销SecurityException、Cursor 字段缺失IllegalArgumentException、IO 异常。兜底策略是权限异常重新走申请流程字段异常降级用getColumnIndex加判空IO 异常跳过当前条目继续。try { val list loadContacts() renderList(list) } catch (e: SecurityException) { // 权限在读取过程中被撤销 ensurePermissionAndLoad() } catch (e: IllegalArgumentException) { // 字段不匹配降级处理 Log.e(TAG, 字段解析失败, e) renderList(emptyList()) } catch (e: Exception) { Log.e(TAG, 读取通讯录未知异常, e) toast(读取失败请重试) }到这里本地链路的骨架就搭完了。但真实业务里联系人数据往往是脏的号码带空格、带 86、姓名里混着表情、同一个人存了三条。这时候就该把模型调用接进来做清洗和结构化。3. 把模型调用 endpoint 改到 TaoToken统一 Key 的配置方法3.1 为什么要在通讯录场景里接模型本地解析出来的联系人字段是「能用」但「不干净」。比如号码86 138-0000-0000、13800000000、013800000000混在一起姓名有「张三」「张三同事」「张 三」。如果直接入库去重和匹配会很难做。用模型做一轮字段清洗和结构化输出能把号码归一化成 E.164、姓名去掉备注、还能顺便判断哪些是公司联系人。关键问题是模型调用要配 Key、配 endpoint。如果每个项目都单独申请、单独管理Key 一多就乱。TaoToken 的思路是统一 Key一个 Key 走多个模型endpoint 改一处就行。3.2 配置三件套Base URL Key Model ID不管你用哪种客户端接入任何 OpenAI 兼容接口都离不开三件套Base URL、API Key、Model ID。TaoToken 的 API 地址是https://taotoken.net/api注意这个地址不带任何查询参数直接作为 base。先看最通用的 JSON 配置很多工具用这种格式{ base_url: https://taotoken.net/api, api_key: sk-你的TaoTokenKey, model: claude-sonnet-4-20250514, timeout: 60 }如果你用的是 Cline 这类 VS Code 插件配置写在settings.json里字段名可能是baseUrl和apiKey注意大小写{ cline.apiProvider: openai, cline.openAiBaseUrl: https://taotoken.net/api, cline.openAiApiKey: sk-你的TaoTokenKey, cline.openAiModelId: claude-sonnet-4-20250514 }如果你用 Codex 这类工具认证信息写在auth.json里路径通常在用户目录下的.codex/auth.json{ OPENAI_API_KEY: sk-你的TaoTokenKey, OPENAI_BASE_URL: https://taotoken.net/api }三件套里最容易错的是 Base URL 结尾。有的工具要求带/v1有的要求不带。TaoToken 的https://taotoken.net/api作为 base具体路径由 SDK 拼接。如果你在 curl 里手写完整地址是https://taotoken.net/api/v1/chat/completions。3.3 在通讯录清洗里怎么调用假设你已经把联系人列表序列化成 JSON接下来发一个请求让模型做清洗。用 curl 演示最直观curl https://taotoken.net/api/v1/chat/completions \ -H Content-Type: application/json \ -H Authorization: Bearer sk-你的TaoTokenKey \ -d { model: claude-sonnet-4-20250514, messages: [ { role: system, content: 你是联系人数据清洗助手。输入是联系人数组请输出结构化 JSONphone 归一化为 E.164 格式name 去掉括号备注并标记 isCompany。只输出 JSON不要解释。 }, { role: user, content: [{\name\:\张三同事\,\phone\:\86 138-0000-0000\},{\name\:\李四\,\phone\:\013900000000\}] } ], temperature: 0 }temperature设 0让输出稳定避免每次清洗结果不一样。返回的choices[0].message.content就是结构化后的 JSON直接解析入库。如果你在 Android 里调用用 OkHttp 或 Retrofit 都行把 base URL 设成https://taotoken.net/api/注意 Retrofit 要求 base URL 以/结尾。Key 不要硬编码在代码里放local.properties或 BuildConfig避免打包泄露。3.4 统一 Key 的好处一个 Key 管多个模型切换模型只改model字段endpoint 和 Key 都不动。对通讯录这种「清洗用便宜模型、复杂判断用强模型」的场景很实用。你可以在配置里放两个 model ID简单清洗走快的遇到歧义再走强的。需要拿 Key 的话去控制台创建https://taotoken.net/console?utm_sourcetaotoken_aicg_blog_endutm_contentconsoleutm_campaignrewrite 。创建后记得复制保存页面关了就看不到了。4. 验证请求确认链路真的通了4.1 先用最小请求验证 Key 和 endpoint别一上来就跑完整通讯录。先发一个最小请求确认三件套没问题curl https://taotoken.net/api/v1/chat/completions \ -H Content-Type: application/json \ -H Authorization: Bearer sk-你的TaoTokenKey \ -d { model: claude-sonnet-4-20250514, messages: [{role: user, content: 回复 ok}], max_tokens: 10 }期望返回里choices[0].message.content包含ok。如果这一步就失败先看第 5 节的报错对照表别往下走。4.2 再验证通讯录读取在 App 里点导入按钮观察日志。正常流程应该是权限弹窗出现 → 授权 → 日志打印「读取到 N 条联系人」→ 列表渲染。如果 N 是 0先确认模拟器里有没有存联系人模拟器默认是空的。4.3 最后验证清洗结果把本地读到的联系人 JSON 发给模型检查返回val cleaned contactCleanService.clean(rawContactsJson) // 期望phone 变成 8613800000000 这种格式 // name 里没有括号备注 // 每条都有 isCompany 字段验证清单可以做成一个 checklist检查项期望结果失败时看权限弹窗首次点击出现第 5 节 401 / 权限被拒读取条数与系统通讯录一致Cursor 字段名号码格式E.164模型 prompt头像非空或占位图PHOTO_ID 解码模型返回合法 JSON第 5 节 reading choices4.4 用模型对话页快速试 prompt如果你不想每次都写代码试 prompt可以直接在模型对话页里粘贴联系人 JSON调好 system prompt 再搬回代码。地址https://taotoken.net/chat?utm_sourcetaotoken_aicg_blog_endutm_contentmodel_chatutm_campaignrewrite 。这样调 prompt 效率高很多尤其是清洗规则复杂的时候。5. 常见报错排查401、local proxy failed、reading choices、OAuth这一节按真实报错来对照。每个报错我都写清楚现象、原因、解决。5.1 401 Unauthorized现象请求返回{error:{message:Invalid API key}}或状态码 401。原因通常三个Key 复制时带了空格、Key 已经失效、Header 格式不对。检查Authorization: Bearer sk-xxxBearer 和 Key 之间一个空格Key 前后不能有空格。如果确认 Key 没问题还是 401去控制台重新生成一个https://taotoken.net/api-keys?utm_sourcetaotoken_aicg_blog_endutm_contentapi_keysutm_campaignrewrite 。5.2 local proxy failed现象客户端报local proxy failed或connection refused。这个报错多半是本地代理配置残留。检查你的工具里有没有设http_proxy/https_proxy环境变量或者客户端设置里开了「使用系统代理」。把代理关掉直连https://taotoken.net/api。如果你在公司网络里确认防火墙没拦 443 端口。5.3 reading choices 相关报错现象Cannot read properties of undefined (reading choices)或reading 0。这是解析返回时choices不存在。原因一般是请求根本没成功返回的是错误对象但代码直接去读response.choices[0]。正确做法是先判断状态码和error字段val body response.body?.string() val json JSONObject(body) if (json.has(error)) { Log.e(TAG, API 错误: ${json.getJSONObject(error).getString(message)}) return } val choices json.optJSONArray(choices) if (choices null || choices.length() 0) { Log.e(TAG, 返回为空) return } val content choices.getJSONObject(0) .getJSONObject(message).getString(content)5.4 OAuth 相关报错现象OAuth token expired或invalid_grant。如果你用的是 Claude Code 这类走 OAuth 的工具报这个说明登录态过期。重新走一次登录流程即可。注意 OAuth 和 API Key 是两套体系别混用。如果你在 Claude Code 里想改用统一 Key把配置里的认证方式从 OAuth 切到 API KeyBase URL 填https://taotoken.net/apiModel ID 填你要用的模型。5.5 报错对照表报错关键词大概率原因处理401 / Invalid API keyKey 错或失效重新复制或生成local proxy failed本地代理残留关代理直连reading choices未判空直接解析先判 error 再取 choicesOAuth token expired登录态过期重新登录或切 API KeySecurityException权限被撤销重新申请权限IllegalArgumentExceptionCursor 字段名错用 getColumnIndexOrThrow 定位ANR主线程解码头像切到 IO 线程排查顺序建议先 curl 验证 Key 和 endpoint再验证 App 权限最后验证模型返回解析。一层一层来别跳。6. 长期做通讯录清洗与 Agent 编排怎么选接入方式通讯录清洗这种任务如果只是偶尔跑一次用模型对话页手动粘贴就够了。但如果你要做成产品里的常驻功能比如「每次打开 App 自动同步并清洗」那就需要一个稳定的接入方式。短期验证 prompt用模型对话页最快https://taotoken.net/chat?utm_sourcetaotoken_aicg_blog_endutm_contentmodel_chatutm_campaignrewrite 。调好规则再搬进代码。如果你在写代码阶段需要频繁调 API、试不同模型用 API Key 直连https://taotoken.net/api-keys?utm_sourcetaotoken_aicg_blog_endutm_contentapi_keysutm_campaignrewrite 。配合接入文档看参数https://taotoken.net/doc?utm_sourcetaotoken_aicg_blog_endutm_contentdocutm_campaignrewrite 。如果你要做的是长期编码、Agent 编排比如让模型自动处理联系人去重、自动分类、自动生成标签那更适合用 Coding Plan把模型能力嵌进你的开发流https://taotoken.net/coding-plan?utm_sourcetaotoken_aicg_blog_endutm_contentcoding_planutm_campaignrewrite 。最后说个我踩过的坑通讯录读取一定要在用户点击后触发别在onCreate里自动申请权限。用户没心理准备时弹权限框拒绝率极高而且一旦勾了「不再询问」后面很难挽回。把导入做成一个明确的按钮文案写清楚「导入后仅用于本地整理」通过率会好很多。模型清洗那一步记得给返回加超时和重试网络抖动时别让整个导入流程卡死。

相关新闻

YOLOv3猫狗检测专用数据集:val2014精筛2568图+DarkNet格式TXT

YOLOv3猫狗检测专用数据集:val2014精筛2568图+DarkNet格式TXT

简介:本资源是专为YOLOv3目标检测模型训练与验证打造的猫狗检测数据集,面向计算机视觉初学者、深度学习实践者及目标检测项目开发者,解决小类别(猫/狗)在COCO数据集中样本筛选难、标签格式适配复杂等实际问题。压缩包共…

2026/10/13 12:39:48 阅读更多 →
WSO2 EI 6.6.0实战:ESB集成运行时配置、代理服务与调优指南

WSO2 EI 6.6.0实战:ESB集成运行时配置、代理服务与调优指南

简介:这是一份WSO2 Enterprise Integrator 6.6.0系统级使用手册,面向企业集成架构师、中间件运维人员以及从传统ESB向新一代EI迁移的开发者。手册先梳理WSO2三款核心产品API Manager、Enterprise Integrator、Identity Server的定位,再深入EI…

2026/10/13 12:39:52 阅读更多 →
CMake Windows免安装zip使用指南:从解压配置到避坑实战

CMake Windows免安装zip使用指南:从解压配置到避坑实战

简介:CMake 3.29.7 for Windows x86-64 是一款官方绿色安装包,面向 C/C 开发者在 Windows 环境下快速搭建构建系统。解压后仅需将 bin 目录加入 PATH 环境变量即可直接使用,无需执行安装向导,适合离线部署与多机分发。包内共 2000…

2026/10/13 12:39:54 阅读更多 →

最新新闻

Java面试如何从“背八股”到“技术深度”?一线模拟面试复盘与追问链解析

Java面试如何从“背八股”到“技术深度”?一线模拟面试复盘与追问链解析

1. 面试官视角的一次模拟:为什么背题高分选手反而被刷有位程序员朋友备考了两个月,把网上能搜到的Java面试题背得滚瓜烂熟,结果在一场模拟面试里连前面十分钟都没撑过。他描述某个项目的技术方案时,堆了一串名词,却说不…

2026/10/13 14:02:53 阅读更多 →
智能体权限安全实战:AI拥有操作能力后,如何守住权限边界?

智能体权限安全实战:AI拥有操作能力后,如何守住权限边界?

最近在做一个Agent项目时,权限配置把我折腾得不轻。模型的对话能力早就不是瓶颈了,真正让人夜里睡不着的是:当AI拿着工具去操作真实系统时,你怎么保证它只做该做的事?这周把一个跨平台的智能体接进内部工单系统试跑&am…

2026/10/13 14:02:53 阅读更多 →
AI落地场景验证的五大基础设施:算力、数据、模型、平台与场景

AI落地场景验证的五大基础设施:算力、数据、模型、平台与场景

最近一年我接触了不少AI落地项目,一个特别明显的感受是:大家终于不再纠结“大模型能不能做这件事”,而是开始纠结“在我们这个场景里,它能不能稳定、可控、划算地用起来”。这两句话之间隔着的那段路,就是场景验证。标…

2026/10/13 14:02:53 阅读更多 →
从HTML网页到可查询知识图谱:规则抽取与可视化实战

从HTML网页到可查询知识图谱:规则抽取与可视化实战

简介:这是一套从非结构化文本自动构造知识图的端到端管道,名为 KnowledgeGraph_Builder,面向 NLP 爱好者、算法工程师及知识图谱研究者。项目借助 spaCy、Stanford CoreNLP、Huggingface Neural Coref 和句子转换器等工具,实现了命…

2026/10/13 14:02:53 阅读更多 →
从大厂面经切入Agent开发:用真实场景重构AI工程能力

从大厂面经切入Agent开发:用真实场景重构AI工程能力

1. 项目概述:这不是刷题,而是一场面向真实工程的Agent能力重构“从面经开始的agent开发学习”——这个标题乍看像程序员求职路上的临时抱佛脚,实则藏着一条被多数人忽略的隐性路径:面经不是终点,而是Agent开发最密集、…

2026/10/13 14:02:53 阅读更多 →
Logstash离线插件安装实战:依赖解析、打包与验证全流程

Logstash离线插件安装实战:依赖解析、打包与验证全流程

1. 为什么Logstash插件必须离线安装——一个被低估的生产环境现实Logstash作为ELK栈中承上启下的数据管道核心,其价值从来不在“能跑起来”,而在于“能在哪跑、怎么稳跑、出问题时能否快速恢复”。我见过太多团队在测试环境用bin/logstash-plugin instal…

2026/10/13 14:01:51 阅读更多 →

日新闻

物联网系统集成避坑指南:从选型到验收的关键要点

物联网系统集成避坑指南:从选型到验收的关键要点

做了这么多年物联网系统集成的项目,我最大的感受是,大部分坑不是出在技术前沿,而是出在一些看起来很平常的地方。设备选了便宜的、协议没问清楚、现场没摸透、验收标准写得含糊——这些细枝末节,最后都会变成延期、超支和扯皮的大…

2026/10/13 0:00:57 阅读更多 →
ESP32舵机控制全攻略:从PWM原理到高级玩法与常见故障排查

ESP32舵机控制全攻略:从PWM原理到高级玩法与常见故障排查

如果你玩ESP32有一阵子了,很难不碰到舵机控制这道坎。做智能小车要转方向,做机械臂要抬关节,做云台要偏航俯仰,背后都是同一个东西在干活:舵机。而我见过太多人卡在“代码能编译、舵机就是不听话”这个阶段&#xff0c…

2026/10/13 0:00:57 阅读更多 →
CAN总线原理与STM32实战:抗干扰、仲裁、错误处理全解析

CAN总线原理与STM32实战:抗干扰、仲裁、错误处理全解析

1. 为什么CAN总线至今仍是工业现场的“硬通货”?——从汽车底盘到智能温室的真实需求你有没有拆过一辆老款燃油车的中控台?或者调试过某高校实验室里那台跑着Modbus协议却频频丢帧的PLC控制柜?又或者,在某个农业物联网项目里&…

2026/10/13 0:00:57 阅读更多 →

周新闻

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

简介:基于 ARIMA、LSTM、Transformer 等模型的流感时间序列预测 Python 源码,面向计算机相关专业课程设计与期末大作业学生,以及项目实战学习者。内容覆盖预处理、平稳性检验、定阶、残差分析、多模型对比预测的完整时序建模流程,…

2026/10/13 2:54:56 阅读更多 →
影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别 做影刀RPA自动化,十个新手有八个栽在"往输入框里填东西"这件事上:要么填不进去,要么填了一半,要么直接把原来内容追加在后面。这背后的根因&…

2026/10/12 0:16:38 阅读更多 →
影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容 1. 认识影刀:什么场景该用RPA采小说数据 起点中文网的页面结构相对稳定——分类榜单、书籍详情、章节内容三块独立页面,跳转链路清晰。这种场景非常适合影刀自动化&#x…

2026/10/13 1:58:08 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/12 21:05:09 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/12 14:48:49 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/12 18:11:17 阅读更多 →