Files
Kordant/tasks/shieldai-unified-restructure/39-android-native-features.md
2026-05-25 12:23:23 -04:00

136 lines
7.4 KiB
Markdown

# 39. Android App — Push Notifications, Biometrics, Voice Enrollment, Call Screening
meta:
id: shieldai-unified-restructure-39
feature: shieldai-unified-restructure
priority: P1
depends_on: [shieldai-unified-restructure-34, shieldai-unified-restructure-35, shieldai-unified-restructure-36, shieldai-unified-restructure-37, shieldai-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/shieldai/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/shieldai/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/shieldai/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/shieldai/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/shieldai/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.