# AGENTS.md — SmsMessage (notiMessage) Android 应用,监听通知栏短信/通知内容并上传至服务器。适配华为、MIUI 等手机。 ## 项目结构 ``` notiMessage/ ├── app/ # 主应用模块 (com.miraclegarden.smsmessage) │ ├── src/main/java/.../ │ │ ├── Activity/ # Activity 类 (MainActivity, NotificationActivity, SettingActivity, AppListActivity) │ │ ├── service/ # Service 类 (NotificationService — 通知监听核心) │ │ ├── comm/ # 通用组件 (CommonAdapter, ViewHolder) │ │ ├── App.java # Application 类,管理通知列表持久化 │ │ ├── MessageInfo.java, AppInfo.java # 数据模型 │ │ └── GsonUtils.java # JSON 工具类 │ └── src/main/res/ # 资源文件 ├── library/ # 基础库模块 (com.miraclegarden.library) │ └── MiracleGardenActivity # ViewBinding 基类 ├── build.gradle # 根构建文件 (AGP 7.3.0) ├── settings.gradle # 模块声明 + 仓库配置 └── gradle.properties # Gradle 配置 ``` ## 构建命令 ```bash # 构建 ./gradlew assembleDebug # 构建 debug APK ./gradlew assembleRelease # 构建 release APK ./gradlew build # 完整构建(编译 + lint + 测试) # Lint ./gradlew lint # 运行所有模块 lint ./gradlew :app:lint # 仅 app 模块 lint ./gradlew :library:lint # 仅 library 模块 lint # 单元测试 ./gradlew test # 运行所有模块单元测试 ./gradlew :app:testDebugUnitTest # 仅 app 模块 debug 单元测试 ./gradlew :app:testDebugUnitTest --tests "com.miraclegarden.smsmessage.ExampleUnitTest" # 运行单个测试类 ./gradlew :app:testDebugUnitTest --tests "*.ExampleUnitTest.addition_isCorrect" # 运行单个测试方法 # Android 测试(需要设备/模拟器) ./gradlew connectedAndroidTest # 运行所有模块 instrumented 测试 ./gradlew :app:connectedDebugAndroidTest # 仅 app 模块 # 清理 ./gradlew clean ``` ## SDK 与依赖版本 | 配置项 | app 模块 | library 模块 | |--------|---------|-------------| | compileSdk | 32 | 32 | | minSdk | 24 | 21 | | targetSdk | 32 | 32 | | Java | 17 | 17 | **关键依赖**: OkHttp 5.0.0-alpha.10 (网络), Gson 2.9.0 (JSON), ViewBinding (UI绑定), Material 1.6.1 **测试框架**: JUnit 4.13.2, Espresso 3.4.0, AndroidX Test JUnit 1.1.3 **Gradle**: 7.5.1, AGP 7.3.0 ## 语言与代码规范 ### 语言 纯 Java 项目,无 Kotlin。所有源文件均为 `.java`。 ### 导入顺序 遵循 Android 标准导入顺序: 1. `android.*` — Android 框架 2. `androidx.*` — AndroidX 兼容库 3. 项目内部包 (`com.miraclegarden.*`) 4. 第三方库 (`org.json.*`, `okhttp3.*`, `com.google.gson.*`) 5. `java.*` — Java 标准库 导入之间按组用空行分隔。不使用通配符导入(`*`)。 ### 命名规范 | 类型 | 规范 | 示例 | |------|------|------| | 类名 | PascalCase | `NotificationService`, `MessageInfo`, `CommonAdapter` | | 方法名 | camelCase | `initData()`, `initView()`, `getSbnByNotificatinList()` | | 变量 | camelCase | `messageInfo`, `sharedPreferences`, `appName` | | 常量 | UPPER_SNAKE_CASE | `private static final String TAG = "..."` | | 成员变量前缀 | 通用组件用 `m` 前缀 | `mContext`, `mDatas`, `mLayoutId` | | 布局文件 | activity_xxx / item_xxx | `activity_main.xml`, `activity_notification.xml` | | Activity 包名 | 大写开头子包 | `com.miraclegarden.smsmessage.Activity` | ### 类结构模式 Activity 类遵循统一初始化模式: ```java public class XxxActivity extends MiracleGardenActivity { private static final String TAG = "XxxActivity"; @Override protected void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); initData(); initView(); } private void initData() { /* 数据初始化 */ } private void initView() { /* UI 绑定与事件监听 */ } } ``` ### ViewBinding - 所有 Activity 继承 `MiracleGardenActivity` - 通过泛型参数自动反射创建 binding 实例 - 直接使用 `binding.xxx` 访问视图,**不使用** `findViewById` ### 数据模型 - POJO 风格:private 字段 + getter/setter - 提供无参和全参构造函数 - 静态工厂方法用于类型转换(如 `MessageInfo.AppInfoToMessageInfo()`) - 行内注释说明字段用途(`// 应用名`, `// 包名`) ### 网络请求 - 使用 OkHttp,异步调用 (`enqueue`) - JSON 请求体使用 `org.json.JSONObject` 手动构建 - MediaType 常量: `public static final MediaType JSON = MediaType.parse("application/json; charset=utf-8")` - 回调中通过 `NotificationActivity.sendMessage()` 反馈 UI ### 错误处理 - try/catch 包裹关键操作,catch 中使用 `e.printStackTrace()` 或 `Log.e(TAG, msg, e)` - 部分场景直接抛出 `RuntimeException`(如 JSONException) - null 检查使用 `TextUtils.isEmpty()` 或直接 `== null` 判断 - lint 配置: `abortOnError false`(lint 错误不阻塞构建) ### 注解使用 | 注解 | 用途 | |------|------| | `@Override` | 方法重写(必须标注) | | `@Nullable` / `@NonNull` | 参数和返回值空安全 | | `@SuppressLint` | 抑制特定 lint 警告(如 `"StaticFieldLeak"`, `"SimpleDateFormat"`) | | `@RequiresApi` | API 版本要求标注 | ### 注释风格 - 类级别使用 Javadoc `/** */` 风格,含 `@Author`、创建时间、用途 - 方法级别使用 `/** */` 或单行 `//` 注释 - 行内注释使用中文(项目主要面向中文开发者) - 代码注释中保留被注释掉的调试代码(`//LogUtils.i(...)`, `//notifyItemRangeChanged`) ### 数据持久化 - 使用 `SharedPreferences`,统一名称为 `"server"` - 通过 `App` 类的静态方法管理通知列表(`saveNotiList`, `getNotiList`, `saveNotiBean`, `deleteNotiBean`) - 列表数据序列化为 JSON 字符串存储 ## 注意事项 - **无 CI/CD 配置** — 无自动化构建流程 - **无代码格式化工具** — 无 .editorconfig、checkstyle、spotless 等配置 - **测试覆盖极低** — 仅有默认生成的示例测试,无业务逻辑测试 - **签名信息硬编码** — keystore 密码直接写在 build.gradle 中 - **ProGuard 未启用** — release 构建 `minifyEnabled false` - **仓库包含阿里云/华为镜像** — 构建时需要网络访问这些 Maven 仓库 - 修改代码时保持现有风格一致,即使风格不够规范 - 中文注释和 UI 字符串是项目惯例,新增代码保持一致