diff --git a/AGENTS.md b/AGENTS.md new file mode 100644 index 0000000..aded2f6 --- /dev/null +++ b/AGENTS.md @@ -0,0 +1,171 @@ +# 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 字符串是项目惯例,新增代码保持一致 diff --git a/app/release/baselineProfiles/0/app-release.dm b/app/release/baselineProfiles/0/app-release.dm new file mode 100644 index 0000000..86241b7 Binary files /dev/null and b/app/release/baselineProfiles/0/app-release.dm differ diff --git a/app/release/baselineProfiles/1/app-release.dm b/app/release/baselineProfiles/1/app-release.dm new file mode 100644 index 0000000..d8297f1 Binary files /dev/null and b/app/release/baselineProfiles/1/app-release.dm differ diff --git a/app/release/noti-msg.apk b/app/release/noti-msg.apk new file mode 100644 index 0000000..fe79c6b Binary files /dev/null and b/app/release/noti-msg.apk differ diff --git a/app/release/output-metadata.json b/app/release/output-metadata.json index 315e395..e0d9a0b 100644 --- a/app/release/output-metadata.json +++ b/app/release/output-metadata.json @@ -11,10 +11,27 @@ "type": "SINGLE", "filters": [], "attributes": [], - "versionCode": 11, - "versionName": "2.1", + "versionCode": 12, + "versionName": "2.2", "outputFile": "app-release.apk" } ], - "elementType": "File" + "elementType": "File", + "baselineProfiles": [ + { + "minApi": 28, + "maxApi": 30, + "baselineProfiles": [ + "baselineProfiles/1/app-release.dm" + ] + }, + { + "minApi": 31, + "maxApi": 2147483647, + "baselineProfiles": [ + "baselineProfiles/0/app-release.dm" + ] + } + ], + "minSdkVersionForDexing": 24 } \ No newline at end of file diff --git a/wzq.jks b/wzq.jks new file mode 100644 index 0000000..c50b165 Binary files /dev/null and b/wzq.jks differ