On-device AI that detects fake and spoofed phone calls in real time. 100% offline — no data ever leaves your phone.
FakeCallShield is an Android application that detects fake, spoofed, and AI-generated phone calls entirely on-device. Rising phone scams exploit caller ID spoofing to impersonate trusted contacts, making it nearly impossible for users to distinguish real calls from fraudulent ones. FakeCallShield solves this by combining carrier-level verification with neural network voice analysis — all without any internet connection.
- Call Screening — Intercepts incoming calls via Android CallScreeningService and verifies caller identity through STIR/SHAKEN carrier-level attestation
- AI Voice Detection — Analyzes speech using a 104-feature neural network to classify audio as human or AI-generated in real time
- Contact Protection — Mark trusted contacts; get instant full-screen alerts when someone spoofs their number
- Live Analysis — Continuous voice analysis during active calls using a 3-second sliding window with rolling confidence
- Zero Network — No internet, no cloud, no analytics, no data collection. Ever.
The ML engine extracts 104 acoustic features from audio and feeds them into an on-device neural network:
| Feature Group | Count | Description |
|---|---|---|
| MFCC + Delta + Delta-Delta | 78 | Mel-frequency cepstral coefficients with velocity and acceleration |
| Spectral | 12 | Centroid, spread, flux, rolloff, ZCR, RMS (mean + std) |
| Pitch Jitter | 3 | Local jitter, RAP, PPQ5 — measures pitch irregularity |
| Amplitude Shimmer | 3 | Local shimmer, APQ3, APQ5 — measures amplitude perturbation |
| Harmonic-to-Noise Ratio | 1 | Ratio of harmonic to noise energy in speech |
| F0 Contour Statistics | 4 | Pitch range, variation, rate of change, dynamics |
| Phase Continuity | 2 | Inter-frame phase difference variance (vocoders disrupt this) |
| Spectral Smoothness | 1 | Spectral envelope regularity (TTS tends to be smoother) |
Why these features? Real human speech has natural irregularities — micro-variations in pitch (jitter), amplitude (shimmer), and breath noise that AI voice synthesis struggles to replicate perfectly. The model learns to detect these subtle differences.
Input (104 features)
|
Dense(256, ReLU)
|
Dense(128, ReLU)
|
Dense(64, ReLU)
|
Dense(1, Sigmoid) --> P(fake)
- Architecture: MLP with 104 → 256 → 128 → 64 → 1 neurons
- Trained with scikit-learn MLPClassifier on 10,000 samples
- Thresholds calibrated from ROC curve analysis (Youden's J statistic)
- No hardcoded detection values — every threshold comes from training data
- Android
CallScreeningServiceintercepts incoming calls at the OS level - Checks STIR/SHAKEN attestation (carrier-level caller verification)
- Matches caller ID against your trusted contacts list
- Multi-signal risk scoring: attestation (40%) + contact match (30%) + timing (15%) + voice ML (15%)
- Must respond within 5 seconds — all processing is local and fast
During active calls:
- Native
AudioRecordcaptures audio (tries VOICE_CALL → VOICE_DOWNLINK → MIC) - 3-second PCM chunks streamed to TypeScript via React Native bridge
- Feature extraction + inference runs on each chunk (~20ms)
- Rolling average across last 5 predictions for stable confidence
| Layer | Technology |
|---|---|
| App Framework | React Native 0.76 + Expo SDK 52 |
| Language (App) | TypeScript |
| Language (Native) | Kotlin |
| ML Inference | Pure TypeScript MLP (no TensorFlow/ONNX dependency) |
| ML Training | Python + scikit-learn |
| State Management | Zustand + AsyncStorage |
| Call Screening | Android CallScreeningService + STIR/SHAKEN |
| Audio Capture | Android AudioRecord (native module) |
| UI | Custom dark theme with animated components |
FakeCallShield/
├── app/ # Expo Router screens
│ ├── (tabs)/
│ │ ├── index.tsx # Detection + monitoring dashboard
│ │ ├── contacts.tsx # Trusted contacts management
│ │ ├── history.tsx # Scan history + call events
│ │ └── settings.tsx # App settings + call screening config
│ └── _layout.tsx # Root layout + event wiring
├── engine/ # Core ML + audio processing
│ ├── mfcc.ts # 104-feature extraction (TypeScript)
│ ├── inference.ts # MLP forward pass + feature-derived reasons
│ ├── pipeline.ts # Record → extract → classify pipeline
│ ├── streamingPipeline.ts # Real-time streaming analysis
│ ├── contacts.ts # Contact loading + phone number matching
│ ├── callScreening.ts # Native call screening bridge
│ └── riskScoring.ts # Multi-signal risk assessment
├── store/ # Zustand state stores
│ ├── settingsStore.ts
│ ├── contactsStore.ts
│ └── callEventsStore.ts
├── components/
│ └── SpoofAlert.tsx # Full-screen spoofed call warning
├── ml/ # Python ML training pipeline
│ ├── generate_data.py # Synthetic voice dataset generator
│ ├── preprocess.py # Audio normalization + trimming
│ ├── features.py # 104-feature extraction (Python)
│ ├── train.py # MLP training + ROC calibration
│ ├── eval.py # Evaluation + plots
│ ├── export_weights.py # Export to model_weights.json
│ ├── infer.py # Single-file inference
│ └── run_pipeline.py # Full pipeline orchestrator
├── android/ # Native Android code
│ └── app/src/main/java/com/fakecallshield/app/
│ ├── FakeCallScreeningService.kt # CallScreeningService
│ ├── CallScreeningModule.kt # RN bridge for screening
│ ├── AudioCaptureModule.kt # In-call audio capture
│ └── ...
├── assets/
│ └── model_weights.json # Trained model (weights + stats + calibration)
├── plugins/
│ └── withCallScreening.js # Expo config plugin
└── constants/
└── theme.ts # Dark UI theme
- Node.js 18+
- Python 3.10+ (for ML training)
- Android Studio with SDK 35
- Physical Android device (not emulator — needs real audio)
git clone git@github.com:theNeuralHorizon/FakeCallShield-.git
cd FakeCallShield-
npm installcd ml
pip install numpy scipy scikit-learn
python run_pipeline.py --n_real 5000 --n_fake 5000 --n_epochs 100This generates assets/model_weights.json with trained weights, feature statistics, and calibrated thresholds.
npx expo prebuild --clean
cd android
./gradlew assembleDebugOr open the android/ folder in Android Studio and click Run.
npx expo run:android| Permission | Purpose |
|---|---|
RECORD_AUDIO |
Voice recording for ML analysis |
READ_CONTACTS |
Identify trusted contacts for spoof detection |
READ_PHONE_STATE |
Call screening functionality |
READ_CALL_LOG |
Call history for pattern analysis |
VIBRATE |
Haptic alerts on fake call detection |
All permissions are used locally. No data is transmitted.
- Zero data collection — No audio, metadata, analytics, or usage data is ever transmitted
- Zero network requests — The app functions fully offline with no internet requirement
- Zero third-party services — No analytics, crash reporting, advertising, or cloud services
- Local storage only — Scan history stored via AsyncStorage on-device; deletable anytime
- Open source — Verify the privacy claims yourself by reading the code
Why TypeScript for ML inference instead of TensorFlow Lite? Eliminates a 5MB+ native dependency. The MLP forward pass is ~2ms in pure TypeScript — fast enough for real-time use. No JNI bridge overhead.
Why not use iOS CallKit? iOS CallKit only supports static blocklists via Call Directory Extension. It cannot dynamically screen calls or access caller details in real time. Android's CallScreeningService is fundamentally more capable for this use case.
Why synthetic training data? Real voice spoofing datasets (ASVspoof) require institutional access. The synthetic pipeline generates acoustically realistic samples with controlled jitter/shimmer/HNR distributions that model the statistical differences between human and TTS speech. The architecture supports swapping in real datasets when available.
Why 104 features instead of raw audio / deep learning? Hand-crafted features (jitter, shimmer, HNR) capture the exact acoustic properties that differentiate human from synthetic speech. They're interpretable (the app can explain why it flagged a call), lightweight (no GPU needed), and fast enough for the 5-second Android call screening timeout.
MIT
Built for the purpose of protecting users from phone scams while preserving complete privacy.