Building a Face Recognition App in Android (Java)

Building a Face Recognition App in Android (Java)

This guide walks you through creating a real-time face recognition Android app using Java, CameraX, and ML Kit (Google’s on-device machine learning SDK). No server needed—everything runs locally!


1. Prerequisites

  • Android Studio (latest version)
  • Android device/emulator (API 21+)
  • Basic Java/Android knowledge

2. Setup Dependencies

Add to app/build.gradle:

gradle

dependencies {
    // CameraX
    implementation "androidx.camera:camera-core:1.3.0"
    implementation "androidx.camera:camera-camera2:1.3.0"
    implementation "androidx.camera:camera-lifecycle:1.3.0"
    implementation "androidx.camera:camera-view:1.3.0"

    // ML Kit Face Detection
    implementation 'com.google.mlkit:face-detection:16.1.5'

    // For drawing face contours
    implementation 'com.github.duanhong169:drawabletoolbox:1.0.7'
}

Sync Gradle.


3. AndroidManifest.xml Permissions

xml

Run

<uses-permission android:name="android.permission.CAMERA" />
<uses-feature android:name="android.hardware.camera" />
<uses-feature android:name="android.hardware.camera.autofocus" />

4. MainActivity.java

Step 1: Initialize CameraX + Face Detector

java

import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.camera.core.*;
import androidx.camera.lifecycle.ProcessCameraProvider;
import androidx.core.content.ContextCompat;
import com.google.common.util.concurrent.ListenableFuture;
import com.google.mlkit.vision.common.InputImage;
import com.google.mlkit.vision.face.Face;
import com.google.mlkit.vision.face.FaceDetection;
import com.google.mlkit.vision.face.FaceDetector;
import com.google.mlkit.vision.face.FaceDetectorOptions;
import java.util.concurrent.ExecutionException;

public class MainActivity extends AppCompatActivity {
    private ListenableFuture<ProcessCameraProvider> cameraProviderFuture;
    private PreviewView previewView;
    private FaceDetector detector;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        previewView = findViewById(R.id.previewView);

        // High-accuracy face detection settings
        FaceDetectorOptions options = new FaceDetectorOptions.Builder()
            .setPerformanceMode(FaceDetectorOptions.PERFORMANCE_MODE_ACCURATE)
            .setContourMode(FaceDetectorOptions.CONTOUR_MODE_ALL)
            .build();

        detector = FaceDetection.getClient(options);
        startCamera();
    }

    private void startCamera() {
        cameraProviderFuture = ProcessCameraProvider.getInstance(this);
        cameraProviderFuture.addListener(() -> {
            try {
                ProcessCameraProvider provider = cameraProviderFuture.get();
                bindPreview(provider);
            } catch (ExecutionException | InterruptedException e) {
                e.printStackTrace();
            }
        }, ContextCompat.getMainExecutor(this));
    }

Step 2: Bind Camera Preview + Face Analysis

java

private void bindPreview(@NonNull ProcessCameraProvider provider) {
    Preview preview = new Preview.Builder().build();
    CameraSelector selector = new CameraSelector.Builder()
        .requireLensFacing(CameraSelector.LENS_FACING_FRONT)
        .build();

    ImageAnalysis analysis = new ImageAnalysis.Builder()
        .setBackpressureStrategy(ImageAnalysis.STRATEGY_KEEP_ONLY_LATEST)
        .build();

    analysis.setAnalyzer(ContextCompat.getMainExecutor(this), imageProxy -> {
        @SuppressLint("UnsafeOptInUsageError")
        Image mediaImage = imageProxy.getImage();
        if (mediaImage != null) {
            InputImage image = InputImage.fromMediaImage(mediaImage, imageProxy.getImageInfo().getRotationDegrees());
            detector.process(image)
                .addOnSuccessListener(faces -> {
                    for (Face face : faces) {
                        // Draw face bounding box (see Step 3)
                        Log.d("FaceRecognition", "Face detected! ID: " + face.getTrackingId());
                    }
                })
                .addOnFailureListener(e -> Log.e("FaceRecognition", "Detection failed", e))
                .addOnCompleteListener(task -> imageProxy.close());
        }
    });

    provider.unbindAll();
    provider.bindToLifecycle(this, selector, preview, analysis);
    preview.setSurfaceProvider(previewView.getSurfaceProvider());
}

5. Face Contour Drawing (Custom View)

Create FaceContourView.java:

java

import android.content.Context;
import android.graphics.*;
import android.util.AttributeSet;
import android.view.View;
import com.google.mlkit.vision.face.Face;
import java.util.List;

public class FaceContourView extends View {
    private Paint paint;
    private List<Face> faces;

    public FaceContourView(Context context, AttributeSet attrs) {
        super(context, attrs);
        paint = new Paint();
        paint.setColor(Color.GREEN);
        paint.setStyle(Paint.Style.STROKE);
        paint.setStrokeWidth(5f);
    }

    public void setFaces(List<Face> faces) {
        this.faces = faces;
        invalidate(); // Redraw
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        if (faces != null) {
            for (Face face : faces) {
                RectF bounds = new RectF(face.getBoundingBox());
                canvas.drawRect(bounds, paint);
            }
        }
    }
}

Add to activity_main.xml:

xml

Run

<com.yourpackage.FaceContourView
    android:id="@+id/faceOverlay"
    android:layout_width="match_parent"
    android:layout_height="match_parent" />

6. Update MainActivity for Drawing

java

Copy

Download

// Add to MainActivity fields
private FaceContourView faceOverlay;

// In onCreate()
faceOverlay = findViewById(R.id.faceOverlay);

// Inside onSuccessListener in bindPreview()
faceOverlay.setFaces(faces);

7. Run the App

  1. Connect an Android device (or use emulator with camera support).
  2. Click Run in Android Studio.
  3. Grant camera permissions when prompted.

8. Enhancements

  • Face Recognition (Not Just Detection):
    • Use TensorFlow Lite with a pre-trained model (e.g., FaceNet).
    • Compare face embeddings against a database.
  • Save Recognized Faces:
    • Store facial features in Room Database.
  • Add User Feedback:
    • Show names when a known face is detected.

9. Key Takeaways

✅ Uses ML Kit for real-time face detection (no internet needed).
✅ CameraX for modern camera handling.
✅ Custom view to draw face bounding boxes.