diff --git a/.idea/misc.xml b/.idea/misc.xml index 1b77328..bd04605 100644 --- a/.idea/misc.xml +++ b/.idea/misc.xml @@ -37,7 +37,7 @@ - + diff --git a/app/build.gradle b/app/build.gradle index db3e5b0..9a4aa11 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -6,7 +6,7 @@ android { compileSdkVersion 24 buildToolsVersion '23.0.3' defaultConfig { - applicationId 'com.rubenvandeven.emotion_hero' + applicationId 'com.rubenvandeven.emotion_hero.kiosk' minSdkVersion 16 targetSdkVersion 24 versionCode 7 diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 461073b..11a4c66 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -6,13 +6,22 @@ + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/java/com/rubenvandeven/emotionhero/AppContext.java b/app/src/main/java/com/rubenvandeven/emotionhero/AppContext.java new file mode 100644 index 0000000..1149f06 --- /dev/null +++ b/app/src/main/java/com/rubenvandeven/emotionhero/AppContext.java @@ -0,0 +1,46 @@ +package com.rubenvandeven.emotionhero; + +import android.app.Application; +import android.content.Context; +import android.content.Intent; +import android.content.IntentFilter; +import android.os.PowerManager; + +/** + * For kioskmode only! + * See http://www.andreas-schrade.de/2015/02/16/android-tutorial-how-to-create-a-kiosk-mode-in-android/ + */ +public class AppContext extends Application { + private AppContext instance; + private PowerManager.WakeLock wakeLock; + private OnScreenOffReceiver onScreenOffReceiver; + + + @Override + public void onCreate() { + super.onCreate(); + instance = this; + registerKioskModeScreenOffReceiver(); + startKioskService(); + } + + private void registerKioskModeScreenOffReceiver() { + // register screen off receiver + final IntentFilter filter = new IntentFilter(Intent.ACTION_SCREEN_OFF); + onScreenOffReceiver = new OnScreenOffReceiver(); + registerReceiver(onScreenOffReceiver, filter); + } + + public PowerManager.WakeLock getWakeLock() { + if(wakeLock == null) { + // lazy loading: first call, create wakeLock via PowerManager. + PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE); + wakeLock = pm.newWakeLock(PowerManager.FULL_WAKE_LOCK | PowerManager.ACQUIRE_CAUSES_WAKEUP, "wakeup"); + } + return wakeLock; + } + + private void startKioskService() { + startService(new Intent(this, KioskService.class)); + } +} \ No newline at end of file diff --git a/app/src/main/java/com/rubenvandeven/emotionhero/BootReceiver.java b/app/src/main/java/com/rubenvandeven/emotionhero/BootReceiver.java new file mode 100644 index 0000000..27f9cf1 --- /dev/null +++ b/app/src/main/java/com/rubenvandeven/emotionhero/BootReceiver.java @@ -0,0 +1,18 @@ +package com.rubenvandeven.emotionhero; + +import android.content.BroadcastReceiver; +import android.content.Context; +import android.content.Intent; + +/** + * For kioskmode only! + * See http://www.andreas-schrade.de/2015/02/16/android-tutorial-how-to-create-a-kiosk-mode-in-android/ + */ +public class BootReceiver extends BroadcastReceiver { + @Override + public void onReceive(Context context, Intent intent) { + Intent myIntent = new Intent(context, IntroActivity.class); + myIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); + context.startActivity(myIntent); + } +} diff --git a/app/src/main/java/com/rubenvandeven/emotionhero/CreditsActivity.java b/app/src/main/java/com/rubenvandeven/emotionhero/CreditsActivity.java index af27a57..8b52ae9 100644 --- a/app/src/main/java/com/rubenvandeven/emotionhero/CreditsActivity.java +++ b/app/src/main/java/com/rubenvandeven/emotionhero/CreditsActivity.java @@ -80,4 +80,18 @@ public class CreditsActivity extends AppCompatActivity { } }); } + + /** + * For kioskmode + * @param hasFocus + */ + @Override + public void onWindowFocusChanged(boolean hasFocus) { + super.onWindowFocusChanged(hasFocus); + if(!hasFocus) { + // Close every kind of system dialog + Intent closeDialog = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS); + sendBroadcast(closeDialog); + } + } } diff --git a/app/src/main/java/com/rubenvandeven/emotionhero/EndingActivity.java b/app/src/main/java/com/rubenvandeven/emotionhero/EndingActivity.java index 99b5fa6..322e99e 100644 --- a/app/src/main/java/com/rubenvandeven/emotionhero/EndingActivity.java +++ b/app/src/main/java/com/rubenvandeven/emotionhero/EndingActivity.java @@ -1,5 +1,6 @@ package com.rubenvandeven.emotionhero; +import android.content.Intent; import android.support.v7.app.AppCompatActivity; import android.os.Bundle; import android.support.v7.widget.Toolbar; @@ -88,4 +89,18 @@ public class EndingActivity extends AppCompatActivity { this.rank.setVisibility(View.VISIBLE); this.textRank.setVisibility(View.VISIBLE); } + + /** + * For kioskmode + * @param hasFocus + */ + @Override + public void onWindowFocusChanged(boolean hasFocus) { + super.onWindowFocusChanged(hasFocus); + if(!hasFocus) { + // Close every kind of system dialog + Intent closeDialog = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS); + sendBroadcast(closeDialog); + } + } } diff --git a/app/src/main/java/com/rubenvandeven/emotionhero/GamingActivity.java b/app/src/main/java/com/rubenvandeven/emotionhero/GamingActivity.java index ee45fc9..7670a6a 100644 --- a/app/src/main/java/com/rubenvandeven/emotionhero/GamingActivity.java +++ b/app/src/main/java/com/rubenvandeven/emotionhero/GamingActivity.java @@ -75,6 +75,7 @@ public class GamingActivity extends AppCompatActivity implements Detector.ImageL protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); getWindow().addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN); + getWindow().addFlags(WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD); // kiosk mode if(getSupportActionBar() != null) { getSupportActionBar().hide(); } @@ -408,4 +409,18 @@ public class GamingActivity extends AppCompatActivity implements Detector.ImageL intent.putExtra(ReviewActivity.INTENT_EXTRA_FROM_GAME, true); startActivity(intent); } + + /** + * For kioskmode + * @param hasFocus + */ + @Override + public void onWindowFocusChanged(boolean hasFocus) { + super.onWindowFocusChanged(hasFocus); + if(!hasFocus) { + // Close every kind of system dialog + Intent closeDialog = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS); + sendBroadcast(closeDialog); + } + } } diff --git a/app/src/main/java/com/rubenvandeven/emotionhero/HighscoreActivity.java b/app/src/main/java/com/rubenvandeven/emotionhero/HighscoreActivity.java index 5820a01..fb88b26 100644 --- a/app/src/main/java/com/rubenvandeven/emotionhero/HighscoreActivity.java +++ b/app/src/main/java/com/rubenvandeven/emotionhero/HighscoreActivity.java @@ -424,4 +424,17 @@ public class HighscoreActivity extends AppCompatActivity { return mViewPager; } + /** + * For kioskmode + * @param hasFocus + */ + @Override + public void onWindowFocusChanged(boolean hasFocus) { + super.onWindowFocusChanged(hasFocus); + if(!hasFocus) { + // Close every kind of system dialog + Intent closeDialog = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS); + sendBroadcast(closeDialog); + } + } } diff --git a/app/src/main/java/com/rubenvandeven/emotionhero/IntroActivity.java b/app/src/main/java/com/rubenvandeven/emotionhero/IntroActivity.java index 1ede131..c38ab99 100644 --- a/app/src/main/java/com/rubenvandeven/emotionhero/IntroActivity.java +++ b/app/src/main/java/com/rubenvandeven/emotionhero/IntroActivity.java @@ -28,6 +28,7 @@ public class IntroActivity extends AppCompatActivity { protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); getWindow().addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN); + getWindow().addFlags(WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD); // kiosk mode if(getSupportActionBar() != null) { getSupportActionBar().hide(); } @@ -95,4 +96,18 @@ public class IntroActivity extends AppCompatActivity { //disable distracting transition when going to menu IntroActivity.this.overridePendingTransition(0, 0); } + + /** + * For kioskmode + * @param hasFocus + */ + @Override + public void onWindowFocusChanged(boolean hasFocus) { + super.onWindowFocusChanged(hasFocus); + if(!hasFocus) { + // Close every kind of system dialog + Intent closeDialog = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS); + sendBroadcast(closeDialog); + } + } } diff --git a/app/src/main/java/com/rubenvandeven/emotionhero/KioskService.java b/app/src/main/java/com/rubenvandeven/emotionhero/KioskService.java new file mode 100644 index 0000000..6b4671b --- /dev/null +++ b/app/src/main/java/com/rubenvandeven/emotionhero/KioskService.java @@ -0,0 +1,95 @@ +package com.rubenvandeven.emotionhero; + +import android.app.ActivityManager; +import android.app.Service; +import android.content.ComponentName; +import android.content.Context; +import android.content.Intent; +import android.os.IBinder; +import android.util.Log; + +import java.util.List; +import java.util.concurrent.TimeUnit; + +/** + * Created by ruben on 05/10/16. + */ + +public class KioskService extends Service { + private static final long INTERVAL = TimeUnit.SECONDS.toMillis(2); // periodic interval to check in seconds -> 2 seconds + private static final String TAG = KioskService.class.getSimpleName(); + private static final String PREF_KIOSK_MODE = "pref_kiosk_mode"; + + private Thread t = null; + private Context ctx = null; + private boolean running = false; + + @Override + public void onDestroy() { + Log.i(TAG, "Stopping service 'KioskService'"); + running =false; + super.onDestroy(); + } + + @Override + public int onStartCommand(Intent intent, int flags, int startId) { + Log.i(TAG, "Starting service 'KioskService'"); + running = true; + ctx = this; + + // start a thread that periodically checks if your app is in the foreground + t = new Thread(new Runnable() { + @Override + public void run() { + do { + handleKioskMode(); + try { + Thread.sleep(INTERVAL); + } catch (InterruptedException e) { + Log.i(TAG, "Thread interrupted: 'KioskService'"); + } + }while(running); + stopSelf(); + } + }); + + t.start(); + return Service.START_NOT_STICKY; + } + + private void handleKioskMode() { + // is Kiosk Mode active? + if(true) { + // is App in background? + if(isInBackground()) { + restoreApp(); // restore! + } + } + } + + private boolean isInBackground() { + ActivityManager am = (ActivityManager) ctx.getSystemService(Context.ACTIVITY_SERVICE); + + List taskInfo = am.getRunningTasks(1); + ComponentName componentInfo = taskInfo.get(0).topActivity; + return (!ctx.getApplicationContext().getPackageName().equals(componentInfo.getPackageName())); + } + + private void restoreApp() { + // Restart activity + Intent i = new Intent(ctx, IntroActivity.class); + i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); + ctx.startActivity(i); + } + + public boolean isKioskModeActive(final Context context) { + return true; +// SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(context); +// return sp.getBoolean(PREF_KIOSK_MODE, false); + } + + @Override + public IBinder onBind(Intent intent) { + return null; + } +} diff --git a/app/src/main/java/com/rubenvandeven/emotionhero/MirrorMenuActivity.java b/app/src/main/java/com/rubenvandeven/emotionhero/MirrorMenuActivity.java index f0032bc..8746b32 100644 --- a/app/src/main/java/com/rubenvandeven/emotionhero/MirrorMenuActivity.java +++ b/app/src/main/java/com/rubenvandeven/emotionhero/MirrorMenuActivity.java @@ -415,4 +415,26 @@ public class MirrorMenuActivity extends AppCompatActivity implements Detector.Im messageText.setVisibility(View.GONE); } + /** + * For kiosk mode only + */ + @Override + public void onBackPressed() { + // nothing to do here + // … really + } + + /** + * For kioskmode + * @param hasFocus + */ + @Override + public void onWindowFocusChanged(boolean hasFocus) { + super.onWindowFocusChanged(hasFocus); + if(!hasFocus) { + // Close every kind of system dialog + Intent closeDialog = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS); + sendBroadcast(closeDialog); + } + } } diff --git a/app/src/main/java/com/rubenvandeven/emotionhero/OnScreenOffReceiver.java b/app/src/main/java/com/rubenvandeven/emotionhero/OnScreenOffReceiver.java new file mode 100644 index 0000000..4eca8b1 --- /dev/null +++ b/app/src/main/java/com/rubenvandeven/emotionhero/OnScreenOffReceiver.java @@ -0,0 +1,46 @@ +package com.rubenvandeven.emotionhero; + +import android.content.BroadcastReceiver; +import android.content.Context; +import android.content.Intent; +import android.content.SharedPreferences; +import android.os.PowerManager; +import android.preference.PreferenceManager; + +/** + * For kioskmode only! + * See http://www.andreas-schrade.de/2015/02/16/android-tutorial-how-to-create-a-kiosk-mode-in-android/ + */ +public class OnScreenOffReceiver extends BroadcastReceiver { + private static final String PREF_KIOSK_MODE = "pref_kiosk_mode"; + + @Override + public void onReceive(Context context, Intent intent) { + if(Intent.ACTION_SCREEN_OFF.equals(intent.getAction())){ + AppContext ctx = (AppContext) context.getApplicationContext(); + // is Kiosk Mode active? + if(isKioskModeActive(ctx)) { + wakeUpDevice(ctx); + } + } + } + + private void wakeUpDevice(AppContext context) { + PowerManager.WakeLock wakeLock = context.getWakeLock(); // get WakeLock reference via AppContext + if (wakeLock.isHeld()) { + wakeLock.release(); // release old wake lock + } + + // create a new wake lock... + wakeLock.acquire(); + + // ... and release again + wakeLock.release(); + } + + private boolean isKioskModeActive(final Context context) { + return true; +// SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(context); +// return sp.getBoolean(PREF_KIOSK_MODE, false); + } +} diff --git a/app/src/main/java/com/rubenvandeven/emotionhero/ProgressActivity.java b/app/src/main/java/com/rubenvandeven/emotionhero/ProgressActivity.java index 7ffcc42..42b4b49 100644 --- a/app/src/main/java/com/rubenvandeven/emotionhero/ProgressActivity.java +++ b/app/src/main/java/com/rubenvandeven/emotionhero/ProgressActivity.java @@ -188,4 +188,18 @@ public class ProgressActivity extends AppCompatActivity { levelsLayout.addView(outroText); } + + /** + * For kioskmode + * @param hasFocus + */ + @Override + public void onWindowFocusChanged(boolean hasFocus) { + super.onWindowFocusChanged(hasFocus); + if(!hasFocus) { + // Close every kind of system dialog + Intent closeDialog = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS); + sendBroadcast(closeDialog); + } + } } diff --git a/app/src/main/java/com/rubenvandeven/emotionhero/ReviewAchievementsActivity.java b/app/src/main/java/com/rubenvandeven/emotionhero/ReviewAchievementsActivity.java index 9b6546f..a6816ac 100644 --- a/app/src/main/java/com/rubenvandeven/emotionhero/ReviewAchievementsActivity.java +++ b/app/src/main/java/com/rubenvandeven/emotionhero/ReviewAchievementsActivity.java @@ -1,5 +1,6 @@ package com.rubenvandeven.emotionhero; +import android.content.Intent; import android.support.v7.app.AppCompatActivity; import android.os.Bundle; import android.support.v7.widget.AppCompatTextView; @@ -94,4 +95,17 @@ public class ReviewAchievementsActivity extends AppCompatActivity { achievementsLayout.addView(titleText); achievementsLayout.addView(descriptionLayout); } + /** + * For kioskmode + * @param hasFocus + */ + @Override + public void onWindowFocusChanged(boolean hasFocus) { + super.onWindowFocusChanged(hasFocus); + if(!hasFocus) { + // Close every kind of system dialog + Intent closeDialog = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS); + sendBroadcast(closeDialog); + } + } } diff --git a/app/src/main/java/com/rubenvandeven/emotionhero/ReviewActivity.java b/app/src/main/java/com/rubenvandeven/emotionhero/ReviewActivity.java index f2add68..2903a70 100644 --- a/app/src/main/java/com/rubenvandeven/emotionhero/ReviewActivity.java +++ b/app/src/main/java/com/rubenvandeven/emotionhero/ReviewActivity.java @@ -353,4 +353,18 @@ public class ReviewActivity extends AppCompatActivity { return super.onOptionsItemSelected(menuItem); } } + + /** + * For kioskmode + * @param hasFocus + */ + @Override + public void onWindowFocusChanged(boolean hasFocus) { + super.onWindowFocusChanged(hasFocus); + if(!hasFocus) { + // Close every kind of system dialog + Intent closeDialog = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS); + sendBroadcast(closeDialog); + } + } } diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 233e527..2594cb2 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -1,5 +1,5 @@ - Emotion Hero + Emotion Hero - Exhibition Edition Dummy Button initialising…