Making an Eye Tracker app in Android

Photo by Marina Vitale on Unsplash
dependencies { //other dependencies 
implementation ‘com.google.android.gms:play-services:12.0.1’
...
}
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.INTERNET"/>
<?xml version="1.0" encoding="utf-8"?><androidx.constraintlayout.widget.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/background"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity"
android:background="#777">

<TextView
android:id="@+id/user_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Hello World!"
android:textSize="18sp"
android:textColor="#fff"
android:textStyle="bold"
android:textAlignment="center"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
public enum Condition {
USER_EYES_OPEN, USER_EYES_CLOSED, FACE_NOT_FOUND
}
public class EyesTracker extends Tracker<Face> {
private final float THRESHOLD = 0.75f;
private Context context;
public EyesTracker(Context context) {
this.context = context;
}
@Override
public void onUpdate(Detector.Detections<Face> detections, Face face) {
if (face.getIsLeftEyeOpenProbability() > THRESHOLD || face.getIsRightEyeOpenProbability() > THRESHOLD) { Log.i(TAG, "onUpdate: Open Eyes Detected");
((MainActivity)context).updateMainView(Condition.USER_EYES_OPEN);

}else {
Log.i(TAG, "onUpdate: Close Eyes Detected"); ((MainActivity)context).updateMainView(Condition.USER_EYES_CLOSED);
}
}
@Override
public void onMissing(Detector.Detections<Face> detections) {
super.onMissing(detections);
Log.i(TAG, "onUpdate: Face Not Detected yet!");
((MainActivity)context).updateMainView(Condition.FACE_NOT_FOUND); } @Override
public void onDone() {
super.onDone();
}
}
public class FaceTrackerDaemon implements MultiProcessor.Factory<Face> {
private Context context;
public FaceTrackerDaemon(Context context) {
this.context = context;
}
@Override
public Tracker<Face> create(Face face) {
return new EyesTracker(context);
}
}
public class MainActivity extends AppCompatActivity {

ConstraintLayout background;
TextView user_message;

boolean flag = false;
CameraSource cameraSource;

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

if (ActivityCompat.checkSelfPermission(this, android.Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.CAMERA}, 1);
Toast.makeText(this, "Permission not granted!\n Grant permission and restart app", Toast.LENGTH_SHORT).show();
}else{
init();
}
}

private void init() {
background = findViewById(R.id.background);
user_message = findViewById(R.id.user_text);
flag = true;

initCameraSource();
}

//method to create camera source from faceFactoryDaemon class
private void
initCameraSource() {
FaceDetector detector = new FaceDetector.Builder(this)
.setTrackingEnabled(true)
.setClassificationType(FaceDetector.ALL_CLASSIFICATIONS)
.setMode(FaceDetector.FAST_MODE)
.build();
detector.setProcessor(new MultiProcessor.Builder(new FaceTrackerDaemon(MainActivity.this)).build());

cameraSource = new CameraSource.Builder(this, detector)
.setRequestedPreviewSize(1024, 768)
.setFacing(CameraSource.CAMERA_FACING_FRONT)
.setRequestedFps(30.0f)
.build();

try {
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) {
// TODO: Consider calling
// ActivityCompat#requestPermissions
// here to request the missing permissions, and then overriding
// public void onRequestPermissionsResult(int requestCode, String[] permissions,
// int[] grantResults)
// to handle the case where the user grants the permission. See the documentation
// for ActivityCompat#requestPermissions for more details.
return
;
}
cameraSource.start();
}
catch (IOException e) {
Toast.makeText(MainActivity.this, e.getMessage(), Toast.LENGTH_SHORT).show();
e.printStackTrace();
}
}

@Override
protected void onResume() {
super.onResume();
if (cameraSource != null) {
try {
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) {
// TODO: Consider calling
// ActivityCompat#requestPermissions
// here to request the missing permissions, and then overriding
// public void onRequestPermissionsResult(int requestCode, String[] permissions,
// int[] grantResults)
// to handle the case where the user grants the permission. See the documentation
// for ActivityCompat#requestPermissions for more details.
return
;
}
cameraSource.start();
}
catch (IOException e) {
e.printStackTrace();
}
}
}

@Override
protected void onPause() {
super.onPause();
if (cameraSource!=null) {
cameraSource.stop();
}

setBackgroundGrey();
}

@Override
protected void onDestroy() {
super.onDestroy();
if (cameraSource!=null) {
cameraSource.release();
}
}

//update view
public void
updateMainView(Condition condition){
switch (condition){
case USER_EYES_OPEN:
setBackgroundGreen();
user_message.setText("Open eyes detected");
break;
case USER_EYES_CLOSED:
setBackgroundOrange();
user_message.setText("Close eyes detected");
break;
case FACE_NOT_FOUND:
setBackgroundRed();
user_message.setText("User not found");
break;
default:
setBackgroundGrey();
user_message.setText("Hello World");
}
}

//set background Grey
private void
setBackgroundGrey() {
if(background != null)
background.setBackgroundColor(getResources().getColor(android.R.color.darker_gray));
}

//set background Green
private void
setBackgroundGreen() {
if(background != null){
runOnUiThread(new Runnable() {
@Override
public void run() {
background.setBackgroundColor(getResources().getColor(android.R.color.holo_green_dark));
}
});
}
}

//set background Orange
private void
setBackgroundOrange() {
if(background != null){
runOnUiThread(new Runnable() {
@Override
public void run() {
background.setBackgroundColor(getResources().getColor(android.R.color.holo_orange_dark));
}
});
}
}

//set background Red
private void
setBackgroundRed() {
if(background != null){
runOnUiThread(new Runnable() {
@Override
public void run() {
background.setBackgroundColor(getResources().getColor(android.R.color.holo_red_dark));
}
});
}
}
}

Founder at Inside Android | Youtuber | App Developer