rebranding
This commit is contained in:
135
tasks/kordant-unified-restructure/39-android-native-features.md
Normal file
135
tasks/kordant-unified-restructure/39-android-native-features.md
Normal file
@@ -0,0 +1,135 @@
|
||||
# 39. Android App — Push Notifications, Biometrics, Voice Enrollment, Call Screening
|
||||
|
||||
meta:
|
||||
id: kordant-unified-restructure-39
|
||||
feature: kordant-unified-restructure
|
||||
priority: P1
|
||||
depends_on: [kordant-unified-restructure-34, kordant-unified-restructure-35, kordant-unified-restructure-36, kordant-unified-restructure-37, kordant-unified-restructure-38]
|
||||
tags: [android, jetpack-compose, native-features, push, biometrics, call-screening, mobile]
|
||||
|
||||
objective:
|
||||
- Implement native Android features that differentiate the mobile experience: push notifications via FCM, biometric authentication, voice enrollment with audio recording, and call screening integration for SpamShield.
|
||||
|
||||
deliverables:
|
||||
- `android/app/src/main/java/com/kordant/android/service/FCMService.kt` — Firebase Cloud Messaging:
|
||||
- Extends `FirebaseMessagingService`
|
||||
- `onMessageReceived` — processes incoming notifications
|
||||
- `onNewToken` — sends token to backend (task 14)
|
||||
- Creates notification channels for different alert types
|
||||
- Rich notifications with images and actions
|
||||
- Deep links to relevant screens based on payload
|
||||
- `android/app/src/main/java/com/kordant/android/ui/screens/auth/BiometricAuthScreen.kt` — Biometric prompt:
|
||||
- Uses `BiometricPrompt` from `androidx.biometric:biometric`
|
||||
- Face/fingerprint authentication
|
||||
- Fallback to device PIN/pattern/password
|
||||
- Stores credential in `EncryptedSharedPreferences`
|
||||
- `android/app/src/main/java/com/kordant/android/ui/screens/voiceprint/RecordingScreen.kt` — Voice recording:
|
||||
- Real-time waveform visualization using `AudioRecord` + `Canvas`
|
||||
- Record / stop / playback controls
|
||||
- Duration timer
|
||||
- Quality check (minimum duration, amplitude threshold)
|
||||
- Submit enrollment to API
|
||||
- `android/app/src/main/java/com/kordant/android/service/CallScreeningService.kt` — Call screening:
|
||||
- Extends `CallScreeningService` (API 29+)
|
||||
- Intercepts incoming calls
|
||||
- Queries `spamshield.checkNumber` via API
|
||||
- Displays caller info overlay with reputation score
|
||||
- Auto-blocks known spam numbers based on user rules
|
||||
- Logs screened calls for history
|
||||
- `android/app/src/main/java/com/kordant/android/util/PermissionManager.kt` — Permission handling:
|
||||
- Centralized manager for all runtime permissions
|
||||
- Camera, microphone, phone, notifications, call screening
|
||||
- Handles permission rationale and denied states
|
||||
- `android/app/src/main/AndroidManifest.xml` — Updated permissions and services:
|
||||
- `INTERNET`, `RECORD_AUDIO`, `READ_PHONE_STATE`, `CALL_PHONE`
|
||||
- `BIND_CALL_SCREENING_SERVICE`
|
||||
- `RECEIVE_BOOT_COMPLETED` (for starting services)
|
||||
- FCM service declaration
|
||||
- Call screening service declaration
|
||||
|
||||
steps:
|
||||
1. **Push Notifications (FCM)**:
|
||||
- Add `google-services.json` to `app/` directory
|
||||
- Add `com.google.gms:google-services` plugin to build.gradle
|
||||
- Create `FCMService.kt` extending `FirebaseMessagingService`
|
||||
- `onNewToken`: send to backend via `api.notification.registerDevice`
|
||||
- `onMessageReceived`:
|
||||
- Parse notification payload
|
||||
- Create notification channel if not exists (Android 8+)
|
||||
- Show notification with `NotificationManager`
|
||||
- Handle data messages (silent pushes) for background sync
|
||||
- Add `FirebaseMessaging.getInstance().subscribeToTopic("alerts")` for broadcast alerts
|
||||
- Handle notification tap: extract `screen` and `id`, navigate via deep link
|
||||
2. **Biometric Auth**:
|
||||
- `BiometricPrompt` with `BiometricPrompt.PromptInfo`
|
||||
- `setDeviceCredentialAllowed(true)` for fallback
|
||||
- `setConfirmationRequired(false)` for faster auth
|
||||
- On success: unlock `EncryptedSharedPreferences`
|
||||
- Show prompt on app launch if biometric is enabled
|
||||
3. **Voice Recording**:
|
||||
- Request `RECORD_AUDIO` permission at runtime
|
||||
- `AudioRecord` with `MediaRecorder.AudioSource.MIC`
|
||||
- Configuration: 16kHz, mono, 16-bit PCM
|
||||
- Real-time waveform: read amplitude in a coroutine, update `Canvas` path
|
||||
- Minimum duration: 5 seconds
|
||||
- Save as WAV file
|
||||
- Playback with `MediaPlayer`
|
||||
- Submit to API via multipart upload
|
||||
4. **Call Screening**:
|
||||
- Extend `CallScreeningService`
|
||||
- `onScreenCall(details)` callback when incoming call arrives
|
||||
- Extract phone number from `Call.Details`
|
||||
- Query API: `spamshield.checkNumber` (use cached result if available)
|
||||
- `respondToCall` with `CallResponse.Builder`:
|
||||
- If spam: `setDisallowCall(true)`, `setRejectCall(true)`, `setSkipCallLog(false)`
|
||||
- If suspicious: `setDisallowCall(false)` but show warning notification
|
||||
- If clean: `setDisallowCall(false)`
|
||||
- Show custom incoming call UI overlay (optional, requires additional permissions)
|
||||
- Log all screened calls to local DB
|
||||
5. **Permission Manager**:
|
||||
- `checkPermission(permission)` → boolean
|
||||
- `requestPermission(permission, rationale)` → shows dialog, then system prompt
|
||||
- `handlePermissionResult(requestCode, permissions, grantResults)`
|
||||
- Guides user to Settings if permission permanently denied
|
||||
6. Update manifest:
|
||||
- Add all required permissions
|
||||
- Declare FCM service with `android:exported="false"`
|
||||
- Declare call screening service with `android:permission="android.permission.BIND_CALL_SCREENING_SERVICE"`
|
||||
7. Test on physical device (emulator cannot test FCM, biometrics, or call screening accurately).
|
||||
|
||||
steps:
|
||||
- Unit: FCMService parses notification payload correctly
|
||||
- Unit: BiometricPrompt configuration is valid
|
||||
- Unit: PermissionManager returns correct status for each permission
|
||||
- Integration: FCM token registration sends correct data to backend
|
||||
- E2E: Receive test push notification and verify deep link navigation
|
||||
- E2E: Record voice sample and submit enrollment successfully
|
||||
- E2E: Simulate incoming call and verify screening logic
|
||||
|
||||
acceptance_criteria:
|
||||
- [ ] App registers for FCM and sends device token to backend
|
||||
- [ ] Incoming push notifications display correctly with channels and actions
|
||||
- [ ] Tapping a notification deep links to the correct screen
|
||||
- [ ] Face/fingerprint authentication works for app unlock
|
||||
- [ ] Voice recording captures audio, shows waveform, and submits enrollment
|
||||
- [ ] Call screening intercepts incoming calls and blocks known spam
|
||||
- [ ] All permission requests include explanatory rationale
|
||||
- [ ] Denied permissions show helpful guidance to Settings app
|
||||
- [ ] Native features work on phones with API 26+
|
||||
|
||||
validation:
|
||||
- Test push notifications using Firebase Console
|
||||
- Verify biometric auth on device with face/fingerprint sensor
|
||||
- Record a 10-second voice sample and verify enrollment created in backend
|
||||
- Simulate incoming call using `adb shell am start -a android.intent.action.CALL -d tel:1234567890`
|
||||
- Run `./gradlew test` for unit tests
|
||||
|
||||
notes:
|
||||
- FCM requires a `google-services.json` file from Firebase Console. Add setup instructions to README.
|
||||
- Call screening (`CallScreeningService`) is only available on Android 10+ (API 29+). For older versions, use a broadcast receiver for `PHONE_STATE` changes as fallback.
|
||||
- The call screening service runs in the background and must be lightweight. Offload API calls to a coroutine.
|
||||
- For call screening UI, the system provides a default incoming call screen. Custom UI overlays require `SYSTEM_ALERT_WINDOW` permission and are complex to implement correctly.
|
||||
- Voice recording quality matters for ML model accuracy. Use 16kHz mono WAV — this matches the web app's preprocessing pipeline.
|
||||
- Biometric auth should be optional. Users can always use password login.
|
||||
- Consider adding a Quick Settings tile for toggling call screening on/off.
|
||||
- For Android 14+ (API 34+), use the new `android.telecom.Call Screening` APIs if available.
|
||||
Reference in New Issue
Block a user