From 5cea05828d6654da892a33aefc3a11578205a572 Mon Sep 17 00:00:00 2001 From: S4NKALP Date: Mon, 30 Jun 2025 13:34:31 +0545 Subject: [PATCH] =?UTF-8?q?=E2=9C=A8=20feat(ui,=20accessibility):=20add=20?= =?UTF-8?q?double=20tap=20to=20lock=20screen=20feature=20with=20accessibil?= =?UTF-8?q?ity=20service=20support?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/src/main/AndroidManifest.xml | 16 +- .../sankalp/lunox/LauncherActivity.java | 56 ++++++- .../lunox/dialogs/DoubleTapLockDialog.java | 151 ++++++++++++++++++ .../lunox/dialogs/GlobalSettingsDialog.java | 55 +++++++ .../LockScreenAccessibilityService.java | 130 +++++++++++++++ .../lunox/utils/AccessibilityUtils.java | 109 +++++++++++++ .../github/sankalp/lunox/utils/DbUtils.java | 15 ++ .../github/sankalp/lunox/utils/Gestures.java | 22 ++- .../main/res/drawable/dialog_background.xml | 6 + .../res/layout/dialog_double_tap_lock.xml | 80 ++++++++++ .../res/layout/dialog_global_settings.xml | 17 ++ app/src/main/res/values/strings.xml | 8 + .../res/xml/accessibility_service_config.xml | 11 ++ 13 files changed, 671 insertions(+), 5 deletions(-) create mode 100644 app/src/main/java/io/github/sankalp/lunox/dialogs/DoubleTapLockDialog.java create mode 100644 app/src/main/java/io/github/sankalp/lunox/services/LockScreenAccessibilityService.java create mode 100644 app/src/main/java/io/github/sankalp/lunox/utils/AccessibilityUtils.java create mode 100644 app/src/main/res/drawable/dialog_background.xml create mode 100644 app/src/main/res/layout/dialog_double_tap_lock.xml create mode 100644 app/src/main/res/xml/accessibility_service_config.xml diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 78bf9e5..8eb05e8 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -15,6 +15,9 @@ + + + - + + + + + + + diff --git a/app/src/main/java/io/github/sankalp/lunox/LauncherActivity.java b/app/src/main/java/io/github/sankalp/lunox/LauncherActivity.java index 8312105..fdf8ce1 100644 --- a/app/src/main/java/io/github/sankalp/lunox/LauncherActivity.java +++ b/app/src/main/java/io/github/sankalp/lunox/LauncherActivity.java @@ -82,6 +82,7 @@ import java.util.Map; import io.github.sankalp.lunox.dialogs.AppSettingsPopup; import io.github.sankalp.lunox.dialogs.ColorSizeDialog; +import io.github.sankalp.lunox.dialogs.DoubleTapLockDialog; import io.github.sankalp.lunox.dialogs.FrozenAppsDialogs; import io.github.sankalp.lunox.dialogs.GlobalColorSizeDialog; import io.github.sankalp.lunox.dialogs.GlobalSettingsDialog; @@ -94,6 +95,7 @@ import io.github.sankalp.lunox.model.Shortcut; import io.github.sankalp.lunox.utils.CrashUtils; import io.github.sankalp.lunox.utils.DbUtils; +import io.github.sankalp.lunox.utils.AccessibilityUtils; import io.github.sankalp.lunox.utils.Gestures; import io.github.sankalp.lunox.utils.NotificationPanelManager; import io.github.sankalp.lunox.utils.ShortcutUtils; @@ -140,7 +142,8 @@ import static io.github.sankalp.lunox.utils.Constants.SORT_BY_UPDATE_TIME; @SuppressLint("NonConstantResourceId") public class LauncherActivity extends Activity implements View.OnClickListener, View.OnLongClickListener, - Gestures.OnSwipeListener { + Gestures.OnSwipeListener, + Gestures.OnDoubleTapListener { //region Field declarations @@ -283,7 +286,7 @@ public class LauncherActivity extends Activity implements View.OnClickListener, //set padding .. mHomeLayout.setPadding(DbUtils.getPaddingLeft(), DbUtils.getPaddingTop(), DbUtils.getPaddingRight(), DbUtils.getPaddingBottom()); - detector = new Gestures(this, this); + detector = new Gestures(this, this, this); // Initialize long press detector for empty areas longPressDetector = new GestureDetector(this, new GestureDetector.SimpleOnGestureListener() { @@ -1211,6 +1214,27 @@ public class LauncherActivity extends Activity implements View.OnClickListener, } } + @Override + public void onDoubleTap(MotionEvent e) { + // Check if double tap to lock is enabled + if (!DbUtils.isDoubleTapToLockEnabled()) { + return; + } + + // Check if the double tap is on an empty area (not on an app) + View touchedView = findViewAt(e.getX(), e.getY()); + if (!(touchedView instanceof AppTextView)) { + // Attempt to lock screen using accessibility service + boolean success = AccessibilityUtils.requestLockScreen(this); + if (!success) { + // Show message if accessibility service is not enabled + if (!AccessibilityUtils.isAccessibilityServiceEnabled(this)) { + showAccessibilityServiceDialog(); + } + } + } + } + @@ -1322,5 +1346,33 @@ public class LauncherActivity extends Activity implements View.OnClickListener, permissionDialog.show(); } + /** + * Show dialog to enable accessibility service for double tap to lock + */ + private void showAccessibilityServiceDialog() { + Context ctx; + if (DbUtils.getTheme() == R.style.Wallpaper) + ctx = new ContextThemeWrapper(this, R.style.AppTheme); + else + ctx = new ContextThemeWrapper(this, DbUtils.getTheme()); + + AlertDialog.Builder builder = new AlertDialog.Builder(ctx); + builder.setTitle("Enable Accessibility Service"); + builder.setMessage("To use double tap to lock screen, please enable the Lunox Accessibility Service in Settings."); + builder.setPositiveButton("Open Settings", (dialog, which) -> { + AccessibilityUtils.openAccessibilitySettings(this); + }); + builder.setNegativeButton("Cancel", null); + builder.show(); + } + + /** + * Show detailed double tap to lock dialog + */ + private void showDoubleTapLockDialog() { + dialogs = new DoubleTapLockDialog(this, this); + dialogs.show(); + } + } \ No newline at end of file diff --git a/app/src/main/java/io/github/sankalp/lunox/dialogs/DoubleTapLockDialog.java b/app/src/main/java/io/github/sankalp/lunox/dialogs/DoubleTapLockDialog.java new file mode 100644 index 0000000..a4e9443 --- /dev/null +++ b/app/src/main/java/io/github/sankalp/lunox/dialogs/DoubleTapLockDialog.java @@ -0,0 +1,151 @@ +/* + * Lunox Launcher + * Copyright (C) 2024 Sankalp + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package io.github.sankalp.lunox.dialogs; + +import android.app.Dialog; +import android.content.Context; + +import android.os.Bundle; +import android.view.View; +import android.view.Window; +import android.widget.TextView; + +import io.github.sankalp.lunox.LauncherActivity; +import io.github.sankalp.lunox.R; +import io.github.sankalp.lunox.utils.AccessibilityUtils; +import io.github.sankalp.lunox.utils.DbUtils; + +/** + * Dialog for configuring double tap to lock screen functionality + */ +public class DoubleTapLockDialog extends Dialog implements View.OnClickListener { + + private final LauncherActivity launcherActivity; + private final Context context; + private TextView enableButton; + private TextView closeButton; + private TextView mainDescription; + private TextView additionalInfo; + + public DoubleTapLockDialog(Context context, LauncherActivity launcherActivity) { + super(context); + this.context = context; + this.launcherActivity = launcherActivity; + } + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + requestWindowFeature(Window.FEATURE_NO_TITLE); + setContentView(R.layout.dialog_double_tap_lock); + + // Make background transparent for rounded corners + if (getWindow() != null) { + getWindow().setBackgroundDrawableResource(android.R.color.transparent); + } + + // Initialize views + enableButton = findViewById(R.id.btn_enable); + closeButton = findViewById(R.id.btn_close); + mainDescription = findViewById(R.id.tv_main_description); + additionalInfo = findViewById(R.id.tv_additional_info); + + // Set click listeners + enableButton.setOnClickListener(this); + closeButton.setOnClickListener(this); + + // Update content based on current state + updateDialogContent(); + } + + @Override + public void onWindowFocusChanged(boolean hasFocus) { + super.onWindowFocusChanged(hasFocus); + if (hasFocus) { + // Refresh dialog content when user returns from settings + updateDialogContent(); + } + } + + @Override + public void onClick(View view) { + int id = view.getId(); + + if (id == R.id.btn_enable) { + handleEnableButton(); + } else if (id == R.id.btn_close) { + dismiss(); + } + } + + private void handleEnableButton() { + boolean isCurrentlyEnabled = DbUtils.isDoubleTapToLockEnabled(); + + if (isCurrentlyEnabled) { + // Disable the feature + DbUtils.setDoubleTapToLock(false); + updateDialogContent(); + dismiss(); + } else { + // Check if accessibility service is enabled before enabling the feature + if (AccessibilityUtils.isAccessibilityServiceEnabled(context)) { + // Service is enabled, so we can enable the feature + DbUtils.setDoubleTapToLock(true); + updateDialogContent(); + dismiss(); + } else { + // Service is not enabled, open accessibility settings but don't enable the feature yet + AccessibilityUtils.openAccessibilitySettings(context); + // Keep the dialog open so user can try again after enabling the service + updateDialogContent(); + } + } + } + + private void updateDialogContent() { + boolean isEnabled = DbUtils.isDoubleTapToLockEnabled(); + boolean isServiceEnabled = AccessibilityUtils.isAccessibilityServiceEnabled(context); + + // Update button text based on current state + if (isEnabled) { + enableButton.setText("Disable"); + } else if (isServiceEnabled) { + enableButton.setText("Enable"); + } else { + enableButton.setText("Open Settings"); + } + + // Update description based on current state + if (isEnabled && isServiceEnabled) { + mainDescription.setText("Double tap to lock is currently enabled and working. You can disable it below if you no longer want this feature."); + additionalInfo.setText("The accessibility service is active and allows you to lock your screen by double tapping on empty areas of the launcher."); + } else if (isEnabled && !isServiceEnabled) { + mainDescription.setText("Double tap to lock is enabled but the accessibility service is not active. Please enable Lunox's accessibility service in your device's settings."); + additionalInfo.setText("The accessibility service is required for the double tap to lock feature to work. It only locks your screen and does not collect any data."); + } else if (!isEnabled && isServiceEnabled) { + mainDescription.setText("The accessibility service is enabled. You can now enable double tap to lock to quickly lock your screen by double tapping on empty areas."); + additionalInfo.setText("This feature will use the accessibility service to lock your screen when you double tap on empty areas of the launcher."); + } else { + mainDescription.setText("To enable double tap to lock, you first need to enable Lunox's accessibility service in your device's settings."); + additionalInfo.setText("The accessibility service is required for this feature to work. It only locks your screen and does not collect or share any data. Click Enable to open the settings."); + } + } + + +} diff --git a/app/src/main/java/io/github/sankalp/lunox/dialogs/GlobalSettingsDialog.java b/app/src/main/java/io/github/sankalp/lunox/dialogs/GlobalSettingsDialog.java index 373337d..9128356 100644 --- a/app/src/main/java/io/github/sankalp/lunox/dialogs/GlobalSettingsDialog.java +++ b/app/src/main/java/io/github/sankalp/lunox/dialogs/GlobalSettingsDialog.java @@ -18,6 +18,7 @@ package io.github.sankalp.lunox.dialogs; +import android.app.AlertDialog; import android.app.Dialog; import android.content.Context; import android.content.Intent; @@ -38,7 +39,9 @@ import java.util.Locale; import io.github.sankalp.lunox.BuildConfig; import io.github.sankalp.lunox.LauncherActivity; import io.github.sankalp.lunox.R; +import io.github.sankalp.lunox.dialogs.DoubleTapLockDialog; import io.github.sankalp.lunox.model.Apps; +import io.github.sankalp.lunox.utils.AccessibilityUtils; import io.github.sankalp.lunox.utils.Constants; import io.github.sankalp.lunox.utils.DbUtils; import io.github.sankalp.lunox.utils.Utils; @@ -57,6 +60,7 @@ public class GlobalSettingsDialog extends Dialog implements View.OnClickListener private final LauncherActivity launcherActivity; private final Context context; private TextView freezeSize; + private TextView doubleTapLockButton; public GlobalSettingsDialog(Context context, LauncherActivity launcherActivity) { super(context); @@ -102,6 +106,10 @@ public class GlobalSettingsDialog extends Dialog implements View.OnClickListener findViewById(R.id.settings_frozen_apps).setOnClickListener(this); findViewById(R.id.settings_hidden_apps).setOnClickListener(this); + // Double tap to lock setting + doubleTapLockButton = findViewById(R.id.settings_double_tap_lock); + doubleTapLockButton.setOnClickListener(this); + //reflect the DB value if (DbUtils.isSizeFrozen()) { @@ -109,6 +117,9 @@ public class GlobalSettingsDialog extends Dialog implements View.OnClickListener } else freezeSize.setText(R.string.freeze_apps_size); + // Set double tap to lock button text + updateDoubleTapLockButtonText(); + } @Override @@ -145,6 +156,8 @@ public class GlobalSettingsDialog extends Dialog implements View.OnClickListener cancel(); } else if (id == R.id.settings_restart_launcher) { launcherActivity.recreate(); + } else if (id == R.id.settings_double_tap_lock) { + toggleDoubleTapToLock(); } } @@ -278,6 +291,48 @@ public class GlobalSettingsDialog extends Dialog implements View.OnClickListener } + private void toggleDoubleTapToLock() { + boolean currentState = DbUtils.isDoubleTapToLockEnabled(); + + if (currentState) { + // If currently enabled, just disable it directly + DbUtils.setDoubleTapToLock(false); + updateDoubleTapLockButtonText(); + } else { + // If currently disabled, show the detailed dialog to explain and enable the feature + DoubleTapLockDialog doubleTapDialog = new DoubleTapLockDialog(context, launcherActivity); + doubleTapDialog.show(); + + // Update button text when dialog is dismissed + doubleTapDialog.setOnDismissListener(dialog -> updateDoubleTapLockButtonText()); + } + } + + private void updateDoubleTapLockButtonText() { + if (DbUtils.isDoubleTapToLockEnabled()) { + doubleTapLockButton.setText(R.string.double_tap_to_lock_enabled); + } else { + doubleTapLockButton.setText(R.string.double_tap_to_lock_disabled); + } + } + + private void showAccessibilityServiceDialog() { + Context ctx; + if (DbUtils.getTheme() == R.style.Wallpaper) + ctx = new ContextThemeWrapper(getContext(), R.style.AppTheme); + else + ctx = new ContextThemeWrapper(getContext(), DbUtils.getTheme()); + + AlertDialog.Builder builder = new AlertDialog.Builder(ctx); + builder.setTitle("Enable Accessibility Service"); + builder.setMessage("To use double tap to lock screen, please enable the Lunox Accessibility Service in Settings."); + builder.setPositiveButton("Open Settings", (dialog, which) -> { + AccessibilityUtils.openAccessibilitySettings(context); + }); + builder.setNegativeButton("Cancel", null); + builder.show(); + } + private void backup() { cancel(); Intent intentBackupFiles; diff --git a/app/src/main/java/io/github/sankalp/lunox/services/LockScreenAccessibilityService.java b/app/src/main/java/io/github/sankalp/lunox/services/LockScreenAccessibilityService.java new file mode 100644 index 0000000..5008ff6 --- /dev/null +++ b/app/src/main/java/io/github/sankalp/lunox/services/LockScreenAccessibilityService.java @@ -0,0 +1,130 @@ +/* + * Lunox Launcher + * Copyright (C) 2024 Sankalp + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package io.github.sankalp.lunox.services; + +import android.accessibilityservice.AccessibilityService; +import android.accessibilityservice.GestureDescription; +import android.content.Intent; +import android.graphics.Path; +import android.os.Build; +import android.util.Log; +import android.view.KeyEvent; +import android.view.accessibility.AccessibilityEvent; + +/** + * Accessibility service for lock screen functionality + * This service can perform global actions like simulating power key press + */ +public class LockScreenAccessibilityService extends AccessibilityService { + + private static final String TAG = "LockScreenAccessibilityService"; + private static LockScreenAccessibilityService instance; + + public static final String ACTION_LOCK_SCREEN = "io.github.sankalp.lunox.ACTION_LOCK_SCREEN"; + + @Override + public void onCreate() { + super.onCreate(); + instance = this; + Log.d(TAG, "Accessibility service created"); + } + + @Override + public void onDestroy() { + super.onDestroy(); + instance = null; + Log.d(TAG, "Accessibility service destroyed"); + } + + @Override + public void onAccessibilityEvent(AccessibilityEvent event) { + // We don't need to handle accessibility events for this use case + } + + @Override + public void onInterrupt() { + Log.d(TAG, "Accessibility service interrupted"); + } + + @Override + protected boolean onKeyEvent(KeyEvent event) { + return super.onKeyEvent(event); + } + + @Override + public int onStartCommand(Intent intent, int flags, int startId) { + if (intent != null && ACTION_LOCK_SCREEN.equals(intent.getAction())) { + lockScreen(); + } + return START_NOT_STICKY; + } + + /** + * Lock the screen using accessibility service global action + */ + public void lockScreen() { + try { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) { + // Android 9+ supports GLOBAL_ACTION_LOCK_SCREEN + boolean success = performGlobalAction(GLOBAL_ACTION_LOCK_SCREEN); + Log.d(TAG, "Lock screen action performed: " + success); + if (!success) { + // Fallback to power button simulation + simulatePowerButton(); + } + } else { + // For older versions, simulate power button press + simulatePowerButton(); + } + } catch (Exception e) { + Log.e(TAG, "Failed to lock screen", e); + } + } + + /** + * Simulate power button press using accessibility service + */ + private void simulatePowerButton() { + try { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { + // Use gesture simulation to simulate power button + // This is a workaround since we can't directly simulate hardware keys + // We'll use the global action for power dialog which can lock the screen + boolean success = performGlobalAction(GLOBAL_ACTION_POWER_DIALOG); + Log.d(TAG, "Power dialog action performed: " + success); + } + } catch (Exception e) { + Log.e(TAG, "Failed to simulate power button", e); + } + } + + /** + * Get the current instance of the accessibility service + */ + public static LockScreenAccessibilityService getInstance() { + return instance; + } + + /** + * Check if the accessibility service is running + */ + public static boolean isServiceRunning() { + return instance != null; + } +} diff --git a/app/src/main/java/io/github/sankalp/lunox/utils/AccessibilityUtils.java b/app/src/main/java/io/github/sankalp/lunox/utils/AccessibilityUtils.java new file mode 100644 index 0000000..fcaa98f --- /dev/null +++ b/app/src/main/java/io/github/sankalp/lunox/utils/AccessibilityUtils.java @@ -0,0 +1,109 @@ +/* + * Lunox Launcher + * Copyright (C) 2024 Sankalp + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package io.github.sankalp.lunox.utils; + +import android.content.Context; +import android.content.Intent; +import android.provider.Settings; +import android.util.Log; +import android.view.accessibility.AccessibilityManager; + +import io.github.sankalp.lunox.services.LockScreenAccessibilityService; + +/** + * Utility class for accessibility service operations + */ +public class AccessibilityUtils { + + private static final String TAG = "AccessibilityUtils"; + + /** + * Check if our accessibility service is enabled + */ + public static boolean isAccessibilityServiceEnabled(Context context) { + AccessibilityManager am = (AccessibilityManager) context.getSystemService(Context.ACCESSIBILITY_SERVICE); + if (am == null) { + return false; + } + + // Check if accessibility is enabled and our service is in the enabled services list + String enabledServices = Settings.Secure.getString( + context.getContentResolver(), + Settings.Secure.ENABLED_ACCESSIBILITY_SERVICES + ); + + if (enabledServices == null || enabledServices.isEmpty()) { + return false; + } + + String packageName = context.getPackageName(); + String serviceName = LockScreenAccessibilityService.class.getName(); + String fullServiceName = packageName + "/" + serviceName; + + // Check if our service is in the enabled services list + return enabledServices.contains(fullServiceName); + } + + /** + * Open accessibility settings to enable our service + */ + public static void openAccessibilitySettings(Context context) { + try { + Intent intent = new Intent(Settings.ACTION_ACCESSIBILITY_SETTINGS); + intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); + context.startActivity(intent); + } catch (Exception e) { + Log.e(TAG, "Failed to open accessibility settings", e); + } + } + + /** + * Request lock screen action through accessibility service + */ + public static boolean requestLockScreen(Context context) { + if (!isAccessibilityServiceEnabled(context)) { + Log.w(TAG, "Accessibility service not enabled"); + return false; + } + + LockScreenAccessibilityService service = LockScreenAccessibilityService.getInstance(); + if (service != null) { + service.lockScreen(); + return true; + } else { + // Try to start the service with intent + try { + Intent intent = new Intent(context, LockScreenAccessibilityService.class); + intent.setAction(LockScreenAccessibilityService.ACTION_LOCK_SCREEN); + context.startService(intent); + return true; + } catch (Exception e) { + Log.e(TAG, "Failed to start accessibility service", e); + return false; + } + } + } + + /** + * Check if accessibility service is running + */ + public static boolean isServiceRunning() { + return LockScreenAccessibilityService.isServiceRunning(); + } +} diff --git a/app/src/main/java/io/github/sankalp/lunox/utils/DbUtils.java b/app/src/main/java/io/github/sankalp/lunox/utils/DbUtils.java index 78d82ad..33f9b2c 100644 --- a/app/src/main/java/io/github/sankalp/lunox/utils/DbUtils.java +++ b/app/src/main/java/io/github/sankalp/lunox/utils/DbUtils.java @@ -62,6 +62,7 @@ public class DbUtils { private static final String APPS_COLORS_DEFAULT = "apps_color_default"; private static final String APPS_SORTS_TYPE = "apps_sorts_types"; private static final String PERMISSION_DIALOG_SHOWN = "permission_dialog_shown"; + private static final String DOUBLE_TAP_TO_LOCK = "double_tap_to_lock"; public static void init(Context context) { @@ -392,6 +393,20 @@ public class DbUtils { SpUtils.getInstance().putBoolean(PERMISSION_DIALOG_SHOWN, shown); } + /** + * Check if double tap to lock is enabled + */ + public static boolean isDoubleTapToLockEnabled() { + return SpUtils.getInstance().getBoolean(DOUBLE_TAP_TO_LOCK, false); + } + + /** + * Set double tap to lock preference + */ + public static void setDoubleTapToLock(boolean enabled) { + SpUtils.getInstance().putBoolean(DOUBLE_TAP_TO_LOCK, enabled); + } + // a simple ciphered counter: "opening counter" is a private thing // rest is on device security private static String codeCount(int count) { diff --git a/app/src/main/java/io/github/sankalp/lunox/utils/Gestures.java b/app/src/main/java/io/github/sankalp/lunox/utils/Gestures.java index dfcba81..1571f80 100644 --- a/app/src/main/java/io/github/sankalp/lunox/utils/Gestures.java +++ b/app/src/main/java/io/github/sankalp/lunox/utils/Gestures.java @@ -30,12 +30,20 @@ public class Gestures extends GestureDetector.SimpleOnGestureListener { private final GestureDetector detector; private final OnSwipeListener listener; + private final OnDoubleTapListener doubleTapListener; public Gestures(Activity context, OnSwipeListener onSwipeListener) { + this(context, onSwipeListener, null); + } + + public Gestures(Activity context, + OnSwipeListener onSwipeListener, + OnDoubleTapListener onDoubleTapListener) { this.detector = new GestureDetector(context, this); this.listener = onSwipeListener; + this.doubleTapListener = onDoubleTapListener; } public void onTouchEvent(MotionEvent event) { @@ -73,8 +81,14 @@ public class Gestures extends GestureDetector.SimpleOnGestureListener { return consumed; } - - + @Override + public boolean onDoubleTap(MotionEvent e) { + if (doubleTapListener != null) { + doubleTapListener.onDoubleTap(e); + return true; + } + return super.onDoubleTap(e); + } public enum Direction { SWIPE_UP, SWIPE_DOWN, SWIPE_LEFT, SWIPE_RIGHT @@ -84,4 +98,8 @@ public class Gestures extends GestureDetector.SimpleOnGestureListener { void onSwipe(Direction direction); } + public interface OnDoubleTapListener { + void onDoubleTap(MotionEvent e); + } + } \ No newline at end of file diff --git a/app/src/main/res/drawable/dialog_background.xml b/app/src/main/res/drawable/dialog_background.xml new file mode 100644 index 0000000..5f337f2 --- /dev/null +++ b/app/src/main/res/drawable/dialog_background.xml @@ -0,0 +1,6 @@ + + + + + diff --git a/app/src/main/res/layout/dialog_double_tap_lock.xml b/app/src/main/res/layout/dialog_double_tap_lock.xml new file mode 100644 index 0000000..b31e273 --- /dev/null +++ b/app/src/main/res/layout/dialog_double_tap_lock.xml @@ -0,0 +1,80 @@ + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/layout/dialog_global_settings.xml b/app/src/main/res/layout/dialog_global_settings.xml index 92c95bb..60d5042 100644 --- a/app/src/main/res/layout/dialog_global_settings.xml +++ b/app/src/main/res/layout/dialog_global_settings.xml @@ -208,6 +208,23 @@ android:background="#DEDEDE" android:foregroundGravity="center_vertical|center_horizontal" /> + + + + From ColorSniffer App Size for this entry + + + Double Tap Lock + Double Tap Lock:On + Double Tap Lock:Off + + + Lunox Accessibility Service for lock screen functionality. This service allows double tap to lock the screen. \ No newline at end of file diff --git a/app/src/main/res/xml/accessibility_service_config.xml b/app/src/main/res/xml/accessibility_service_config.xml new file mode 100644 index 0000000..c54b847 --- /dev/null +++ b/app/src/main/res/xml/accessibility_service_config.xml @@ -0,0 +1,11 @@ + +