🔧 This commit updates the app name to "Lunox" in multiple files, adds QUERY_ALL_PACKAGES and PACKAGE_USAGE_STATS permissions for improved app detection, and enhances the permissions handling with a comprehensive permission request dialog and better device admin management.

This commit is contained in:
sankalp committed 2025-06-30 09:26:45 +05:45
1 parent 9fae48ad18
commit 26e5320d45
17 files changed
+411 -366

No files matched your search

+2 -2
View File
@@ -12,11 +12,11 @@ jobs:
steps:
- uses: actions/checkout@v4
- name: set up JDK 11
- name: set up JDK 17
uses: actions/setup-java@v4
with:
distribution: 'temurin'
java-version: '11'
java-version: '17'
- uses: actions/cache@v4
with:
path: |
+16 -20
View File
@@ -2,52 +2,48 @@ apply plugin: 'com.android.application'
android {
namespace "io.github.sankalp.lunox"
compileSdkVersion 34
buildToolsVersion "34.0.0"
defaultConfig {
applicationId "io.github.sankalp.lunox"
minSdkVersion 14
minSdkVersion 26
targetSdkVersion 34
versionCode 19
versionName "0.19"
//resConfigs "en", "de"
buildConfigField "boolean", "enableColorSniffer", "false"
}
buildFeatures {
buildConfig true
}
buildTypes {
debug {
def workingBranch = getGitWorkingBranch()
def normalizedWorkingBranch = workingBranch.replaceFirst("^[^A-Za-z]+", "").replaceAll("[^0-9A-Za-z]+", "")
if (normalizedWorkingBranch.isEmpty() || workingBranch == "master" ) {
applicationIdSuffix ".debug"
resValue "string", "app_name", "Last Launcher Dev"
} else {
archivesBaseName = 'Last_Launcher_' + normalizedWorkingBranch
applicationIdSuffix ".debug." + normalizedWorkingBranch
resValue "string", "app_name", "Last Launcher-" + workingBranch
}
applicationIdSuffix ".debug"
resValue "string", "app_name", "Lunox Dev"
debuggable true
jniDebuggable true
versionNameSuffix "-debug"
minifyEnabled false
shrinkResources false
}
release {
debuggable false
jniDebuggable false
minifyEnabled true
shrinkResources true
minifyEnabled false
shrinkResources false
zipAlignEnabled true
resValue "string", "app_name", "Last Launcher"
resValue "string", "app_name", "Lunox"
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
sourceCompatibility JavaVersion.VERSION_11
targetCompatibility JavaVersion.VERSION_11
}
lintOptions {
@@ -59,7 +55,7 @@ android {
variant.outputs.all {
def date = new Date()
def formattedDate = date.format('yyyyMMddHHmmss')
outputFileName = "Last-Launcher-${variant.name}-${variant.versionName}-${formattedDate}.apk"
outputFileName = "Lunox-${variant.name}-${variant.versionName}-${formattedDate}.apk"
}
}
packagingOptions {
@@ -69,7 +65,7 @@ android {
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation project(':flowlayout:layouts')
debugImplementation 'com.squareup.leakcanary:leakcanary-android:2.2'
debugImplementation 'com.squareup.leakcanary:leakcanary-android:2.13'
}
static String getGitWorkingBranch() {
+7 -2
View File
@@ -1,7 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
package="io.github.sankalp.lunox">
xmlns:tools="http://schemas.android.com/tools">
<uses-permission android:name="com.android.launcher.permission.INSTALL_SHORTCUT" />
<uses-permission android:name="com.android.launcher.permission.UNINSTALL_SHORTCUT" />
@@ -10,6 +9,11 @@
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="android.permission.BIND_DEVICE_ADMIN" />
<!-- Permissions for app detection -->
<uses-permission android:name="android.permission.QUERY_ALL_PACKAGES" />
<uses-permission android:name="android.permission.PACKAGE_USAGE_STATS"
tools:ignore="ProtectedPermissions" />
<application
android:allowBackup="true"
android:clearTaskOnLaunch="true"
@@ -21,6 +25,7 @@
<activity
android:name=".LauncherActivity"
android:exported="true"
android:excludeFromRecents="true"
android:label="@string/app_name"
android:launchMode="singleTask"
@@ -21,6 +21,8 @@ package io.github.sankalp.lunox;
import android.annotation.SuppressLint;
import android.annotation.TargetApi;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.AppOpsManager;
import android.app.Dialog;
import android.content.BroadcastReceiver;
import android.content.ClipData;
@@ -40,6 +42,8 @@ import android.os.Build;
import android.os.Bundle;
import android.os.ParcelFileDescriptor;
import android.os.PowerManager;
import android.provider.Settings;
import android.provider.Settings.Global;
import android.text.Editable;
import android.text.SpannableString;
import android.text.TextWatcher;
@@ -248,6 +252,9 @@ public class LauncherActivity extends Activity implements View.OnClickListener,
// initGestures();
// Check permissions before loading apps
checkAndRequestPermissions();
// loads the apps
loadApps();
// register the receiver for installed, uninstall, update apps and shortcut pwa add
@@ -286,12 +293,8 @@ public class LauncherActivity extends Activity implements View.OnClickListener,
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
switch (theme) {
case R.style.White:
case R.style.WhiteOnGrey:
case R.style.BlackOnGrey: {
getWindow().getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR);
}
if (theme == R.style.White || theme == R.style.WhiteOnGrey || theme == R.style.BlackOnGrey) {
getWindow().getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR);
}
}
}
@@ -319,6 +322,15 @@ public class LauncherActivity extends Activity implements View.OnClickListener,
PackageManager pm = getPackageManager();
List<ResolveInfo> activities = pm.queryIntentActivities(startupIntent, 0);
// For Android 11+ (API 30+), also try alternative method if first method returns few apps
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R && activities.size() < 10) {
// Try alternative method for better app detection
List<ResolveInfo> alternativeActivities = pm.queryIntentActivities(startupIntent, PackageManager.MATCH_ALL);
if (alternativeActivities.size() > activities.size()) {
activities = alternativeActivities;
}
}
// check whether our app list is already initialized if yes then clear this(when new app or shortcut installed)
if (mAppsList != null) {
mAppsList.clear();
@@ -547,14 +559,20 @@ public class LauncherActivity extends Activity implements View.OnClickListener,
@Override
protected void onResume() {
super.onResume();
if (searching) {
mSearchBox.setVisibility(View.GONE);
searching = false;
imm.hideSoftInputFromWindow(mSearchBox.getWindowToken(), 0);
mHomeLayout.setPadding(DbUtils.getPaddingLeft(), DbUtils.getPaddingTop(), DbUtils.getPaddingRight(), DbUtils.getPaddingBottom());
sortApps(DbUtils.getSortsTypes());
// Check if we need to reload apps (e.g., after returning from settings)
if (mAppsList != null && mAppsList.size() < 10) {
// If we have very few apps, try reloading in case permissions were granted
loadApps();
}
// Check if search box is visible and hide it if needed
if (mSearchBox.getVisibility() == View.VISIBLE) {
mSearchBox.setVisibility(View.GONE);
mHomeLayout.setPadding(DbUtils.getPaddingLeft(), DbUtils.getPaddingTop(), DbUtils.getPaddingRight(), DbUtils.getPaddingBottom());
}
// Reset search state
searching = false;
}
@Override
@@ -637,38 +655,29 @@ public class LauncherActivity extends Activity implements View.OnClickListener,
}
popupMenu.setOnMenuItemClickListener(menuItem -> {
switch (menuItem.getItemId()) {
case R.id.menu_color:
changeColorSize(activityName, view);
break;
case R.id.menu_rename:
renameApp(activityName, view.getText().toString());
break;
case R.id.menu_freeze_size:
freezeAppSize(activityName);
break;
case R.id.menu_hide:
hideApp(activityName);
break;
case R.id.menu_uninstall:
if (view.isShortcut()) {
removeShortcut(view);
} else {
uninstallApp(activityName);
}
break;
case R.id.menu_app_info:
showAppInfo(activityName);
break;
case R.id.menu_reset_to_default:
resetApp(activityName);
break;
case R.id.menu_reset_color:
resetAppColor(activityName);
break;
default:
return true;
int id = menuItem.getItemId();
if (id == R.id.menu_color) {
changeColorSize(activityName, view);
} else if (id == R.id.menu_rename) {
renameApp(activityName, view.getText().toString());
} else if (id == R.id.menu_freeze_size) {
freezeAppSize(activityName);
} else if (id == R.id.menu_hide) {
hideApp(activityName);
} else if (id == R.id.menu_uninstall) {
if (view.isShortcut()) {
removeShortcut(view);
} else {
uninstallApp(activityName);
}
} else if (id == R.id.menu_app_info) {
showAppInfo(activityName);
} else if (id == R.id.menu_reset_to_default) {
resetApp(activityName);
} else if (id == R.id.menu_reset_color) {
resetAppColor(activityName);
} else {
return true;
}
return true;
});
@@ -893,7 +902,11 @@ public class LauncherActivity extends Activity implements View.OnClickListener,
loadApps();
}
};
registerReceiver(broadcastReceiverAppInstall, intentFilter);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
registerReceiver(broadcastReceiverAppInstall, intentFilter, Context.RECEIVER_NOT_EXPORTED);
} else {
registerReceiver(broadcastReceiverAppInstall, intentFilter);
}
}
//shortcut install receiver
@@ -922,7 +935,11 @@ public class LauncherActivity extends Activity implements View.OnClickListener,
}
}
};
registerReceiver(broadcastReceiverShortcutInstall, filter);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
registerReceiver(broadcastReceiverShortcutInstall, filter, Context.RECEIVER_NOT_EXPORTED);
} else {
registerReceiver(broadcastReceiverShortcutInstall, filter);
}
}
}
@@ -1314,4 +1331,110 @@ public class LauncherActivity extends Activity implements View.OnClickListener,
return null;
}
}
/**
* Check and request necessary permissions for app detection
*/
private void checkAndRequestPermissions() {
// Check if permissions dialog was already shown
if (DbUtils.isPermissionDialogShown()) {
return;
}
// Create a comprehensive permission request dialog
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setTitle("Welcome to Lunox! 🚀");
builder.setMessage("To provide the best experience, Lunox needs a few permissions:\n\n" +
"📱 **Usage Access**: To show all your installed apps\n" +
"🔒 **Device Admin**: To manage app freezing and advanced features\n\n" +
"These permissions help Lunox work properly and show all your apps.");
builder.setIcon(android.R.drawable.ic_dialog_info);
builder.setCancelable(false);
builder.setPositiveButton("Grant Permissions", (dialog, which) -> {
requestPermissions();
});
builder.setNegativeButton("Skip for Now", (dialog, which) -> {
DbUtils.setPermissionDialogShown(true);
});
AlertDialog dialog = builder.create();
dialog.show();
}
/**
* Request all necessary permissions
*/
private void requestPermissions() {
// Check and request Usage Access permission
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP_MR1) {
AppOpsManager appOps = (AppOpsManager) getSystemService(Context.APP_OPS_SERVICE);
int mode = appOps.checkOpNoThrow(AppOpsManager.OPSTR_GET_USAGE_STATS,
android.os.Process.myUid(), getPackageName());
if (mode != AppOpsManager.MODE_ALLOWED) {
showUsageAccessDialog();
}
}
// Check and request Device Admin permission
if (!DeviceAdminManager.isDeviceAdminActive(this)) {
showDeviceAdminDialog();
}
DbUtils.setPermissionDialogShown(true);
}
/**
* Show dialog to guide user to enable usage access
*/
private void showUsageAccessDialog() {
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setTitle("📱 Usage Access Required");
builder.setMessage("To show all your installed apps, please enable 'Usage Access' for Lunox:\n\n" +
"1. Tap 'Open Settings'\n" +
"2. Find 'Lunox Dev' in the list\n" +
"3. Toggle 'Allow usage access' ON\n" +
"4. Return to Lunox\n\n" +
"This helps Lunox detect all your apps properly.");
builder.setIcon(android.R.drawable.ic_menu_manage);
builder.setCancelable(false);
builder.setPositiveButton("Open Settings", (dialog, which) -> {
Intent intent = new Intent(Settings.ACTION_USAGE_ACCESS_SETTINGS);
startActivity(intent);
});
builder.setNegativeButton("Later", null);
AlertDialog dialog = builder.create();
dialog.show();
}
/**
* Show dialog to guide user to enable device admin
*/
private void showDeviceAdminDialog() {
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setTitle("🔒 Device Admin Required");
builder.setMessage("Device Admin permission enables advanced features like:\n\n" +
"• App freezing functionality\n" +
"• Enhanced app management\n" +
"• Better system integration\n\n" +
"This permission is safe and only used for launcher features.");
builder.setIcon(android.R.drawable.ic_lock_lock);
builder.setCancelable(false);
builder.setPositiveButton("Enable Device Admin", (dialog, which) -> {
DeviceAdminManager.requestDeviceAdminPermission(this);
});
builder.setNegativeButton("Skip", null);
AlertDialog dialog = builder.create();
dialog.show();
}
}
@@ -53,19 +53,14 @@ public class ColorSnifferDialog extends Dialog implements View.OnClickListener {
@Override
public void onClick(View view) {
switch (view.getId()) {
case R.id.text_color_sniffer_on_off:
onOffColorSnifferCustomisation();
break;
case R.id.color_sniffer_clipboard:
launcherActivity.clipboardData();
break;
case R.id.color_sniffer_external_app: {
if (DbUtils.isExternalSourceColor())
startColorSnifferApp();
break;
}
int id = view.getId();
if (id == R.id.text_color_sniffer_on_off) {
onOffColorSnifferCustomisation();
} else if (id == R.id.color_sniffer_clipboard) {
launcherActivity.clipboardData();
} else if (id == R.id.color_sniffer_external_app) {
if (DbUtils.isExternalSourceColor())
startColorSnifferApp();
}
}
@@ -114,63 +114,43 @@ public class GlobalSettingsDialog extends Dialog implements View.OnClickListener
@Override
public void onClick(View view) {
switch (view.getId()) {
case R.id.settings_fonts:
fontSelection(view);
break;
case R.id.settings_themes:
showThemeDialog();
break;
case R.id.settings_color_sniffer: {
if (BuildConfig.enableColorSniffer)
showColorSnifferDialog();
else randomColor();
}
break;
case R.id.settings_sort_app_by: {
sortApps(view);
break;
}
case R.id.settings_color_size: {
showColorAndSizeDialog();
}
break;
case R.id.settings_freeze_size:
freezeAppsSize();
break;
case R.id.settings_hidden_apps:
hiddenApps();
break;
case R.id.settings_frozen_apps:
frozenApps();
break;
case R.id.settings_backup:
backup();
break;
case R.id.settings_restore:
restore();
break;
case R.id.settings_reset_to_defaults:
defaultSettings();
break;
case R.id.settings_alignment:
setFlowLayoutAlignment(view);
break;
case R.id.settings_padding:
launcherActivity.setPadding();
cancel();
break;
case R.id.settings_restart_launcher:
launcherActivity.recreate();
break;
int id = view.getId();
if (id == R.id.settings_fonts) {
fontSelection(view);
} else if (id == R.id.settings_themes) {
showThemeDialog();
} else if (id == R.id.settings_color_sniffer) {
if (BuildConfig.enableColorSniffer)
showColorSnifferDialog();
else randomColor();
} else if (id == R.id.settings_sort_app_by) {
sortApps(view);
} else if (id == R.id.settings_color_size) {
showColorAndSizeDialog();
} else if (id == R.id.settings_freeze_size) {
freezeAppsSize();
} else if (id == R.id.settings_hidden_apps) {
hiddenApps();
} else if (id == R.id.settings_frozen_apps) {
frozenApps();
} else if (id == R.id.settings_backup) {
backup();
} else if (id == R.id.settings_restore) {
restore();
} else if (id == R.id.settings_reset_to_defaults) {
defaultSettings();
} else if (id == R.id.settings_alignment) {
setFlowLayoutAlignment(view);
} else if (id == R.id.settings_padding) {
launcherActivity.setPadding();
cancel();
} else if (id == R.id.settings_restart_launcher) {
launcherActivity.recreate();
}
}
private void sortApps(View view) {
Context context;
// set theme
// if theme wallpaper ie transparent then we have to show other theme
if (DbUtils.getTheme() == R.style.Wallpaper)
context = new ContextThemeWrapper(getContext(), R.style.AppTheme);
else
@@ -180,29 +160,19 @@ public class GlobalSettingsDialog extends Dialog implements View.OnClickListener
popupMenu.getMenuInflater().inflate(R.menu.sort_apps_popups, popupMenu.getMenu());
popupMenu.setOnMenuItemClickListener(menuItem -> {
cancel();
switch (menuItem.getItemId()) {
case R.id.menu_sort_by_name:
launcherActivity.sortApps(Constants.SORT_BY_NAME);
break;
case R.id.menu_sort_by_opening_counts:
launcherActivity.sortApps(Constants.SORT_BY_OPENING_COUNTS);
break;
case R.id.menu_sort_by_color:
launcherActivity.sortApps(Constants.SORT_BY_COLOR);
break;
/* case R.id.menu_sort_by_customs:
launcherActivity.sortApps(LauncherActivity.SORT_BY_CUSTOM);
break;*/
case R.id.menu_sort_by_size:
launcherActivity.sortApps(Constants.SORT_BY_SIZE);
break;
case R.id.menu_sort_by_update_time:
launcherActivity.sortApps(Constants.SORT_BY_UPDATE_TIME);
break;
case R.id.menu_sort_by_recent_use:
launcherActivity.sortApps(Constants.SORT_BY_RECENT_OPEN);
break;
int id = menuItem.getItemId();
if (id == R.id.menu_sort_by_name) {
launcherActivity.sortApps(Constants.SORT_BY_NAME);
} else if (id == R.id.menu_sort_by_opening_counts) {
launcherActivity.sortApps(Constants.SORT_BY_OPENING_COUNTS);
} else if (id == R.id.menu_sort_by_color) {
launcherActivity.sortApps(Constants.SORT_BY_COLOR);
} else if (id == R.id.menu_sort_by_size) {
launcherActivity.sortApps(Constants.SORT_BY_SIZE);
} else if (id == R.id.menu_sort_by_update_time) {
launcherActivity.sortApps(Constants.SORT_BY_UPDATE_TIME);
} else if (id == R.id.menu_sort_by_recent_use) {
launcherActivity.sortApps(Constants.SORT_BY_RECENT_OPEN);
}
return true;
});
@@ -215,10 +185,7 @@ public class GlobalSettingsDialog extends Dialog implements View.OnClickListener
}
private void setFlowLayoutAlignment(View view) {
Context context;
// set theme
// if theme is wallpaper i.e. transparent then we have to show other theme:
if (DbUtils.getTheme() == R.style.Wallpaper)
context = new ContextThemeWrapper(getContext(), R.style.AppTheme);
else
@@ -228,21 +195,17 @@ public class GlobalSettingsDialog extends Dialog implements View.OnClickListener
popupMenu.getMenuInflater().inflate(R.menu.alignment_popup, popupMenu.getMenu());
popupMenu.setOnMenuItemClickListener(menuItem -> {
switch (menuItem.getItemId()) {
case R.id.menu_center:
launcherActivity.setFlowLayoutAlignment(Gravity.CENTER | Gravity.CENTER_HORIZONTAL | Gravity.CENTER_VERTICAL);
break;
case R.id.menu_end:
launcherActivity.setFlowLayoutAlignment(Gravity.END | Gravity.CENTER_VERTICAL);
break;
case R.id.menu_start:
launcherActivity.setFlowLayoutAlignment(Gravity.START | Gravity.CENTER_VERTICAL);
break;
int id = menuItem.getItemId();
if (id == R.id.menu_center) {
launcherActivity.setFlowLayoutAlignment(Gravity.CENTER | Gravity.CENTER_HORIZONTAL | Gravity.CENTER_VERTICAL);
} else if (id == R.id.menu_end) {
launcherActivity.setFlowLayoutAlignment(Gravity.END | Gravity.CENTER_VERTICAL);
} else if (id == R.id.menu_start) {
launcherActivity.setFlowLayoutAlignment(Gravity.START | Gravity.CENTER_VERTICAL);
}
return true;
});
popupMenu.show();
}
private void randomColor() {
@@ -363,10 +326,7 @@ public class GlobalSettingsDialog extends Dialog implements View.OnClickListener
}
private void fontSelection(View view) {
Context context;
// set theme
// if theme wallpaper ie transparent then we have to show other theme
if (DbUtils.getTheme() == R.style.Wallpaper)
context = new ContextThemeWrapper(getContext(), R.style.AppTheme);
else
@@ -376,24 +336,20 @@ public class GlobalSettingsDialog extends Dialog implements View.OnClickListener
popupMenu.getMenuInflater().inflate(R.menu.font_selection_popup, popupMenu.getMenu());
popupMenu.setOnMenuItemClickListener(menuItem -> {
switch (menuItem.getItemId()) {
case R.id.menu_choose_fonts:
setFonts();
break;
case R.id.menu_default_font: {
if (DbUtils.isFontExists()) {
DbUtils.removeFont();
launcherActivity.setFont();
launcherActivity.loadApps();
cancel();
break;
}
int id = menuItem.getItemId();
if (id == R.id.menu_choose_fonts) {
setFonts();
} else if (id == R.id.menu_default_font) {
if (DbUtils.isFontExists()) {
DbUtils.removeFont();
launcherActivity.setFont();
launcherActivity.loadApps();
cancel();
}
}
return true;
});
popupMenu.show();
}
}
@@ -127,101 +127,79 @@ public class PaddingDialog extends Dialog implements View.OnLongClickListener, V
@Override
public boolean onLongClick(View button) {
switch (button.getId()) {
case R.id.btn_left_minus:
runner((TextView) button, left, -2, Padding.LEFT);
break;
case R.id.btn_left_plus:
runner((TextView) button, left, 2, Padding.LEFT);
break;
case R.id.btn_right_minus:
runner((TextView) button, right, -2, Padding.RIGHT);
break;
case R.id.btn_right_plus:
runner((TextView) button, right, 2, Padding.RIGHT);
break;
case R.id.btn_top_minus:
runner((TextView) button, top, -2, Padding.TOP);
break;
case R.id.btn_top_plus:
runner((TextView) button, top, 2, Padding.TOP);
break;
case R.id.btn_bottom_minus:
runner((TextView) button, bottom, -2, Padding.BOTTOM);
break;
case R.id.btn_bottom_plus:
runner((TextView) button, bottom, 2, Padding.BOTTOM);
break;
int id = button.getId();
if (id == R.id.btn_left_minus) {
runner((TextView) button, left, -2, Padding.LEFT);
} else if (id == R.id.btn_left_plus) {
runner((TextView) button, left, 2, Padding.LEFT);
} else if (id == R.id.btn_right_minus) {
runner((TextView) button, right, -2, Padding.RIGHT);
} else if (id == R.id.btn_right_plus) {
runner((TextView) button, right, 2, Padding.RIGHT);
} else if (id == R.id.btn_top_minus) {
runner((TextView) button, top, -2, Padding.TOP);
} else if (id == R.id.btn_top_plus) {
runner((TextView) button, top, 2, Padding.TOP);
} else if (id == R.id.btn_bottom_minus) {
runner((TextView) button, bottom, -2, Padding.BOTTOM);
} else if (id == R.id.btn_bottom_plus) {
runner((TextView) button, bottom, 2, Padding.BOTTOM);
}
return true;
}
@Override
public void onClick(View view) {
switch (view.getId()) {
case R.id.btn_left_minus:
//decrease the value as minus button is pressed
leftInt--;
// check the lower limit i.e. 0
if (leftInt < MIN_PADDING) {
leftInt = MIN_PADDING;
}
//reflect it on screen
left.setText(String.valueOf(leftInt));
break;
case R.id.btn_left_plus:
leftInt++;
// check the upper limit
if (leftInt > MAX_PADDING_LEFT) {
leftInt = MAX_PADDING_LEFT;
}
left.setText(String.valueOf(leftInt));
break;
case R.id.btn_right_minus:
rightInt--;
if (rightInt < MIN_PADDING) {
rightInt = MIN_PADDING;
}
right.setText(String.valueOf(rightInt));
break;
case R.id.btn_right_plus:
rightInt++;
if (rightInt > MAX_PADDING_RIGHT) {
rightInt = MAX_PADDING_RIGHT;
}
right.setText(String.valueOf(rightInt));
break;
case R.id.btn_top_minus:
topInt--;
if (topInt < MIN_PADDING) {
topInt = MIN_PADDING;
}
top.setText(String.valueOf(topInt));
break;
case R.id.btn_top_plus:
topInt++;
if (topInt > MAX_PADDING_TOP) {
topInt = MAX_PADDING_TOP;
}
top.setText(String.valueOf(topInt));
break;
case R.id.btn_bottom_minus:
bottomInt--;
if (bottomInt < MIN_PADDING) {
bottomInt = MIN_PADDING;
}
bottom.setText(String.valueOf(bottomInt));
break;
case R.id.btn_bottom_plus:
bottomInt++;
if (bottomInt > MAX_PADDING_BOTTOM) {
bottomInt = MAX_PADDING_BOTTOM;
}
bottom.setText(String.valueOf(bottomInt));
break;
int id = view.getId();
if (id == R.id.btn_left_minus) {
leftInt--;
if (leftInt < MIN_PADDING) {
leftInt = MIN_PADDING;
}
left.setText(String.valueOf(leftInt));
} else if (id == R.id.btn_left_plus) {
leftInt++;
if (leftInt > MAX_PADDING_LEFT) {
leftInt = MAX_PADDING_LEFT;
}
left.setText(String.valueOf(leftInt));
} else if (id == R.id.btn_right_minus) {
rightInt--;
if (rightInt < MIN_PADDING) {
rightInt = MIN_PADDING;
}
right.setText(String.valueOf(rightInt));
} else if (id == R.id.btn_right_plus) {
rightInt++;
if (rightInt > MAX_PADDING_RIGHT) {
rightInt = MAX_PADDING_RIGHT;
}
right.setText(String.valueOf(rightInt));
} else if (id == R.id.btn_top_minus) {
topInt--;
if (topInt < MIN_PADDING) {
topInt = MIN_PADDING;
}
top.setText(String.valueOf(topInt));
} else if (id == R.id.btn_top_plus) {
topInt++;
if (topInt > MAX_PADDING_TOP) {
topInt = MAX_PADDING_TOP;
}
top.setText(String.valueOf(topInt));
} else if (id == R.id.btn_bottom_minus) {
bottomInt--;
if (bottomInt < MIN_PADDING) {
bottomInt = MIN_PADDING;
}
bottom.setText(String.valueOf(bottomInt));
} else if (id == R.id.btn_bottom_plus) {
bottomInt++;
if (bottomInt > MAX_PADDING_BOTTOM) {
bottomInt = MAX_PADDING_BOTTOM;
}
bottom.setText(String.valueOf(bottomInt));
}
// apply all padding to home layout
homeLayout.setPadding(leftInt, topInt, rightInt, bottomInt);
}
@@ -51,31 +51,23 @@ public class ThemeSelectorDialog extends Dialog implements View.OnClickListener
@Override
public void onClick(View view) {
switch (view.getId()) {
case R.id.t1:
setTheme(R.style.AppTheme);
break;
case R.id.t2:
setTheme(R.style.Wallpaper);
break;
case R.id.t3:
setTheme(R.style.Black);
break;
case R.id.t4:
setTheme(R.style.White);
break;
case R.id.t5:
setTheme(R.style.WhiteOnGrey);
break;
case R.id.t6:
setTheme(R.style.BlackOnGrey);
break;
case R.id.t35:
setTheme(R.style.Hacker_green);
break;
case R.id.t36:
setTheme(R.style.Hacker_red);
break;
int id = view.getId();
if (id == R.id.t1) {
setTheme(R.style.AppTheme);
} else if (id == R.id.t2) {
setTheme(R.style.Wallpaper);
} else if (id == R.id.t3) {
setTheme(R.style.Black);
} else if (id == R.id.t4) {
setTheme(R.style.White);
} else if (id == R.id.t5) {
setTheme(R.style.WhiteOnGrey);
} else if (id == R.id.t6) {
setTheme(R.style.BlackOnGrey);
} else if (id == R.id.t35) {
setTheme(R.style.Hacker_green);
} else if (id == R.id.t36) {
setTheme(R.style.Hacker_red);
}
}
@@ -61,6 +61,7 @@ public class DbUtils {
private static final String GLOBAL_SIZE_ADDITION_EXTRA = "global_size_addition_extra";
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";
public static void init(Context context) {
@@ -166,55 +167,44 @@ public class DbUtils {
public static int getTheme() {
int theme = SpUtils.getInstance().getInt(LAUNCHER_THEME, 2);
switch (theme) {
case 1:
return R.style.Wallpaper;
case 2:
return R.style.AppTheme;
case 3:
return R.style.White;
case 4:
return R.style.WhiteOnGrey;
case 5:
return R.style.Black;
case 6:
return R.style.BlackOnGrey;
case 7:
return R.style.Hacker_green;
case 8:
return R.style.Hacker_red;
if (theme == 1) {
return R.style.Wallpaper;
} else if (theme == 2) {
return R.style.AppTheme;
} else if (theme == 3) {
return R.style.White;
} else if (theme == 4) {
return R.style.WhiteOnGrey;
} else if (theme == 5) {
return R.style.Black;
} else if (theme == 6) {
return R.style.BlackOnGrey;
} else if (theme == 7) {
return R.style.Hacker_green;
} else if (theme == 8) {
return R.style.Hacker_red;
}
return R.style.AppTheme;
}
public static void setTheme(int id) {
int theme = 0;
switch (id) {
case R.style.Wallpaper:
theme = 1;
break;
case R.style.AppTheme:
theme = 2;
break;
case R.style.White:
theme = 3;
break;
case R.style.WhiteOnGrey:
theme = 4;
break;
case R.style.Black:
theme = 5;
break;
case R.style.BlackOnGrey:
theme = 6;
break;
case R.style.Hacker_green:
theme = 7;
break;
case R.style.Hacker_red:
theme = 8;
break;
if (id == R.style.Wallpaper) {
theme = 1;
} else if (id == R.style.AppTheme) {
theme = 2;
} else if (id == R.style.White) {
theme = 3;
} else if (id == R.style.WhiteOnGrey) {
theme = 4;
} else if (id == R.style.Black) {
theme = 5;
} else if (id == R.style.BlackOnGrey) {
theme = 6;
} else if (id == R.style.Hacker_green) {
theme = 7;
} else if (id == R.style.Hacker_red) {
theme = 8;
}
SpUtils.getInstance().putInt(LAUNCHER_THEME, theme);
}
@@ -388,6 +378,20 @@ public class DbUtils {
SpUtils.getInstance().putInt(APPS_SORTS_TYPE, type);
}
/**
* Check if permission dialog has been shown
*/
public static boolean isPermissionDialogShown() {
return SpUtils.getInstance().getBoolean(PERMISSION_DIALOG_SHOWN, false);
}
/**
* Set permission dialog as shown
*/
public static void setPermissionDialogShown(boolean shown) {
SpUtils.getInstance().putBoolean(PERMISSION_DIALOG_SHOWN, shown);
}
// a simple ciphered counter: "opening counter" is a private thing
// rest is on device security
private static String codeCount(int count) {
+1 -1
View File
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="app_name">Last Launcher</string>
<string name="app_name">Lunox</string>
<string name="action_settings">Ajustes</string>
<!--App information related strings-->
+8 -2
View File
@@ -91,9 +91,15 @@
<string name="recently_first">Recently first</string>
<string name="restart_launcher">Restart Launcher</string>
<!-- Device Admin strings -->
<string name="device_admin_label">Last Launcher Device Admin</string>
<string name="device_admin_label">Lunox Device Admin</string>
<string name="device_admin_description">Required for double-tap to lock screen functionality</string>
<string name="device_admin_enable">Enable Device Admin</string>
<string name="device_admin_disabled">Device Admin is required for lock screen functionality</string>
<!-- Frozen apps dialog title -->
<string name="freezed_apps">Freezed Apps</string>
<!-- Color source from ColorSniffer app -->
<string name="from_colorsniffer_app">From ColorSniffer App</string>
<!-- Size setting for individual app entry -->
<string name="size_for_this_entry">Size for this entry</string>
</resources>
-13
View File
@@ -120,17 +120,4 @@
</style>
<!--<style name="myDialog">
<item name="android:windowFrame">@null</item>
<item name="android:windowBackground">@android:color/transparent</item>
<item name="android:windowIsFloating">true</item>
<item name="android:windowContentOverlay">@null</item>
<item name="android:windowTitleStyle">@null</item>
<item name="android:windowAnimationStyle">@android:style/Animation.Dialog</item>
<item name="android:windowSoftInputMode">stateUnspecified|adjustPan</item>
<item name="android:backgroundDimEnabled">false</item>
<item name="android:background">@android:color/transparent</item>
</style>-->
</resources>
+3 -3
View File
@@ -3,10 +3,10 @@
buildscript {
repositories {
google()
jcenter()
mavenCentral()
}
dependencies {
classpath 'com.android.tools.build:gradle:7.4.2'
classpath 'com.android.tools.build:gradle:8.1.4'
// NOTE: Do not place your application dependencies here; they belong
@@ -17,7 +17,7 @@ buildscript {
allprojects {
repositories {
google()
jcenter()
mavenCentral()
maven { url 'https://jitpack.io' }
}
}
+1
View File
@@ -1,6 +1,7 @@
apply plugin: 'com.android.library'
android {
namespace "org.apmem.tools.layouts"
compileSdkVersion 29
buildToolsVersion "35.0.1"
@@ -1,2 +1,2 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest package="org.apmem.tools.layouts" />
<manifest />
+2
View File
@@ -19,6 +19,7 @@
#
org.gradle.parallel=true
org.gradle.jvmargs=-Xmx1024m -Dfile.encoding=UTF-8
org.gradle.java.home=/usr/lib/jvm/java-17-openjdk
android.useAndroidX=false
android.enableJetifier=false
#exerimental
@@ -28,3 +29,4 @@ android.enableR8.fullMode=true
android.enableResourceOptimizations=true
#enable
android.nonTransitiveRClass=true
android.suppressUnsupportedCompileSdk=34
+1 -1
View File
@@ -3,4 +3,4 @@ distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-7.6.2-all.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-8.4-all.zip