136 lines
7.4 KiB
Markdown
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.
|