package com.morristaedt.mirror.modules; import android.content.Context; import android.content.res.Resources; import android.util.Log; import android.util.SparseArray; import com.google.android.gms.vision.CameraSource; import com.google.android.gms.vision.Detector; import com.google.android.gms.vision.face.Face; import com.google.android.gms.vision.face.FaceDetector; import com.morristaedt.mirror.R; import java.io.IOException; import java.lang.ref.WeakReference; /** * Created by akodiakson on 9/13/15. */ public class MoodModule { private static final String TAG = "MoodModule"; private WeakReference<Context> mContextWeakReference; private CameraSource mCameraSource = null; private MoodListener mCallBacks; public interface MoodListener { void onShouldGivePositiveAffirmation(String affirmation); } public MoodModule(WeakReference<Context> contextWeakReference) { mContextWeakReference = contextWeakReference; } public void getCurrentMood(MoodListener moodListener) { createCameraSource(); mCallBacks = moodListener; } public void release() { if (mCameraSource != null) { mCameraSource.release(); mCameraSource = null; } } /** * Creates and starts the camera. Note that this uses a higher resolution in comparison * to other detection examples to enable the barcode detector to detect small barcodes * at long distances. */ private void createCameraSource() { Context context = mContextWeakReference.get(); FaceDetector detector = new FaceDetector.Builder(context) .setClassificationType(FaceDetector.ALL_CLASSIFICATIONS) .build(); detector.setProcessor(new Detector.Processor<Face>() { @Override public void release() { } @Override public void receiveDetections(final Detector.Detections<Face> detections) { final SparseArray<Face> detectedItems = detections.getDetectedItems(); if (detectedItems.size() != 0) { final int key = detectedItems.keyAt(0); final Face face = detectedItems.get(key); final float isSmilingProbability = face.getIsSmilingProbability(); String feedback = getFeedbackForSmileProbability(isSmilingProbability); mCallBacks.onShouldGivePositiveAffirmation(feedback); } } }); if (!detector.isOperational()) { // Note: The first time that an app using face API is installed on a device, GMS will // download a native library to the device in order to do detection. Usually this // completes before the app is run for the first time. But if that download has not yet // completed, then the above call will not detect any faces. // // isOperational() can be used to check if the required native library is currently // available. The detector will automatically become operational once the library // download completes on device. Log.w(TAG, "Face detector dependencies are not yet available."); } try { mCameraSource = new CameraSource.Builder(context, detector) .setRequestedPreviewSize(640, 480) .setFacing(CameraSource.CAMERA_FACING_FRONT) .setRequestedFps(30.0f) .build(); mCameraSource.start(); } catch (IOException | RuntimeException e) { Log.e(TAG, "Something went horribly wrong, with your face.", e); } } private String getFeedbackForSmileProbability(float isSmilingProbability) { final boolean isSmiling = isSmilingProbability > 0.5f; final boolean aFaceIsntDetected = isSmilingProbability <= 0; String feedback; if (isSmiling || aFaceIsntDetected) { return null; } final Resources resources = mContextWeakReference.get().getResources(); if (isSmilingProbability < 0.15) { feedback = resources.getString(R.string.it_gets_better); } else if (isSmilingProbability < 0.30) { feedback = resources.getString(R.string.looking_good); } else { feedback = resources.getString(R.string.something_special); } return feedback; } }