/* * Copyright 2013-2015 Colin McDonough, University of South Florida, * Sean J. Barbeau * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.onebusaway.android.ui; import org.onebusaway.android.R; import org.onebusaway.android.util.UIUtils; import android.content.Context; import android.content.DialogInterface; import android.content.Intent; import android.content.SharedPreferences; import android.graphics.Color; import android.os.Bundle; import android.preference.PreferenceManager; import android.support.v7.app.AlertDialog; import android.support.v7.app.AppCompatActivity; import android.util.Log; import android.view.Menu; import android.view.MenuItem; import android.view.View; import android.view.WindowManager; /** * A flashing light that riders can show at night to flag bus drivers */ public class NightLightActivity extends AppCompatActivity { private static final String TAG = "NightLightActivity"; private static final String PREFERENCE_SHOWED_DIALOG = "showed_night_light_dialog"; static final String INSTALL_SHORTCUT = "com.android.launcher.action.INSTALL_SHORTCUT"; private static final int COLOR_DARK = 0xCC000000; private boolean lightOn; private boolean dialogShown; private View screen; boolean active = true; // Amount of time between flashes, in milliseconds private int[] waitTime = {100, 100, 400}; // Amount of time light is left on for single flash, in milliseconds private static final int FLASH_TIME_ON = 75; private int counter = 0; private int[] mColors; private float mOldScreenBrightness; /** * Starts the activity */ public static void start(Context context) { Intent i = new Intent(context, NightLightActivity.class); context.startActivity(i); } @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); UIUtils.setupActionBar(this); setContentView(R.layout.night_light); screen = findViewById(R.id.screen); disableScreenSleep(); // Set up colors to flash on screen mColors = new int[3]; mColors[0] = Color.WHITE; mColors[1] = getResources().getColor(R.color.theme_primary); mColors[2] = Color.WHITE; maybeShowIntroDialog(); } @Override public void onResume() { super.onResume(); turnLightOn(); active = true; // Flash the light via a Thread new Thread(new Runnable() { @Override public void run() { while (active) { runOnUiThread(new Runnable() { @Override public void run() { turnLightOn(); } }); Log.d(TAG, "Flashing for " + FLASH_TIME_ON + "ms"); try { Thread.sleep(FLASH_TIME_ON); } catch (InterruptedException e) { e.printStackTrace(); } runOnUiThread(new Runnable() { @Override public void run() { turnLightOff(); } }); try { Log.d(TAG, "Sleeping for " + waitTime[counter % 3] + "ms"); Thread.sleep(waitTime[counter % 3]); } catch (InterruptedException e) { e.printStackTrace(); } counter++; } } }).start(); } @Override public void onPause() { super.onPause(); turnLightOff(); active = false; restoreScreenBrightness(); } @Override public boolean onCreateOptionsMenu(Menu menu) { getMenuInflater().inflate(R.menu.night_light, menu); return super.onCreateOptionsMenu(menu); } @Override public boolean onOptionsItemSelected(MenuItem item) { if (item.getItemId() == R.id.create_shortcut) { createShortcut(); return true; } return false; } /** * Called after its confirmed that the user has seen the intro dialog to start the flashing */ public void onViewedDialog() { dialogShown = true; // Set screen brightness to full setScreenBrightness(); turnLightOn(); } private void disableScreenSleep() { getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON); } /** * Shows the initial intro dialog if the user hasn't yet seen it, and then start the flashing. * If the user has already seen the dialog, immediately start flashing */ private void maybeShowIntroDialog() { final SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(this); if (!sp.getBoolean(PREFERENCE_SHOWED_DIALOG, false)) { final AlertDialog.Builder builder = new AlertDialog.Builder(this); builder.setTitle(R.string.night_light_dialog_title); builder.setCancelable(false); builder.setPositiveButton(R.string.ok, new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int which) { sp.edit().putBoolean(PREFERENCE_SHOWED_DIALOG, true).commit(); // Start the flashing onViewedDialog(); } }); builder.setMessage(R.string.night_light_dialog_message); builder.create().show(); } else { // Start the flashing onViewedDialog(); } } /* * Called by the view (see main.xml) */ public void toggleLight(View view) { toggleLight(); } private void toggleLight() { if (lightOn) { turnLightOff(); } else { turnLightOn(); } } private void turnLightOn() { if (!dialogShown) { return; } lightOn = true; // Use the screen as a flashlight screen.setBackgroundColor(mColors[counter % 3]); } private void turnLightOff() { if (lightOn) { // Set the background to dark screen.setBackgroundColor(COLOR_DARK); lightOn = false; } } private void setScreenBrightness() { WindowManager.LayoutParams lp = this.getWindow().getAttributes(); mOldScreenBrightness = lp.screenBrightness; lp.screenBrightness = 1.0f; this.getWindow().setAttributes(lp); } private void restoreScreenBrightness() { WindowManager.LayoutParams lp = this.getWindow().getAttributes(); lp.screenBrightness = mOldScreenBrightness; } /** * Create a shortcut on the home screen */ private void createShortcut() { final Intent shortcutIntent = UIUtils.makeShortcut(this, getString(R.string.stop_info_option_night_light), new Intent(this, NightLightActivity.class)); shortcutIntent.setAction(INSTALL_SHORTCUT); shortcutIntent.setFlags(0); sendBroadcast(shortcutIntent); } }