Skip to content

Repository files navigation

PlantNet 植物养护助手

Android 原生植物养护 App,基于 Jetpack Compose + Material 3。当前版本 v2.1.0

通过通义千问多模态 API 实现植物识别、病害诊断、健康评估等 AI 功能,结合和风天气 API 实现天气感知的智能养护决策。


架构说明

整体架构

┌─────────────────────────────────────────────────┐
│                   UI Layer                       │
│  Jetpack Compose + Material 3 + Navigation       │
│  (10 Screen Modules, 21 Reusable Components)     │
├─────────────────────────────────────────────────┤
│                  Domain Layer                    │
│  PlantPhotoAnalyzer · CareDecisionEngine          │
│  WateringPeriodSuggester · PlantProfileMatcher    │
│  HealthCalculator · CareStatsAggregator           │
├─────────────────────────────────────────────────┤
│                  Data Layer                       │
│  ┌──────────┐  ┌──────────┐  ┌───────────────┐  │
│  │ SQLite   │  │ Retrofit │  │ DataStore     │  │
│  │ (9 Tables│  │ (DashScope│  │ (Preferences) │  │
│  │  11 DAOs)│  │  QWeather)│  │               │  │
│  └──────────┘  └──────────┘  └───────────────┘  │
├─────────────────────────────────────────────────┤
│              Background Tasks                    │
│  WorkManager: DailyCare / PlantReminder /         │
│               ExtremeWeather Workers              │
│  Glance AppWidget · Notification Channels         │
└─────────────────────────────────────────────────┘

项目结构

app/src/main/java/com/example/plantnet/
├── PlantNetApp.kt              # Application 类,手动 DI 容器
├── MainActivity.kt             # 入口 Activity
├── data/
│   ├── db/                     # 11 DAO + PlantDatabaseHelper
│   ├── model/                  # 17 数据模型
│   ├── network/                # Retrofit 接口定义
│   └── repository/             # 13 Repository
├── domain/                     # 13 领域逻辑类
├── notification/               # 11 通知/Worker 类
├── ui/
│   ├── component/              # 21 可复用 UI 组件
│   ├── navigation/             # 路由定义
│   ├── screen/                 # 10 功能模块
│   └── theme/                  # 主题/设计系统
├── util/                       # 工具类
└── widget/                     # 桌面小组件

技术栈

层面 技术
语言 Kotlin
UI Jetpack Compose + Material 3
导航 Navigation Compose 2.8.5
数据库 SQLite(SQLiteOpenHelper),9 表 11 DAO
偏好 DataStore Preferences 1.1.1
网络 Retrofit 2.11.0 + OkHttp 4.12.0 + Gson
图片 Coil Compose 2.7.0
后台 WorkManager 2.9.1
小组件 Glance AppWidget 1.1.1
AI 通义千问 DashScope(qwen3-omni-flash)
天气 和风天气 QWeather API
DI 手动依赖注入(PlantNetApp 单例)

关键 Prompt 与 Vibe 思路

Prompt 设计原则

  1. JSON-Only 输出约束:所有 prompt 均要求"仅返回 JSON,不要其他文字",确保客户端可稳定解析
  2. 天气环境注入:浇水周期 prompt 动态拼接用户所在地天气数据,使 AI 输出个性化结果
  3. 知识库修正:AI 返回结果经本地 WateringPeriodSuggester 修正,融合内置植物知识库的基准值
  4. 上下文增强:养护问答注入用户全部植物档案作为 system prompt 上下文

核心 Prompt 清单

植物识别 Prompt

请识别照片中的植物并评估其当前健康状态,仅返回 JSON,不要其他文字:
{
  "name":"植物中文名",
  "species":"科属或品种",
  "healthScore":85,
  "healthAssessment":"30字内:叶片颜色、是否有黄叶/病斑/缺水迹象",
  "wateringDays":5,
  "wateringReason":"20字内:结合盆土干湿、盆器大小、当地天气给出周期理由",
  "lightRequirement":"全日照/半阴/散射光/耐阴 之一",
  "description":"50字以内简介",
  "careTips":"浇水光照建议",
  "confidence":"高/中/低"
}
healthScore 为 0-100 整数;wateringDays 为 1-30 的个性化浇水间隔天数,
必须结合天气独立计算,不要照抄示例数字。

识别时动态拼接天气环境块(城市、气温、湿度、降水概率),引导 AI 结合天气给出个性化浇水周期。

健康评估 Prompt

请评估照片中植物的健康状态,仅返回 JSON,不要其他文字:
{"healthScore":85,"healthAssessment":"30字内:叶片颜色、是否有黄叶/病斑/缺水迹象"}
healthScore 为 0-100 整数。

生长对比 Prompt

请对比两张同一植物在不同时间的照片(第一张为较早,第二张为较晚),评估生长变化。
仅返回 JSON,不要其他文字:
{
  "summary":"50字内总体变化",
  "growthTrend":"变好/持平/变差",
  "changes":["叶色更绿","新芽2处"],
  "healthDelta":5,
  "suggestions":"30字内建议"
}
healthDelta 为 -100 到 100 的整数,表示健康度变化估计。

浇水周期 Prompt

请根据照片中植物状态、盆土干湿、盆器大小,并结合用户所在地天气与环境,
评估个性化浇水周期,仅返回 JSON,不要其他文字:
{"wateringDays":5,"wateringReason":"20字内理由,需提及天气或环境因素影响",
 "lightRequirement":"全日照/半阴/散射光/耐阴 之一"}
wateringDays 为 1-30 的整数;必须结合天气独立计算,不要照抄示例数字。

病害诊断 Prompt

请作为植物病理专家分析照片中植物的健康状况,仅返回 JSON:
{"summary":"总体判断50字内","possibleIssues":"可能的问题",
 "suggestions":"处理建议","severity":"轻/中/重"}
若看不出植物或无法判断,在 summary 中说明。

养护问答 System Prompt

你是专业的植物养护助手。根据用户植物档案回答问题,给出简洁实用的建议
用户植物档案
{动态注入用户所有植物的名称、种类、健康评分、浇水周期}
回答控制200字以内,使用中文

Vibe 思路

  • AI 作为结构化数据源:不把 AI 当聊天机器人,而是当作"多模态 JSON 生成器",prompt 精确约束输出格式
  • 本地修正 > 纯 AI 依赖:AI 返回的浇水周期经 WateringPeriodSuggester 修正,融合知识库基准值,避免 AI 幻觉导致极端值
  • 天气感知闭环:天气 API → 环境上下文注入 prompt → AI 个性化输出 → CareDecisionEngine 天气感知决策 → 通知推送,形成完整闭环
  • 图片压缩前置:AI 调用前将图片压缩至 768px 宽度并转 base64,控制 token 消耗

AI 调用逻辑

调用方式

  • 协议:OpenAI 兼容模式(DashScope compatible-mode/v1/chat/completions
  • 模型qwen3-omni-flash
  • 调用模式非流式(同步等待完整响应)
  • 认证Authorization: Bearer ${DASHSCOPE_API_KEY}
  • 超时:连接 30s / 读写 60s

请求构造

// 多模态请求(图片 + 文本)
ChatRequest(
    model = "qwen3-omni-flash",
    messages = listOf(
        Message(role = "user", content = listOf(
            ContentPart(type = "image_url", 
                image_url = ImageUrl(url = "data:image/jpeg;base64,{base64}")),
            ContentPart(type = "text", text = "prompt")
        ))
    )
)

// 文本问答请求(system + user)
ChatRequest(
    model = "qwen3-omni-flash",
    messages = listOf(
        Message(role = "system", content = listOf(
            ContentPart(type = "text", text = systemPrompt))),
        Message(role = "user", content = listOf(
            ContentPart(type = "text", text = question)))
    )
)

响应解析流程

AI Response (JSON string)
    │
    ▼
extractJson() ── 从回复文本中提取 {...} 子串
    │
    ▼
Gson JsonObject ── 按字段名手动解析
    │
    ▼
结构化数据模型 ── IdentifyResult / PlantHealthAnalysis / GrowthCompareResult
    │
    ▼
本地修正 ── WateringPeriodSuggester.refine() / PlantProfileMatcher
    │
    ▼
持久化 ── 写入 SQLite / 更新 UI 状态

AI 功能调用链路

功能 入口 调用链
植物识别 识别 Tab / FAB IdentifyViewModel → PlantPhotoAnalyzer.identifyPlant() → AiRepository.analyzeImage() → DashScope API → parseIdentifyResult() → enrichIdentifyResult()
病害诊断 识别 Tab IdentifyViewModel → AiRepository.analyzeImage() → DashScope API
健康评估 生长记录拍照 PlantPhotoAnalyzer.analyzeHealth() → AiRepository.analyzeImage() → DashScope API
生长对比 双图对比页 PlantPhotoAnalyzer.compareGrowth() → AiRepository.analyzeImages() → DashScope API
浇水周期 AI 识别添加 PlantPhotoAnalyzer.calculateWatering() → AiRepository.analyzeImage() → WateringPeriodSuggester.refine()
养护问答 我的 → 养护问答 CareAskViewModel → AiRepository.askCareQuestion() → DashScope API

Token 成本控制

  • 图片压缩至 768px 宽度后再 base64 编码,减少图片 token 消耗
  • 使用 qwen3-omni-flash 而非更大模型,平衡效果与成本
  • 养护问答限制 200 字回复,prompt 中明确约束输出长度
  • 非流式调用,单次请求完整返回,避免长连接开销

部署步骤说明

环境要求

  • Android Studio(推荐最新稳定版,需支持 AGP 9)
  • JDK 11+
  • Android SDK(minSdk 24,targetSdk 36)

构建与运行

  1. 克隆项目
git clone https://github.com/你的用户名/Plantnet.git
cd Plantnet
  1. 配置 API Key
cp local.properties.example local.properties

编辑 local.properties

sdk.dir=你的Android SDK路径
DASHSCOPE_API_KEY=你的通义千问Key
QWEATHER_API_KEY=你的和风天气Key
QWEATHER_API_HOST=你的专属域名.re.qweatherapi.com
  1. 构建运行
./gradlew assembleDebug

或直接在 Android Studio 中 Sync Gradle → Run。

API Key 获取

API 获取地址 用途
通义千问 DashScope https://dashscope.console.aliyun.com/ 植物识别、病害诊断、养护问答
和风天气 QWeather https://dev.qweather.com/ 实时天气、天气预报、极端天气预警

Key 通过 local.properties 注入到 BuildConfig不会提交到 Git

和风天气 HTTPS 与域名配置

和风天气 API 支持 HTTPS,需在控制台绑定专属域名:

  1. 登录和风天气开发控制台 → 项目管理 → 创建项目
  2. 绑定专属域名(格式:xxx.re.qweatherapi.com),该域名自动配置 SSL 证书
  3. 将域名填入 QWEATHER_API_HOST,App 内所有请求自动走 HTTPS

生成 Release APK

# 生成签名 APK
./gradlew assembleRelease

# 输出路径
# app/build/outputs/apk/release/app-release.apk

签名配置在 app/build.gradlesigningConfigs 中设置。


功能概览

  • 首页控制台:今日浇水、养护简报、统计卡片、和风天气;下拉刷新
  • 植物档案:添加/编辑/删除、分组、浇水/施肥/换盆/换土打卡、养护画像、AI 健康评估
  • 养护日历:浇水/施肥/换盆/换土日程,完成/忽略/推迟
  • 识别 Tab:植物识别与病害诊断同一 Tab 切换;识别结果预填添加表单
  • 生长记录:时间线拍照、AI 健康评分、双图生长对比
  • 养护问答:单轮 AI 问答,结合本地植物档案上下文
  • 知识库:常见植物养护指南,标签筛选
  • 全局统计:全库汇总与近 30 天养护柱状图
  • 桌面小组件:今日待浇水株数,点击跳转首页
  • 分享卡片:植物详情页生成分享图
  • 数据备份:ZIP v2 导出/导入(兼容旧版 JSON)

通知策略

类型 时机 开关
每日养护简报 每天 7:00 合并推送 每日 7:00 养护简报
单株浇水提醒 浇水周期到期时独立推送 单株浇水提醒
极端天气预警 暴雨/高温等触发时即时推送 极端天气预警
日历待办摘要 当日有施肥/换盆/换土待办 随每日简报通道

项目文档

文档 说明
CHANGELOG.md 版本变更
docs/plantnet-development-plan.md 完善方案与历史 Phase 进度
docs/superpowers/specs/2026-06-09-weather-care-design.md 天气感知养护设计
docs/superpowers/specs/2026-06-05-plant-care-app-design.md 初版设计(历史归档)

About

No description, website, or topics provided.

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages