Skip to content
This repository was archived by the owner on Sep 13, 2024. It is now read-only.

Commit 5475771

Browse files
Merge pull request #29 from coderbunker/issue#27-eye_tracking
Issue#27 eye tracking
2 parents fafeb0e + 0ef19c9 commit 5475771

File tree

9 files changed

+310
-53
lines changed

9 files changed

+310
-53
lines changed

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,3 +8,5 @@
88
/build
99
/captures
1010
.externalNativeBuild
11+
.idea/caches/build_file_checksums.ser
12+
.idea/caches/build_file_checksums.ser

app/build.gradle

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ dependencies {
2424
implementation 'com.android.support.constraint:constraint-layout:1.1.2'
2525
implementation 'com.android.support:support-v4:27.1.1'
2626
implementation 'com.journeyapps:zxing-android-embedded:3.6.0'
27+
implementation 'gun0912.ted:tedpermission:2.2.0'
2728
testImplementation 'junit:junit:4.12'
2829
androidTestImplementation 'com.android.support.test:runner:1.0.2'
2930
androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'

app/src/main/AndroidManifest.xml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,13 @@
66
<uses-permission android:name="android.permission.INTERNET" />
77
<uses-permission android:name="android.permission.REORDER_TASKS" />
88
<uses-permission android:name="android.permission.CAMERA" />
9+
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
10+
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
11+
12+
<uses-feature
13+
android:name="android.hardware.camera"
14+
android:required="false" />
15+
<uses-feature android:name="android.hardware.camera.autofocus" />
916

1017
<application
1118
android:allowBackup="false"

app/src/main/java/com/coderbunker/kioskapp/KioskActivity.java

Lines changed: 70 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package com.coderbunker.kioskapp;
22

3+
import android.Manifest;
34
import android.app.Activity;
45
import android.app.Dialog;
56
import android.content.Context;
@@ -11,12 +12,15 @@
1112
import android.hardware.Camera;
1213
import android.net.http.SslError;
1314
import android.os.Bundle;
15+
import android.support.annotation.Nullable;
1416
import android.view.KeyEvent;
1517
import android.view.MotionEvent;
1618
import android.view.View;
1719
import android.view.Window;
1820
import android.view.WindowManager;
1921
import android.webkit.SslErrorHandler;
22+
import android.webkit.WebResourceRequest;
23+
import android.webkit.WebResourceResponse;
2024
import android.webkit.WebSettings;
2125
import android.webkit.WebView;
2226
import android.webkit.WebViewClient;
@@ -28,7 +32,11 @@
2832
import com.coderbunker.kioskapp.facerecognition.CameraPreview;
2933
import com.coderbunker.kioskapp.facerecognition.FaceDetectionListener;
3034
import com.coderbunker.kioskapp.lib.HOTP;
35+
import com.coderbunker.kioskapp.lib.SaveAndLoad;
3136
import com.coderbunker.kioskapp.lib.TOTP;
37+
import com.coderbunker.kioskapp.lib.URLRequest;
38+
import com.gun0912.tedpermission.PermissionListener;
39+
import com.gun0912.tedpermission.TedPermission;
3240

3341
import java.util.ArrayList;
3442
import java.util.Arrays;
@@ -45,7 +53,7 @@ public class KioskActivity extends Activity implements Observer {
4553
private WebView webView;
4654
private TextView face_detection_score, face_counter_view;
4755
private static String password = "1234";
48-
private static String URL = "";
56+
private static String url = "";
4957

5058
private final List blockedKeys = new ArrayList(Arrays.asList(KeyEvent.KEYCODE_VOLUME_DOWN,
5159
KeyEvent.KEYCODE_VOLUME_UP, KeyEvent.KEYCODE_BACK, KeyEvent.KEYCODE_HOME, KeyEvent.KEYCODE_POWER, KeyEvent.KEYCODE_APP_SWITCH));
@@ -68,6 +76,8 @@ public class KioskActivity extends Activity implements Observer {
6876
private Camera mCamera;
6977
private CameraPreview mCameraPreview;
7078

79+
private boolean enableCaching = false;
80+
7181
@Override
7282
public void onBackPressed() {
7383
//Do nothing...
@@ -93,7 +103,7 @@ protected void onCreate(Bundle savedInstanceState) {
93103
prefs = this.getSharedPreferences(
94104
"com.coderbunker.kioskapp", Context.MODE_PRIVATE);
95105

96-
URL = prefs.getString("url", "https://coderbunker.github.io/kiosk-web/");
106+
url = prefs.getString("url", "https://coderbunker.github.io/kiosk-web/");
97107
String otp = prefs.getString("otp", null);
98108

99109
if (otp == null) {
@@ -127,6 +137,26 @@ public void run() {
127137
timerLock.schedule(lock, 5000);
128138
}
129139

140+
@Nullable
141+
@Override
142+
public WebResourceResponse shouldInterceptRequest(WebView view, WebResourceRequest request) {
143+
System.out.println("Test: " + request.getUrl().toString());
144+
145+
if (enableCaching) {
146+
if (request.getUrl().toString().contains(".mp4") || request.getUrl().toString().contains(".wav")) {
147+
String[] url_parts = request.getUrl().toString().split("/");
148+
String file_name = url_parts[url_parts.length - 1];
149+
150+
if (SaveAndLoad.readFromFile(file_name, KioskActivity.this).equals("")) {
151+
URLRequest.startDownload(request.getUrl().toString(), file_name);
152+
}
153+
return new WebResourceResponse(SaveAndLoad.getMimeType(request.getUrl().toString()), "UTF-8", SaveAndLoad.readFromFileAndReturnInputStream(file_name, KioskActivity.this));
154+
155+
}
156+
}
157+
return super.shouldInterceptRequest(view, request);
158+
}
159+
130160
@Override
131161
public boolean shouldOverrideUrlLoading(WebView view, String url) {
132162
if (url.contains(url)) {
@@ -141,14 +171,15 @@ public void onReceivedSslError(WebView view, SslErrorHandler handler, SslError e
141171
handler.proceed(); //Ignore SSL certificate error
142172
}
143173
});
174+
144175
webView.getSettings().setJavaScriptEnabled(true);
145176
webView.getSettings().setAppCacheEnabled(true);
146-
webView.getSettings().setAppCacheMaxSize(5000 * 1000 * 1000);
147-
webView.getSettings().setCacheMode(WebSettings.LOAD_CACHE_ELSE_NETWORK);
177+
webView.getSettings().setAppCacheMaxSize(200 * 1024 * 1024);
178+
webView.getSettings().setCacheMode(WebSettings.LOAD_DEFAULT);
148179
webView.getSettings().setMediaPlaybackRequiresUserGesture(false);
149-
webView.loadUrl(URL);
180+
webView.loadUrl(url);
150181

151-
Toast.makeText(this, "Loading " + URL, Toast.LENGTH_SHORT).show();
182+
Toast.makeText(this, "Loading " + url, Toast.LENGTH_SHORT).show();
152183

153184
//Touch events for password
154185
webView.setOnClickListener(new View.OnClickListener() {
@@ -207,22 +238,41 @@ public void run() {
207238

208239

209240
if (checkCameraHardware(this)) {
210-
mCamera = getCameraInstance();
211-
if (mCamera != null) {
212241

213-
FaceDetectionListener faceDetectionListener = new FaceDetectionListener();
214-
faceDetectionListener.addObserver(this);
215-
mCamera.setFaceDetectionListener(faceDetectionListener);
242+
PermissionListener permissionlistener = new PermissionListener() {
243+
@Override
244+
public void onPermissionGranted() {
245+
try {
246+
mCamera.unlock();
247+
} catch (Exception e) {
216248

217-
mCameraPreview = new CameraPreview(this, mCamera);
249+
}
250+
mCamera = getCameraInstance();
251+
if (mCamera != null) {
252+
FaceDetectionListener faceDetectionListener = new FaceDetectionListener();
253+
faceDetectionListener.addObserver(KioskActivity.this);
254+
mCamera.setFaceDetectionListener(faceDetectionListener);
218255

219-
FrameLayout preview = findViewById(R.id.camera_preview);
220-
preview.addView(mCameraPreview);
256+
mCameraPreview = new CameraPreview(context, mCamera);
221257

222-
mCamera.startPreview();
223-
} else {
258+
FrameLayout preview = findViewById(R.id.camera_preview);
259+
preview.addView(mCameraPreview);
224260

225-
}
261+
mCamera.startPreview();
262+
Toast.makeText(context, "Face recognition started", Toast.LENGTH_LONG).show();
263+
} else {
264+
Toast.makeText(context, "Due a camera issue the face recognition can not be started.", Toast.LENGTH_LONG).show();
265+
}
266+
}
267+
268+
@Override
269+
public void onPermissionDenied(ArrayList<String> deniedPermissions) {
270+
Toast.makeText(context, "Face recognition not active due denied permissions.", Toast.LENGTH_SHORT).show();
271+
}
272+
273+
};
274+
275+
TedPermission.with(context).setPermissionListener(permissionlistener).setPermissions(Manifest.permission.CAMERA).check();
226276
}
227277

228278

@@ -465,31 +515,12 @@ protected void onPause() {
465515
super.onPause();
466516
}
467517

468-
private long last_detected = 0;
469-
private long face_current_counter = 0;
470-
private long face_counter = 0;
471-
472518
@Override
473519
public void update(Observable o, Object arg) {
474520
if (o instanceof FaceDetectionListener) {
475-
Camera.Face face = ((Camera.Face) arg);
476-
477-
face_detection_score.setText("Score:" + face.score);
478-
479-
if (face.score >= 85) {
480-
face_current_counter++;
481-
} else {
482-
face_current_counter = 0;
483-
}
484-
485-
if (face_current_counter >= 5 && last_detected < System.currentTimeMillis() + 45000) {
486-
face_counter++;
487-
last_detected = System.currentTimeMillis();
488-
face_current_counter = -5000;
489-
}
490-
491-
face_counter_view.setText("Viewers: " + face_counter);
492-
521+
Camera.Face[] faces = ((Camera.Face[]) arg);
522+
//face_detection_score.setText("Faces:" + faces.length);
523+
face_counter_view.setText("Current faces: " + faces.length);
493524
}
494525
}
495526
}

app/src/main/java/com/coderbunker/kioskapp/facerecognition/CameraPreview.java

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,11 @@ public void startFaceDetection() {
8080
// start face detection only *after* preview has started
8181
if (params.getMaxNumDetectedFaces() > 0) {
8282
// camera supports face detection, so can start it:
83-
mCamera.startFaceDetection();
83+
try {
84+
mCamera.startFaceDetection();
85+
} catch (RuntimeException ex) {
86+
System.out.println("Face recognition not started");
87+
}
8488
}
8589
}
8690
}

app/src/main/java/com/coderbunker/kioskapp/facerecognition/FaceDetectionListener.java

Lines changed: 3 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -8,17 +8,8 @@ public class FaceDetectionListener extends Observable implements Camera.FaceDete
88

99
@Override
1010
public void onFaceDetection(Camera.Face[] faces, Camera camera) {
11-
if (faces.length > 0) {
12-
for (Camera.Face face : faces) {
13-
try {
14-
/*System.out.println("--------------------------");
15-
System.out.println(face.score);*/
16-
setChanged();
17-
notifyObservers(face);
18-
} catch (Exception e) {
19-
e.printStackTrace();
20-
}
21-
}
22-
}
11+
setChanged();
12+
notifyObservers(faces);
2313
}
14+
2415
}
Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
package com.coderbunker.kioskapp.lib;
2+
3+
import android.content.Context;
4+
import android.util.Log;
5+
import android.webkit.MimeTypeMap;
6+
7+
import java.io.BufferedReader;
8+
import java.io.FileNotFoundException;
9+
import java.io.FileOutputStream;
10+
import java.io.IOException;
11+
import java.io.InputStream;
12+
import java.io.InputStreamReader;
13+
import java.io.OutputStreamWriter;
14+
15+
public class SaveAndLoad {
16+
//Source: https://stackoverflow.com/questions/14376807/how-to-read-write-string-from-a-file-in-android
17+
18+
public static void writeToFile(String filename, String data, Context ctx) {
19+
try {
20+
FileOutputStream fou = ctx.openFileOutput(filename, Context.MODE_PRIVATE);
21+
OutputStreamWriter osw = new OutputStreamWriter(fou);
22+
try {
23+
osw.write(data);
24+
osw.flush();
25+
osw.close();
26+
} catch (IOException e) {
27+
e.printStackTrace();
28+
}
29+
} catch (FileNotFoundException e) {
30+
e.printStackTrace();
31+
}
32+
}
33+
34+
public static String readFromFile(String filename, Context context) {
35+
36+
String ret = "";
37+
38+
try {
39+
InputStream inputStream = context.openFileInput(filename);
40+
41+
if (inputStream != null) {
42+
InputStreamReader inputStreamReader = new InputStreamReader(inputStream);
43+
BufferedReader bufferedReader = new BufferedReader(inputStreamReader);
44+
String receiveString = "";
45+
StringBuilder stringBuilder = new StringBuilder();
46+
47+
while ((receiveString = bufferedReader.readLine()) != null) {
48+
stringBuilder.append(receiveString);
49+
}
50+
51+
inputStream.close();
52+
ret = stringBuilder.toString();
53+
}
54+
} catch (FileNotFoundException e) {
55+
Log.e("login activity", "File not found: " + e.toString());
56+
} catch (IOException e) {
57+
Log.e("login activity", "Can not read file: " + e.toString());
58+
}
59+
60+
return ret;
61+
}
62+
63+
public static InputStream readFromFileAndReturnInputStream(String filename, Context context) {
64+
65+
String ret = "";
66+
67+
try {
68+
InputStream inputStream = context.openFileInput(filename);
69+
70+
return inputStream;
71+
} catch (FileNotFoundException e) {
72+
Log.e("login activity", "File not found: " + e.toString());
73+
} catch (IOException e) {
74+
Log.e("login activity", "Can not read file: " + e.toString());
75+
}
76+
77+
return null;
78+
}
79+
80+
public static String getMimeType(String url) {
81+
String type = null;
82+
String extension = MimeTypeMap.getFileExtensionFromUrl(url);
83+
if (extension != null) {
84+
type = MimeTypeMap.getSingleton().getMimeTypeFromExtension(extension);
85+
}
86+
return type;
87+
}
88+
}

0 commit comments

Comments
 (0)