Skip to content

Commit

Permalink
Merge pull request #143 from unbiaseduser/flash_off_on_screen_off
Browse files Browse the repository at this point in the history
Add option to turn off flash on screen off
  • Loading branch information
CrazyMarvin authored Jul 24, 2023
2 parents 238f0a1 + 6e707fd commit 8434aef
Show file tree
Hide file tree
Showing 10 changed files with 186 additions and 63 deletions.
3 changes: 1 addition & 2 deletions .idea/misc.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

10 changes: 4 additions & 6 deletions app/src/main/java/rocks/poopjournal/flashy/QSTileService.java
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ public void onCreate() {
@Override
public void onStartListening() {
super.onStartListening();
getQsTile().setState(Boolean.TRUE.equals(CameraHelper.getNormalFlashStatus().getValue()) ? Tile.STATE_ACTIVE : Tile.STATE_INACTIVE);
getQsTile().setState(Boolean.TRUE.equals(helper.getNormalFlashStatus().getValue()) ? Tile.STATE_ACTIVE : Tile.STATE_INACTIVE);
getQsTile().updateTile();
}

Expand All @@ -34,7 +34,7 @@ public void onTileAdded() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
getQsTile().setSubtitle(getString(R.string.no_camera));
}
} else if (Boolean.TRUE.equals(CameraHelper.getNormalFlashStatus().getValue())) {
} else if (Boolean.TRUE.equals(helper.getNormalFlashStatus().getValue())) {
getQsTile().setState(Tile.STATE_ACTIVE);
}
getQsTile().updateTile();
Expand All @@ -43,16 +43,14 @@ public void onTileAdded() {
@Override
public void onTileRemoved() {
super.onTileRemoved();
if (Boolean.TRUE.equals(CameraHelper.getNormalFlashStatus().getValue())) {
helper.toggleNormalFlash(this);
}
helper.turnOffNormalFlash(this);
}

@Override
public void onClick() {
super.onClick();
helper.toggleNormalFlash(this);
getQsTile().setState(Boolean.TRUE.equals(CameraHelper.getNormalFlashStatus().getValue()) ? Tile.STATE_ACTIVE : Tile.STATE_INACTIVE);
getQsTile().setState(Boolean.TRUE.equals(helper.getNormalFlashStatus().getValue()) ? Tile.STATE_ACTIVE : Tile.STATE_INACTIVE);
getQsTile().updateTile();
}
}
Original file line number Diff line number Diff line change
@@ -1,12 +1,15 @@
package rocks.poopjournal.flashy.activities;

import android.animation.LayoutTransition;
import android.content.BroadcastReceiver;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.SharedPreferences;
import android.content.pm.PackageManager;
import android.graphics.Color;
import android.os.Build;
import android.os.Bundle;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
Expand All @@ -25,6 +28,7 @@
import rocks.poopjournal.flashy.NoFlashlightDialog;
import rocks.poopjournal.flashy.R;
import rocks.poopjournal.flashy.databinding.MainActivityBinding;
import rocks.poopjournal.flashy.receivers.ScreenOffBroadcastReceiver;
import rocks.poopjournal.flashy.utils.CameraHelper;
import rocks.poopjournal.flashy.utils.Shortcuts;
import rocks.poopjournal.flashy.utils.Utils;
Expand All @@ -37,17 +41,34 @@ public class MainActivity extends AppCompatActivity {
private SharedPreferences defaultPreferences;
private CameraHelper helper;
private MainActivityBinding binding;
private final ScreenOffBroadcastReceiver turnOffFlashlightOnScreenOffReceiver = new ScreenOffBroadcastReceiver();
private enum FlashlightMode {
NORMAL, SOS, STROBOSCOPE
}
private final SharedPreferences.OnSharedPreferenceChangeListener material3Listener = (sharedPreferences, key) -> {
if (key.equals("md3")) recreate();
switch (key) {
case "md3":
recreate();
break;
case "no_flash_on_device_screen_off":
if (sharedPreferences.getBoolean("no_flash_on_device_screen_off", false)) {
turnOffFlashlightOnScreenOffReceiver.registerWith(this);
} else {
turnOffFlashlightOnScreenOffReceiver.unregisterWith(this);
}
break;
default:
Log.v(getClass().getSimpleName(), "Preference key received: " + key);
}
};

@Override
protected void onCreate(Bundle savedInstanceState) {
PreferenceManager.setDefaultValues(this, R.xml.root_preferences, false);
defaultPreferences = PreferenceManager.getDefaultSharedPreferences(this);
if (defaultPreferences.getBoolean("no_flash_on_device_screen_off", false)) {
turnOffFlashlightOnScreenOffReceiver.registerWith(this);
}
defaultPreferences.registerOnSharedPreferenceChangeListener(material3Listener);
if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.P && defaultPreferences.getString("theme", "system").equals("system"))
defaultPreferences.edit().putString("theme", "light").apply();
Expand All @@ -61,11 +82,11 @@ protected void onCreate(Bundle savedInstanceState) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU &&
helper.getFlashlightStrengthLevel(this) > 1 &&
defaultPreferences.getInt("flashlight_strength", -1) == -1) { //if flash brightness is not saved into preferences
CameraHelper.setFlashlightStrength(helper.getFlashlightStrengthLevel(this)); //then set brightness to max
helper.setFlashlightStrength(helper.getFlashlightStrengthLevel(this)); //then set brightness to max
} else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU &&
helper.getFlashlightStrengthLevel(this) > 1 &&
defaultPreferences.getInt("flashlight_strength", -1) != -1) { //if flash brightness is saved into preferences
CameraHelper.setFlashlightStrength(defaultPreferences.getInt("flashlight_strength", -1)); //then set brightness from there
helper.setFlashlightStrength(defaultPreferences.getInt("flashlight_strength", -1)); //then set brightness from there
}
setSupportActionBar(binding.toolbar);
window = getWindow();
Expand All @@ -88,24 +109,24 @@ protected void onCreate(Bundle savedInstanceState) {
binding.stroboscopeInterval.setVisibility(View.GONE);
binding.stroboscopeIntervalSlider.setVisibility(View.GONE);
} else {
CameraHelper.getNormalFlashStatus().observe(this, (isOn -> changeButtonColors(FlashlightMode.NORMAL, isOn)));
CameraHelper.getSosStatus().observe(this, (isOn -> changeButtonColors(FlashlightMode.SOS, isOn)));
CameraHelper.getStroboscopeStatus().observe(this, (isOn -> {
helper.getNormalFlashStatus().observe(this, (isOn -> changeButtonColors(FlashlightMode.NORMAL, isOn)));
helper.getSosStatus().observe(this, (isOn -> changeButtonColors(FlashlightMode.SOS, isOn)));
helper.getStroboscopeStatus().observe(this, (isOn -> {
changeButtonColors(FlashlightMode.STROBOSCOPE, isOn);
binding.stroboscopeInterval.setVisibility(isOn ? View.VISIBLE : View.GONE);
binding.stroboscopeIntervalSlider.setVisibility(isOn ? View.VISIBLE : View.GONE);
}));
binding.sosButton.setOnClickListener(v -> helper.toggleSos(this));
binding.stroboscopeButton.setOnClickListener(v -> helper.toggleStroboscope(this));
float stroboscopeIntervalInPreferences = defaultPreferences.getFloat("stroboscope_interval", -1);
CameraHelper.setStroboscopeInterval(stroboscopeIntervalInPreferences != -1 ? (int) (stroboscopeIntervalInPreferences * 1000) : 500);
helper.setStroboscopeInterval(stroboscopeIntervalInPreferences != -1 ? (int) (stroboscopeIntervalInPreferences * 1000) : 500);
binding.stroboscopeIntervalSlider.setValue(stroboscopeIntervalInPreferences != -1 ? stroboscopeIntervalInPreferences : 0.5F);
binding.stroboscopeIntervalSlider.addOnSliderTouchListener(new Slider.OnSliderTouchListener() {
@Override
public void onStartTrackingTouch(@NonNull Slider slider) {}
@Override
public void onStopTrackingTouch(@NonNull Slider slider) {
CameraHelper.setStroboscopeInterval((int) (slider.getValue() * 1000));
helper.setStroboscopeInterval((int) (slider.getValue() * 1000));
}
});
}
Expand All @@ -117,6 +138,12 @@ protected void onPause() {
defaultPreferences.edit().putFloat("stroboscope_interval", binding.stroboscopeIntervalSlider.getValue()).apply();
}

@Override
protected void onDestroy() {
super.onDestroy();
turnOffFlashlightOnScreenOffReceiver.unregisterWith(this);
}

@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.menu_main, menu);
Expand Down Expand Up @@ -166,8 +193,8 @@ else if (getPackageManager().hasSystemFeature(PackageManager.FEATURE_CAMERA_FLAS
binding.progressCircular.setOnSeekBarChangeListener(new CircularSeekBar.OnCircularSeekBarChangeListener() {
@Override
public void onProgressChanged(@Nullable CircularSeekBar circularSeekBar, float v, boolean b) {
CameraHelper.setFlashlightStrength(Math.round(v + 1));
if (Boolean.TRUE.equals(CameraHelper.getNormalFlashStatus().getValue()))
helper.setFlashlightStrength(Math.round(v + 1));
if (Boolean.TRUE.equals(helper.getNormalFlashStatus().getValue()))
helper.turnOnFlashWithStrength(MainActivity.this);
}
@Override
Expand All @@ -178,7 +205,7 @@ public void onStopTrackingTouch(@Nullable CircularSeekBar circularSeekBar) {
@Override
public void onStartTrackingTouch(@Nullable CircularSeekBar circularSeekBar) {}
});
binding.progressCircular.setProgress(CameraHelper.getFlashlightStrength() - 1);
binding.progressCircular.setProgress(helper.getFlashlightStrength() - 1);
binding.powerCenter.setOnClickListener(v -> helper.toggleNormalFlash(this));
} else if (getPackageManager().hasSystemFeature(PackageManager.FEATURE_CAMERA_FLASH)) {
binding.progressCircular.setOnSeekBarChangeListener(null);
Expand Down Expand Up @@ -231,7 +258,7 @@ void refreshActivityForScreenLight() {
binding.progressCircular.setPointerColor(Color.parseColor("#FFB137"));
binding.progressCircular.setEnabled(true);
if (defaultPreferences.getBoolean("no_flash_when_screen", true) && getPackageManager().hasSystemFeature(PackageManager.FEATURE_CAMERA_FLASH))
turnOff();
helper.turnOffAll(this);
binding.rootLayout.setBackgroundColor(Color.parseColor("#FFFFFF")); //force set white, because it does not make sense for the app to be dark when using screen light
if (binding.progressCircular.getProgress() > 0) {
binding.progressCircular.setOnSeekBarChangeListener(null);
Expand All @@ -255,18 +282,6 @@ public void onStartTrackingTouch(CircularSeekBar seekBar) {}
binding.powerCenter.setOnClickListener(view -> binding.progressCircular.setProgress(brightness != 100 ? 100 : 0));
}

public void turnOff() {
if (Boolean.TRUE.equals(CameraHelper.getNormalFlashStatus().getValue())) {
helper.toggleNormalFlash(this);
}
if (Boolean.TRUE.equals(CameraHelper.getSosStatus().getValue())) {
helper.toggleSos(this);
}
if (Boolean.TRUE.equals(CameraHelper.getStroboscopeStatus().getValue())) {
helper.toggleStroboscope(this);
}
}

@Override
protected void onSaveInstanceState(@NonNull Bundle outState) {
super.onSaveInstanceState(outState);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ public void onCreatePreferences(Bundle savedInstanceState, String rootKey) {
SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(requireContext());
preferences.registerOnSharedPreferenceChangeListener(listener);
helper = CameraHelper.getInstance(requireContext());
if (Boolean.TRUE.equals(CameraHelper.getSosStatus().getValue())) helper.toggleSos(requireContext());
if (Boolean.TRUE.equals(helper.getSosStatus().getValue())) helper.toggleSos(requireContext());

ListPreference themePref = findPreference("theme");
assert themePref != null;
Expand Down Expand Up @@ -92,11 +92,14 @@ public void onCreatePreferences(Bundle savedInstanceState, String rootKey) {
assert learnMoreAboutMorseTiming != null;
SwitchPreferenceCompat noFlashWhenScreen = findPreference("no_flash_when_screen");
assert noFlashWhenScreen != null;
SwitchPreferenceCompat noFlashOnDeviceScreenOff = findPreference("no_flash_on_device_screen_off");
assert noFlashOnDeviceScreenOff != null;
if (!requireContext().getPackageManager().hasSystemFeature(PackageManager.FEATURE_CAMERA_FLASH)) {
wordsPerMin.setVisible(false);
useFarnsworth.setVisible(false);
farnsworthUnitLength.setVisible(false);
noFlashWhenScreen.setVisible(false);
noFlashOnDeviceScreenOff.setVisible(false);
learnMoreAboutMorseTiming.setVisible(false);
} else {
wordsPerMin.setOnBindEditTextListener(editText -> editText.setInputType(InputType.TYPE_CLASS_NUMBER));
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
package rocks.poopjournal.flashy.receivers;

import static java.util.Objects.requireNonNull;

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Build;
import android.view.Display;

import androidx.annotation.RequiresApi;
import androidx.core.hardware.display.DisplayManagerCompat;

import rocks.poopjournal.flashy.utils.CameraHelper;

public class ScreenOffBroadcastReceiver extends BroadcastReceiver {

private boolean isRegistered = false;

public void registerWith(Context context) {
if (isRegistered) {
return;
}
context.registerReceiver(this, new IntentFilter(Intent.ACTION_SCREEN_OFF));
isRegistered = true;
}

public void unregisterWith(Context context) {
if (!isRegistered) {
return;
}
context.unregisterReceiver(this);
isRegistered = false;
}

@RequiresApi(api = Build.VERSION_CODES.KITKAT_WATCH)
@Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if (action == null) {
return;
}
if (Intent.ACTION_SCREEN_OFF.equals(action) && !isScreenOn(context)) {
CameraHelper helper = CameraHelper.getInstance(context);
helper.turnOffAll(context);
}
}

/**
* Checks if the screen is actually turned off because {@link Intent#ACTION_SCREEN_OFF} doesn't necessarily indicate that the screen is off.
* @return true if screen is actually turned off
*/
@RequiresApi(api = Build.VERSION_CODES.KITKAT_WATCH)
private boolean isScreenOn(Context context) {
Display display = requireNonNull(DisplayManagerCompat.getInstance(context).getDisplay(Display.DEFAULT_DISPLAY));
return display.getState() != Display.STATE_OFF;
}
}
Loading

0 comments on commit 8434aef

Please sign in to comment.