From c31aa722b69c0c9c2d906fb448fd0c6ac04c8db3 Mon Sep 17 00:00:00 2001 From: Ratul Hasan Date: Fri, 7 Nov 2025 14:17:09 +0600 Subject: [PATCH 01/27] move fonts to res --- app/src/main/assets/fonts/google_sans_bold.ttf | Bin 92096 -> 0 bytes app/src/main/res/font/product_sans_medium.ttf | Bin 0 -> 118508 bytes .../font/product_sans_regular.ttf} | Bin 3 files changed, 0 insertions(+), 0 deletions(-) delete mode 100644 app/src/main/assets/fonts/google_sans_bold.ttf create mode 100644 app/src/main/res/font/product_sans_medium.ttf rename app/src/main/{assets/fonts/google_sans_regular.ttf => res/font/product_sans_regular.ttf} (100%) diff --git a/app/src/main/assets/fonts/google_sans_bold.ttf b/app/src/main/assets/fonts/google_sans_bold.ttf deleted file mode 100644 index 96619df92e347c5852b6c50d71c362e4404c4c3c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 92096 zcmcG%33wdEnKxe5b4xR$IW&jn?3tcJ(r9$dNSe`MX)If^Z26FE$(C$mOSZ7_*cc-l zYz~9LfQ>jpNWvzBBy51dLY9>wOB`~Mgb=bJ2_bCACgdQ=?y`Jg!;)i(gJ=G~s_v0S z!esaPp6@TIyZWeltLnY#t+(E45lRTL;iM+wz`*Fb6OX4qLg?NH@zl3!W&ePAxn(t> z)oXFTX4UY9OWyZ;*pyYT*_gy??0VN+8o-yrTFgg%1≤gS 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 literal 0 HcmV?d00001 diff --git a/app/src/main/assets/fonts/google_sans_regular.ttf b/app/src/main/res/font/product_sans_regular.ttf similarity index 100% rename from app/src/main/assets/fonts/google_sans_regular.ttf rename to app/src/main/res/font/product_sans_regular.ttf From 4f1452b8e90974f3586f61146197787097d21050 Mon Sep 17 00:00:00 2001 From: Ratul Hasan Date: Fri, 7 Nov 2025 14:19:16 +0600 Subject: [PATCH 02/27] add more events --- app/src/global/res/xml/accessibility.xml | 10 ++++++++++ app/src/main/res/xml/accessibility.xml | 12 ------------ 2 files changed, 10 insertions(+), 12 deletions(-) create mode 100644 app/src/global/res/xml/accessibility.xml delete mode 100644 app/src/main/res/xml/accessibility.xml diff --git a/app/src/global/res/xml/accessibility.xml b/app/src/global/res/xml/accessibility.xml new file mode 100644 index 0000000..7b4510d --- /dev/null +++ b/app/src/global/res/xml/accessibility.xml @@ -0,0 +1,10 @@ + + diff --git a/app/src/main/res/xml/accessibility.xml b/app/src/main/res/xml/accessibility.xml deleted file mode 100644 index 291139d..0000000 --- a/app/src/main/res/xml/accessibility.xml +++ /dev/null @@ -1,12 +0,0 @@ - - From 001e89e1aff1a824fc652164d00a55a4c04df6dc Mon Sep 17 00:00:00 2001 From: Ratul Hasan Date: Fri, 7 Nov 2025 14:19:55 +0600 Subject: [PATCH 03/27] move accessibility service to global version --- .../AccessibilityMonitoringService.java | 92 ------------------- .../AccessibilityMonitoringService.java | 89 ++++++++++++++++++ 2 files changed, 89 insertions(+), 92 deletions(-) delete mode 100644 app/src/main/java/io/github/ratul/topactivity/service/AccessibilityMonitoringService.java create mode 100644 app/src/main/java/io/github/ratul/topactivity/services/AccessibilityMonitoringService.java diff --git a/app/src/main/java/io/github/ratul/topactivity/service/AccessibilityMonitoringService.java b/app/src/main/java/io/github/ratul/topactivity/service/AccessibilityMonitoringService.java deleted file mode 100644 index 916d6e7..0000000 --- a/app/src/main/java/io/github/ratul/topactivity/service/AccessibilityMonitoringService.java +++ /dev/null @@ -1,92 +0,0 @@ -/* - * Copyright (C) 2022 Ratul Hasan - * - * 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.ratul.topactivity.service; - -import android.accessibilityservice.AccessibilityService; -import android.annotation.SuppressLint; -import android.content.Intent; -import android.view.accessibility.AccessibilityEvent; -import android.widget.Toast; -import io.github.ratul.topactivity.utils.WindowUtil; -import io.github.ratul.topactivity.utils.DatabaseUtil; -import io.github.ratul.topactivity.model.NotificationMonitor; -import android.content.pm.PackageManager; -import java.util.List; -import android.content.pm.ResolveInfo; -import android.content.Context; - -/** - * Created by Wen on 16/02/2017. - * Refactored by Ratul on 04/05/2022. - */ -public class AccessibilityMonitoringService extends AccessibilityService { - private static AccessibilityMonitoringService sInstance; - - public static AccessibilityMonitoringService getInstance() { - return sInstance; - } - - public boolean isPackageInstalled(String packageName) { - final PackageManager packageManager = getPackageManager(); - Intent intent = packageManager.getLaunchIntentForPackage(packageName); - if (intent == null) { - return false; - } - List list = packageManager.queryIntentActivities(intent, PackageManager.MATCH_DEFAULT_ONLY); - return list.size() > 0; - } - - public boolean isSystemClass(String className) { - try { - ClassLoader.getSystemClassLoader().loadClass(className); - return true; - } catch (ClassNotFoundException e) { - return false; - } - } - - @Override - public void onAccessibilityEvent(AccessibilityEvent event) { - if (WindowUtil.viewAdded && DatabaseUtil.isShowWindow() && DatabaseUtil.hasAccess()) { - String act1 = String.valueOf(event.getClassName()); - String act2 = String.valueOf(event.getPackageName()); - - if (isSystemClass(act1)) - return; - WindowUtil.show(this, act2, act1); - } - } - - @Override - public void onInterrupt() { - } - - @Override - protected void onServiceConnected() { - sInstance = this; - super.onServiceConnected(); - } - - @Override - public boolean onUnbind(Intent intent) { - sInstance = null; - WindowUtil.dismiss(this); - NotificationMonitor.cancelNotification(this); - sendBroadcast(new Intent(QuickSettingsTileService.ACTION_UPDATE_TITLE)); - return super.onUnbind(intent); - } -} diff --git a/app/src/main/java/io/github/ratul/topactivity/services/AccessibilityMonitoringService.java b/app/src/main/java/io/github/ratul/topactivity/services/AccessibilityMonitoringService.java new file mode 100644 index 0000000..2530dcd --- /dev/null +++ b/app/src/main/java/io/github/ratul/topactivity/services/AccessibilityMonitoringService.java @@ -0,0 +1,89 @@ +/* + * Copyright (C) 2022 Ratul Hasan + * + * 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.ratul.topactivity.services; + +import static io.github.ratul.topactivity.utils.NullSafety.isNullOrEmpty; + +import android.accessibilityservice.AccessibilityService; +import android.annotation.SuppressLint; +import android.content.Intent; +import android.util.Log; +import android.view.accessibility.AccessibilityEvent; + +import io.github.ratul.topactivity.BuildConfig; +import io.github.ratul.topactivity.utils.DatabaseUtil; +import io.github.ratul.topactivity.utils.WindowUtil; + +/** + * Created by Wen on 16/02/2017. + * Refactored by Ratul on 04/05/2022. + */ +@SuppressLint("AccessibilityPolicy") +public class AccessibilityMonitoringService extends AccessibilityService { + private static AccessibilityMonitoringService instance; + + public static AccessibilityMonitoringService getInstance() { + return instance; + } + + @Override + public void onAccessibilityEvent(AccessibilityEvent event) { + if (WindowUtil.isViewVisible() && DatabaseUtil.isShowingWindow()) { + CharSequence pkgName = event.getPackageName(); + CharSequence className = event.getClassName(); + + if (!isNullOrEmpty(pkgName) && + !isNullOrEmpty(className) && + !isSystemClass(className.toString())) { + if (BuildConfig.DEBUG) { + Log.d("AccessibilityService", "Pkg: " + pkgName + ", Class: " + className); + } + WindowUtil.show(this, pkgName.toString(), className.toString()); + } + } + } + + @Override + public void onInterrupt() { + } + + @Override + protected void onServiceConnected() { + instance = this; + super.onServiceConnected(); + } + + @Override + public void onRebind(Intent intent) { + instance = this; + super.onRebind(intent); + } + + @Override + public boolean onUnbind(Intent intent) { + instance = null; + return true; + } + + private boolean isSystemClass(String className) { + try { + return ClassLoader.getSystemClassLoader().loadClass(className) != null; + } catch (ClassNotFoundException e) { + return false; + } + } +} From 7b12cd36c4cbd2508bf047fe5e98d754357f2be5 Mon Sep 17 00:00:00 2001 From: Ratul Hasan Date: Fri, 7 Nov 2025 14:21:03 +0600 Subject: [PATCH 04/27] remove deprecated code and fix warnings --- app/build/bin/injected/AndroidManifest.xml | 159 --------------------- app/build/bin/merged/AndroidManifest.xml | 131 ----------------- app/src/global/AndroidManifest.xml | 20 +++ app/src/main/AndroidManifest.xml | 116 +++++---------- 4 files changed, 53 insertions(+), 373 deletions(-) delete mode 100644 app/build/bin/injected/AndroidManifest.xml delete mode 100644 app/build/bin/merged/AndroidManifest.xml create mode 100644 app/src/global/AndroidManifest.xml diff --git a/app/build/bin/injected/AndroidManifest.xml b/app/build/bin/injected/AndroidManifest.xml deleted file mode 100644 index c0ada5e..0000000 --- a/app/build/bin/injected/AndroidManifest.xml +++ /dev/null @@ -1,159 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/app/build/bin/merged/AndroidManifest.xml b/app/build/bin/merged/AndroidManifest.xml deleted file mode 100644 index 5188fe4..0000000 --- a/app/build/bin/merged/AndroidManifest.xml +++ /dev/null @@ -1,131 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/app/src/global/AndroidManifest.xml b/app/src/global/AndroidManifest.xml new file mode 100644 index 0000000..fbbdc2b --- /dev/null +++ b/app/src/global/AndroidManifest.xml @@ -0,0 +1,20 @@ + + + + + + + + + + + + + diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 113c201..5921b42 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -1,114 +1,64 @@ - - - + - - - - - - - - - - + + + + + android:roundIcon="@mipmap/ic_launcher_round" + android:supportsPictureInPicture="true" + android:theme="@style/BaseTheme"> + + android:launchMode="singleTask"> - - + + - - - - - + android:launchMode="singleInstance" + android:noHistory="true" + android:taskAffinity="" + android:theme="@style/TransparentTheme" /> - - - - - - + - - - + + android:value="true" /> - - - - + android:name=".receivers.NotificationReceiver" + android:exported="true" + android:permission="${applicationId}.DYNAMIC_RECEIVER_NOT_EXPORTED_PERMISSION" /> From 8e65e2c3566ea4e6bda1e4e06127ed2fc7f9e1df Mon Sep 17 00:00:00 2001 From: Ratul Hasan Date: Fri, 7 Nov 2025 14:23:30 +0600 Subject: [PATCH 05/27] remove obsolete resources --- app/src/main/res/anim/bottom_sheet_close.xml | 6 --- app/src/main/res/anim/bottom_sheet_enter.xml | 7 --- .../main/res/anim/fancy_animation_enter.xml | 6 --- .../main/res/anim/fancy_animation_exit.xml | 6 --- app/src/main/res/drawable/layers.xml | 29 ----------- app/src/main/res/values-night/colors.xml | 6 --- app/src/main/res/values-night/styles.xml | 6 --- app/src/main/res/values-v24/bools.xml | 4 -- app/src/main/res/values/bools.xml | 4 -- app/src/main/res/values/colors.xml | 13 ----- app/src/main/res/values/styles.xml | 48 ------------------- 11 files changed, 135 deletions(-) delete mode 100644 app/src/main/res/anim/bottom_sheet_close.xml delete mode 100644 app/src/main/res/anim/bottom_sheet_enter.xml delete mode 100644 app/src/main/res/anim/fancy_animation_enter.xml delete mode 100644 app/src/main/res/anim/fancy_animation_exit.xml delete mode 100644 app/src/main/res/drawable/layers.xml delete mode 100644 app/src/main/res/values-night/colors.xml delete mode 100644 app/src/main/res/values-night/styles.xml delete mode 100644 app/src/main/res/values-v24/bools.xml delete mode 100644 app/src/main/res/values/bools.xml delete mode 100644 app/src/main/res/values/colors.xml delete mode 100644 app/src/main/res/values/styles.xml diff --git a/app/src/main/res/anim/bottom_sheet_close.xml b/app/src/main/res/anim/bottom_sheet_close.xml deleted file mode 100644 index 9dab7af..0000000 --- a/app/src/main/res/anim/bottom_sheet_close.xml +++ /dev/null @@ -1,6 +0,0 @@ - - diff --git a/app/src/main/res/anim/bottom_sheet_enter.xml b/app/src/main/res/anim/bottom_sheet_enter.xml deleted file mode 100644 index ee4ef8d..0000000 --- a/app/src/main/res/anim/bottom_sheet_enter.xml +++ /dev/null @@ -1,7 +0,0 @@ - - - diff --git a/app/src/main/res/anim/fancy_animation_enter.xml b/app/src/main/res/anim/fancy_animation_enter.xml deleted file mode 100644 index e332395..0000000 --- a/app/src/main/res/anim/fancy_animation_enter.xml +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - diff --git a/app/src/main/res/anim/fancy_animation_exit.xml b/app/src/main/res/anim/fancy_animation_exit.xml deleted file mode 100644 index 3acb0c5..0000000 --- a/app/src/main/res/anim/fancy_animation_exit.xml +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - diff --git a/app/src/main/res/drawable/layers.xml b/app/src/main/res/drawable/layers.xml deleted file mode 100644 index b4f637e..0000000 --- a/app/src/main/res/drawable/layers.xml +++ /dev/null @@ -1,29 +0,0 @@ - - - - - - - diff --git a/app/src/main/res/values-night/colors.xml b/app/src/main/res/values-night/colors.xml deleted file mode 100644 index 27e9567..0000000 --- a/app/src/main/res/values-night/colors.xml +++ /dev/null @@ -1,6 +0,0 @@ - - - #FFA8A8A8 - #FFBDC1C6 - #FF3C4042 - diff --git a/app/src/main/res/values-night/styles.xml b/app/src/main/res/values-night/styles.xml deleted file mode 100644 index 87d0148..0000000 --- a/app/src/main/res/values-night/styles.xml +++ /dev/null @@ -1,6 +0,0 @@ - - - - diff --git a/app/src/main/res/values-v24/bools.xml b/app/src/main/res/values-v24/bools.xml deleted file mode 100644 index f93b670..0000000 --- a/app/src/main/res/values-v24/bools.xml +++ /dev/null @@ -1,4 +0,0 @@ - - - true - diff --git a/app/src/main/res/values/bools.xml b/app/src/main/res/values/bools.xml deleted file mode 100644 index 72fc307..0000000 --- a/app/src/main/res/values/bools.xml +++ /dev/null @@ -1,4 +0,0 @@ - - - false - diff --git a/app/src/main/res/values/colors.xml b/app/src/main/res/values/colors.xml deleted file mode 100644 index 85f5214..0000000 --- a/app/src/main/res/values/colors.xml +++ /dev/null @@ -1,13 +0,0 @@ - - - #FFFAFAFA - #FF5E7C87 - #FF202124 - #FF202124 - #FFBDC1C6 - #FF202124 - #FF3C4042 - #FF3C4042 - #888888 - #FF505153 - diff --git a/app/src/main/res/values/styles.xml b/app/src/main/res/values/styles.xml deleted file mode 100644 index 61caf1b..0000000 --- a/app/src/main/res/values/styles.xml +++ /dev/null @@ -1,48 +0,0 @@ - - - - - - - - - - - - - From e9b8b4adab28f1272f10d7abca6a429e6417a03a Mon Sep 17 00:00:00 2001 From: Ratul Hasan Date: Fri, 7 Nov 2025 14:24:09 +0600 Subject: [PATCH 06/27] remove unnecessary shortcut --- .../ui/ShortcutHandlerActivity.java | 64 ------------------- app/src/main/res/drawable/ic_shortcut.xml | 9 --- app/src/main/res/xml-v25/app_shortcuts.xml | 14 ---- 3 files changed, 87 deletions(-) delete mode 100644 app/src/main/java/io/github/ratul/topactivity/ui/ShortcutHandlerActivity.java delete mode 100644 app/src/main/res/drawable/ic_shortcut.xml delete mode 100644 app/src/main/res/xml-v25/app_shortcuts.xml diff --git a/app/src/main/java/io/github/ratul/topactivity/ui/ShortcutHandlerActivity.java b/app/src/main/java/io/github/ratul/topactivity/ui/ShortcutHandlerActivity.java deleted file mode 100644 index a13e9cf..0000000 --- a/app/src/main/java/io/github/ratul/topactivity/ui/ShortcutHandlerActivity.java +++ /dev/null @@ -1,64 +0,0 @@ -/* - * Copyright (C) 2022 Ratul Hasan - * - * 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.ratul.topactivity.ui; - -import android.annotation.TargetApi; -import android.app.Activity; -import android.content.Intent; -import android.os.Build; -import android.os.Bundle; -import android.provider.Settings; -import androidx.appcompat.app.AppCompatActivity; -import io.github.ratul.topactivity.utils.DatabaseUtil; -import io.github.ratul.topactivity.utils.WindowUtil; -import io.github.ratul.topactivity.model.NotificationMonitor; -import io.github.ratul.topactivity.service.MonitoringService; -import io.github.ratul.topactivity.service.AccessibilityMonitoringService; - -/** - * Created by Wen on 16/02/2017. - * Refactored by Ratul on 04/05/2022. - */ -@TargetApi(Build.VERSION_CODES.N) -public class ShortcutHandlerActivity extends AppCompatActivity { - @Override - protected void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - DatabaseUtil.setDisplayWidth(MainActivity.getScreenWidth(this)); - - if (!MainActivity.usageStats(this) || !Settings.canDrawOverlays(this)) { - Intent intent = new Intent(this, MainActivity.class); - intent.putExtra(MainActivity.EXTRA_FROM_QS_TILE, true); - startActivity(intent); - finish(); - } else if (AccessibilityMonitoringService.getInstance() == null && DatabaseUtil.hasAccess()) - startService(new Intent().setClass(this, AccessibilityMonitoringService.class)); - - boolean isShow = !DatabaseUtil.isShowWindow(); - DatabaseUtil.setIsShowWindow(isShow); - if (!isShow) { - WindowUtil.dismiss(this); - NotificationMonitor.showNotification(this, true); - } else { - WindowUtil.init(this); - NotificationMonitor.showNotification(this, false); - startService(new Intent(this, MonitoringService.class)); - } - sendBroadcast(new Intent(MainActivity.ACTION_STATE_CHANGED)); - finish(); - } -} diff --git a/app/src/main/res/drawable/ic_shortcut.xml b/app/src/main/res/drawable/ic_shortcut.xml deleted file mode 100644 index b27c8af..0000000 --- a/app/src/main/res/drawable/ic_shortcut.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - diff --git a/app/src/main/res/xml-v25/app_shortcuts.xml b/app/src/main/res/xml-v25/app_shortcuts.xml deleted file mode 100644 index 72f1548..0000000 --- a/app/src/main/res/xml-v25/app_shortcuts.xml +++ /dev/null @@ -1,14 +0,0 @@ - - - - - - From a562353a56e22fef5f560bc950098344c4c2de94 Mon Sep 17 00:00:00 2001 From: Ratul Hasan Date: Fri, 7 Nov 2025 14:24:52 +0600 Subject: [PATCH 07/27] remove crash handler --- .../ratul/topactivity/model/CrashHandler.java | 152 ------------------ .../ratul/topactivity/ui/CrashActivity.java | 130 --------------- app/src/main/res/layout/crash_view.xml | 28 ---- 3 files changed, 310 deletions(-) delete mode 100644 app/src/main/java/io/github/ratul/topactivity/model/CrashHandler.java delete mode 100644 app/src/main/java/io/github/ratul/topactivity/ui/CrashActivity.java delete mode 100644 app/src/main/res/layout/crash_view.xml diff --git a/app/src/main/java/io/github/ratul/topactivity/model/CrashHandler.java b/app/src/main/java/io/github/ratul/topactivity/model/CrashHandler.java deleted file mode 100644 index 9abf750..0000000 --- a/app/src/main/java/io/github/ratul/topactivity/model/CrashHandler.java +++ /dev/null @@ -1,152 +0,0 @@ -/* - * Copyright (C) 2022 Ratul Hasan - * - * 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.ratul.topactivity.model; - -import io.github.ratul.topactivity.App; -import io.github.ratul.topactivity.ui.*; -import android.app.*; -import java.text.*; -import java.io.*; -import android.content.pm.*; -import android.text.*; -import android.os.*; -import android.content.*; -import java.util.*; -import java.lang.Thread.UncaughtExceptionHandler; -import android.widget.Toast; - -/** - * Created by Ratul on 04/05/2022. - */ - -public class CrashHandler implements UncaughtExceptionHandler { - - private static UncaughtExceptionHandler DEFAULT = Thread.getDefaultUncaughtExceptionHandler(); - - public static CrashHandler getInstance(App app) { - return new CrashHandler(app); - } - - private App mApp; - private File crashDirectory; - private String fullStackTrace, versionName; - private long versionCode; - - public CrashHandler(App app) { - mApp = app; - crashDirectory = app.getExternalFilesDir(null); - try { - PackageInfo packageInfo = mApp.getPackageManager().getPackageInfo(mApp.getPackageName(), 0); - versionName = packageInfo.versionName; - versionCode = Build.VERSION.SDK_INT >= 28 ? packageInfo.getLongVersionCode() : packageInfo.versionCode; - } catch (PackageManager.NameNotFoundException ignored) { - ignored.printStackTrace(); - versionName = "unknown"; - } - } - - @Override - public void uncaughtException(Thread main, Throwable mThrowable) { - if (tryUncaughtException(main, mThrowable) || DEFAULT == null) { - try { - Thread.sleep(1000L); - } catch (InterruptedException e) { - android.os.Process.sendSignal(android.os.Process.myPid(), android.os.Process.SIGNAL_KILL); - } - android.os.Process.killProcess(android.os.Process.myPid()); - } else { - DEFAULT.uncaughtException(main, mThrowable); - } - } - - private void showToast(String str, int length) { - Toast.makeText(mApp, str, length).show(); - } - - private boolean tryUncaughtException(Thread thread, Throwable throwable) { - if (throwable == null) { - return false; - } else { - new Thread() { - @Override - public void run() { - Looper.prepare(); - showToast("Saving Crash Log", 0); - Looper.loop(); - } - }.start(); - } - File crashFile = new File(crashDirectory, "crash.txt"); - long timestamp = System.currentTimeMillis(); - SimpleDateFormat format = new SimpleDateFormat("dd-MM-yyyy HH:mm"); - String time = format.format(new Date(timestamp)); - - StringWriter sw = new StringWriter(); - PrintWriter pw = new PrintWriter(sw); - throwable.printStackTrace(pw); - Throwable cause = throwable.getCause(); - if (cause != null) - cause.printStackTrace(pw); - fullStackTrace = sw.toString(); - pw.close(); - - StringBuilder sb = new StringBuilder(); - sb.append("*********************** Crash Head ***********************\n"); - sb.append("Time Of Crash : ").append(time).append("\n"); - sb.append("Device Manufacturer : ").append(Build.MANUFACTURER).append("\n"); - sb.append("Device Model : ").append(Build.MODEL).append("\n"); - sb.append("Android Version : ").append(Build.VERSION.RELEASE).append("\n"); - sb.append("Android SDK : ").append(Build.VERSION.SDK_INT).append("\n"); - sb.append("App VersionName : ").append(versionName).append("\n"); - sb.append("App VersionCode : ").append(versionCode).append("\n"); - sb.append("\n*********************** Crash Log ***********************"); - sb.append("\n").append(fullStackTrace); - - String errorLog = sb.toString(); - - try { - writeFile(crashFile, errorLog); - } catch (IOException ignored) { - ignored.printStackTrace(); - } - - gotoCrashActiviy: { - Intent intent = new Intent(mApp, CrashActivity.class); - intent.addFlags( - Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_CLEAR_TASK); - intent.putExtra(CrashActivity.EXTRA_CRASH_INFO, errorLog); - mApp.startActivity(intent); - } - - return errorLog != null; - } - - private void writeFile(File file, String content) throws IOException { - File parentFile = file.getParentFile(); - if (parentFile != null && !parentFile.exists()) { - parentFile.mkdirs(); - } - file.createNewFile(); - try { - FileWriter writer = new FileWriter(file); - writer.write(content); - writer.close(); - } catch (IOException e) { - e.printStackTrace(); - } - } -} diff --git a/app/src/main/java/io/github/ratul/topactivity/ui/CrashActivity.java b/app/src/main/java/io/github/ratul/topactivity/ui/CrashActivity.java deleted file mode 100644 index 27c0af6..0000000 --- a/app/src/main/java/io/github/ratul/topactivity/ui/CrashActivity.java +++ /dev/null @@ -1,130 +0,0 @@ -/* - * Copyright (C) 2022 Ratul Hasan - * - * 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.ratul.topactivity.ui; - -import android.app.Activity; -import android.os.Bundle; -import com.google.android.material.textview.MaterialTextView; -import androidx.appcompat.app.AppCompatActivity; -import io.github.ratul.topactivity.R; -import android.view.MenuItem; -import android.content.ClipboardManager; -import android.content.ClipData; -import android.view.Menu; -import android.content.pm.PackageManager; -import android.content.Intent; -import android.content.Context; -import android.content.DialogInterface; -import android.graphics.Typeface; -import android.view.View; -import android.widget.Toast; -import android.text.SpannableString; -import androidx.appcompat.app.ActionBar; -import android.text.Spannable; -import com.google.android.material.dialog.MaterialAlertDialogBuilder; -import io.github.ratul.topactivity.model.TypefaceSpan; - -/** - * Created by Ratul on 04/05/2022. - */ - -public class CrashActivity extends AppCompatActivity { - public static String EXTRA_CRASH_INFO = "crash"; - private String crashInfo; - private boolean restart; - - @Override - protected void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - setContentView(R.layout.crash_view); - - SpannableString s = new SpannableString(getString(R.string.app_name)); - s.setSpan(new TypefaceSpan(this, "fonts/google_sans_bold.ttf"), 0, s.length(), - Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); - ActionBar actionBar = getSupportActionBar(); - actionBar.setTitle(s); - - restart = getIntent().getBooleanExtra("Restart", true); - String mLog = getIntent().getStringExtra(EXTRA_CRASH_INFO); - crashInfo = mLog; - MaterialTextView crashed = findViewById(R.id.crashed); - crashed.setText(mLog); - } - - @Override - public void onBackPressed() { - if (!restart) { - finish(); - return; - } - new MaterialAlertDialogBuilder(this).setTitle("Exit").setMessage("App will restart, are you sure to exit") - .setPositiveButton("Yes", new DialogInterface.OnClickListener() { - @Override - public void onClick(DialogInterface di, int btn) { - di.dismiss(); - restart(); - } - }).setNegativeButton("No", new DialogInterface.OnClickListener() { - @Override - public void onClick(DialogInterface di, int btn) { - di.dismiss(); - } - }).setCancelable(false).show(); - } - - private void restart() { - PackageManager pm = getPackageManager(); - Intent intent = pm.getLaunchIntentForPackage(getPackageName()); - if (intent != null) { - intent.addFlags( - Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_CLEAR_TASK); - startActivity(intent); - } - finish(); - android.os.Process.killProcess(android.os.Process.myPid()); - System.exit(0); - } - - @Override - public boolean onOptionsItemSelected(MenuItem item) { - if (item.getItemId() == android.R.id.copy) { - ClipboardManager cm = (ClipboardManager) getSystemService(Context.CLIPBOARD_SERVICE); - cm.setPrimaryClip(ClipData.newPlainText(getPackageName(), crashInfo)); - Toast.makeText(this, "Copied", 0).show(); - } else if (item.getItemId() == android.R.id.redo) { - onBackPressed(); - } - return super.onOptionsItemSelected(item); - } - - @Override - public boolean onCreateOptionsMenu(Menu menu) { - SpannableString s = new SpannableString("Copy Log"); - s.setSpan(new TypefaceSpan(this, "fonts/google_sans_regular.ttf"), 0, s.length(), - Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); - menu.add(0, android.R.id.copy, 0, s); - if (restart) { - s = new SpannableString("Restart App"); - s.setSpan(new TypefaceSpan(this, "fonts/google_sans_regular.ttf"), 0, s.length(), - Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); - - menu.add(1, android.R.id.redo, 1, s); - } - return super.onCreateOptionsMenu(menu); - } - -} diff --git a/app/src/main/res/layout/crash_view.xml b/app/src/main/res/layout/crash_view.xml deleted file mode 100644 index 3bf0639..0000000 --- a/app/src/main/res/layout/crash_view.xml +++ /dev/null @@ -1,28 +0,0 @@ - - - - - - - - From 4fcaa7aed402e62f2739c4dbee9c40999c9af740 Mon Sep 17 00:00:00 2001 From: Ratul Hasan Date: Fri, 7 Nov 2025 14:25:29 +0600 Subject: [PATCH 08/27] improve copy functionality --- .../topactivity/ui/BackgroundActivity.java | 73 ------------------- .../ui/CopyToClipboardActivity.java | 51 +++++++++++++ 2 files changed, 51 insertions(+), 73 deletions(-) delete mode 100644 app/src/main/java/io/github/ratul/topactivity/ui/BackgroundActivity.java create mode 100644 app/src/main/java/io/github/ratul/topactivity/ui/CopyToClipboardActivity.java diff --git a/app/src/main/java/io/github/ratul/topactivity/ui/BackgroundActivity.java b/app/src/main/java/io/github/ratul/topactivity/ui/BackgroundActivity.java deleted file mode 100644 index 81dd142..0000000 --- a/app/src/main/java/io/github/ratul/topactivity/ui/BackgroundActivity.java +++ /dev/null @@ -1,73 +0,0 @@ -/* - * Copyright (C) 2022 Ratul Hasan - * - * 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.ratul.topactivity.ui; - -import android.annotation.TargetApi; -import android.app.Activity; -import android.content.Intent; -import android.os.Build; -import android.os.Bundle; -import android.provider.Settings; -import android.content.ClipboardManager; -import android.content.ClipData; -import androidx.appcompat.app.AppCompatActivity; -import io.github.ratul.topactivity.App; - -/** - * Created by Ratul on 04/05/2022. - */ -@TargetApi(Build.VERSION_CODES.O) -public class BackgroundActivity extends AppCompatActivity { - public static String STRING_COPY = "io.github.ratul.topactivity.COPY_STRING"; - public static String COPY_MSG = "io.github.ratul.topactivity.COPY_STRING_MSG"; - public static boolean isAlive; - - @Override - protected void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - if (!getIntent().hasExtra(STRING_COPY)) - finish(); - String str = getIntent().getStringExtra(STRING_COPY); - String msg = getIntent().getStringExtra(COPY_MSG); - msg = (msg == null || msg.trim().isEmpty()) ? "Copied" : msg; - - if (str != null) { - ClipboardManager clipboard = (ClipboardManager) getSystemService(CLIPBOARD_SERVICE); - ClipData clip = new ClipData(ClipData.newPlainText("", str)); - clipboard.setPrimaryClip(clip); - } - finish(); - } - - @Override - protected void onStop() { - isAlive = false; - super.onStop(); - } - - @Override - protected void onDestroy() { - isAlive = false; - super.onDestroy(); - } - - @Override - protected void onStart() { - isAlive = true; - super.onStart(); - } -} diff --git a/app/src/main/java/io/github/ratul/topactivity/ui/CopyToClipboardActivity.java b/app/src/main/java/io/github/ratul/topactivity/ui/CopyToClipboardActivity.java new file mode 100644 index 0000000..0f57d7f --- /dev/null +++ b/app/src/main/java/io/github/ratul/topactivity/ui/CopyToClipboardActivity.java @@ -0,0 +1,51 @@ +/* + * Copyright (C) 2022 Ratul Hasan + * + * 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.ratul.topactivity.ui; + +import static io.github.ratul.topactivity.utils.NullSafety.isNullOrEmpty; + +import android.content.ClipData; +import android.content.ClipboardManager; +import android.content.Intent; +import android.os.Bundle; + +import androidx.appcompat.app.AppCompatActivity; + +import io.github.ratul.topactivity.R; + +/** + * Created by Ratul on 04/05/2022. + */ +public class CopyToClipboardActivity extends AppCompatActivity { + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + + if (getIntent().hasExtra(Intent.EXTRA_TEXT)) { + String text = getIntent().getStringExtra(Intent.EXTRA_TEXT); + + if (!isNullOrEmpty(text)) { + ClipboardManager clipboard = (ClipboardManager) getSystemService(CLIPBOARD_SERVICE); + ClipData clip = new ClipData(ClipData.newPlainText( + getString(R.string.app_name), text)); + clipboard.setPrimaryClip(clip); + } + } + finish(); + } +} From c9180dfeec9385082301d4bafe846ebc79017edf Mon Sep 17 00:00:00 2001 From: Ratul Hasan Date: Fri, 7 Nov 2025 14:26:11 +0600 Subject: [PATCH 09/27] remove typeface related views --- .../ratul/topactivity/model/TypefaceSpan.java | 54 ------------------- .../ratul/topactivity/view/BoldTextView.java | 54 ------------------- .../topactivity/view/NormalTextView.java | 54 ------------------- .../topactivity/view/RegularTextView.java | 54 ------------------- 4 files changed, 216 deletions(-) delete mode 100644 app/src/main/java/io/github/ratul/topactivity/model/TypefaceSpan.java delete mode 100644 app/src/main/java/io/github/ratul/topactivity/view/BoldTextView.java delete mode 100644 app/src/main/java/io/github/ratul/topactivity/view/NormalTextView.java delete mode 100644 app/src/main/java/io/github/ratul/topactivity/view/RegularTextView.java diff --git a/app/src/main/java/io/github/ratul/topactivity/model/TypefaceSpan.java b/app/src/main/java/io/github/ratul/topactivity/model/TypefaceSpan.java deleted file mode 100644 index 54ec372..0000000 --- a/app/src/main/java/io/github/ratul/topactivity/model/TypefaceSpan.java +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Copyright (C) 2022 Ratul Hasan - * - * 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.ratul.topactivity.model; - -import android.util.LruCache; -import android.graphics.Typeface; -import android.text.style.MetricAffectingSpan; -import android.content.Context; -import android.text.TextPaint; -import android.graphics.Paint; - -public class TypefaceSpan extends MetricAffectingSpan { - - private static LruCache sTypefaceCache = new LruCache(12); - - private Typeface mTypeface; - - public TypefaceSpan(Context context, String typefaceName) { - mTypeface = sTypefaceCache.get(typefaceName); - if (mTypeface == null) { - mTypeface = Typeface.createFromAsset(context.getApplicationContext() - .getAssets(), typefaceName); - sTypefaceCache.put(typefaceName, mTypeface); - } - } - - @Override - public void updateMeasureState(TextPaint p) { - p.setTypeface(mTypeface); - // Note: This flag is required for proper typeface rendering - p.setFlags(p.getFlags() | Paint.SUBPIXEL_TEXT_FLAG); - } - - @Override - public void updateDrawState(TextPaint tp) { - tp.setTypeface(mTypeface); - // Note: This flag is required for proper typeface rendering - tp.setFlags(tp.getFlags() | Paint.SUBPIXEL_TEXT_FLAG); - } -} diff --git a/app/src/main/java/io/github/ratul/topactivity/view/BoldTextView.java b/app/src/main/java/io/github/ratul/topactivity/view/BoldTextView.java deleted file mode 100644 index 5d87080..0000000 --- a/app/src/main/java/io/github/ratul/topactivity/view/BoldTextView.java +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Copyright (C) 2022 Ratul Hasan - * - * 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.ratul.topactivity.view; - -import android.content.Context; -import android.graphics.Canvas; -import android.graphics.Typeface; -import android.util.AttributeSet; -import com.google.android.material.textview.MaterialTextView; - -public class BoldTextView extends MaterialTextView { - public void setBoldFont(Context context) { - Typeface face = Typeface.createFromAsset(context.getAssets(), "fonts/google_sans_bold.ttf"); - super.setTypeface(face); - } - - public BoldTextView(Context context) { - super(context); - setBoldFont(context); - } - - public BoldTextView(Context context, AttributeSet attrs) { - super(context, attrs); - setBoldFont(context); - } - - public BoldTextView(Context context, AttributeSet attrs, int defStyle) { - super(context, attrs, defStyle); - setBoldFont(context); - } - - public BoldTextView(Context context, AttributeSet attrs, int defStyle, int res) { - super(context, attrs, defStyle, res); - setBoldFont(context); - } - - protected void onDraw(Canvas canvas) { - super.onDraw(canvas); - } -} diff --git a/app/src/main/java/io/github/ratul/topactivity/view/NormalTextView.java b/app/src/main/java/io/github/ratul/topactivity/view/NormalTextView.java deleted file mode 100644 index 381c8d7..0000000 --- a/app/src/main/java/io/github/ratul/topactivity/view/NormalTextView.java +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Copyright (C) 2022 Ratul Hasan - * - * 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.ratul.topactivity.view; - -import android.content.Context; -import android.graphics.Canvas; -import android.graphics.Typeface; -import android.util.AttributeSet; -import com.google.android.material.textview.MaterialTextView; - -public class NormalTextView extends MaterialTextView { - public void setRegularFont(Context context) { - Typeface face = Typeface.createFromAsset(context.getAssets(), "fonts/google_sans_regular.ttf"); - super.setTypeface(face); - } - - public NormalTextView(Context context) { - super(context); - setRegularFont(context); - } - - public NormalTextView(Context context, AttributeSet attrs) { - super(context, attrs); - setRegularFont(context); - } - - public NormalTextView(Context context, AttributeSet attrs, int defStyle) { - super(context, attrs, defStyle); - setRegularFont(context); - } - - public NormalTextView(Context context, AttributeSet attrs, int defStyle, int res) { - super(context, attrs, defStyle, res); - setRegularFont(context); - } - - protected void onDraw (Canvas canvas) { - super.onDraw(canvas); - } -} diff --git a/app/src/main/java/io/github/ratul/topactivity/view/RegularTextView.java b/app/src/main/java/io/github/ratul/topactivity/view/RegularTextView.java deleted file mode 100644 index 8470b9c..0000000 --- a/app/src/main/java/io/github/ratul/topactivity/view/RegularTextView.java +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Copyright (C) 2022 Ratul Hasan - * - * 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.ratul.topactivity.view; - -import android.content.Context; -import android.graphics.Canvas; -import android.graphics.Typeface; -import android.util.AttributeSet; -import com.google.android.material.textview.MaterialTextView; - -public class RegularTextView extends MaterialTextView { - public void setRegularFont(Context context) { - Typeface face = Typeface.createFromAsset(context.getAssets(), "fonts/google_sans_regular.ttf"); - super.setTypeface(face, 1); - } - - public RegularTextView(Context context) { - super(context); - setRegularFont(context); - } - - public RegularTextView(Context context, AttributeSet attrs) { - super(context, attrs); - setRegularFont(context); - } - - public RegularTextView(Context context, AttributeSet attrs, int defStyle) { - super(context, attrs, defStyle); - setRegularFont(context); - } - - public RegularTextView(Context context, AttributeSet attrs, int defStyle, int res) { - super(context, attrs, defStyle, res); - setRegularFont(context); - } - - protected void onDraw(Canvas canvas) { - super.onDraw(canvas); - } -} From d1c9ab22a02b09d537eeb24c631ebdb6d564d9ee Mon Sep 17 00:00:00 2001 From: Ratul Hasan Date: Fri, 7 Nov 2025 14:26:59 +0600 Subject: [PATCH 10/27] update agp and gradle --- build.gradle | 2 +- gradle/wrapper/gradle-wrapper.properties | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/build.gradle b/build.gradle index 78a6726..182b248 100644 --- a/build.gradle +++ b/build.gradle @@ -5,7 +5,7 @@ buildscript { mavenCentral() } dependencies { - classpath 'com.android.tools.build:gradle:8.11.1' + classpath 'com.android.tools.build:gradle:8.13.0' } } diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 0156b72..3ec3649 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ #Mon Aug 30 15:20:07 CST 2021 distributionBase=GRADLE_USER_HOME -distributionUrl=https\://services.gradle.org/distributions/gradle-8.13-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.14.3-bin.zip distributionPath=wrapper/dists zipStorePath=wrapper/dists zipStoreBase=GRADLE_USER_HOME From 099c5b0bd7a24d953ffc8c1e0f84ffa2c108d23c Mon Sep 17 00:00:00 2001 From: Ratul Hasan Date: Fri, 7 Nov 2025 14:27:27 +0600 Subject: [PATCH 11/27] add product flavors and appcompat --- app/build.gradle | 39 +++++++++++++++++++++++++-------------- 1 file changed, 25 insertions(+), 14 deletions(-) diff --git a/app/build.gradle b/app/build.gradle index 9922e74..8e252e0 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -1,6 +1,7 @@ apply plugin: 'com.android.application' android { + namespace "io.github.ratul.topactivity" compileSdkVersion 36 defaultConfig { @@ -8,33 +9,43 @@ android { minSdkVersion 24 targetSdkVersion 36 versionCode 20 - versionName "2.0.0" + versionName "1.5.9" } buildTypes { release { - debuggable false minifyEnabled true - shrinkResources false - proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' - } - debug { - debuggable true - minifyEnabled false - shrinkResources false - proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' + proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' + signingConfig signingConfigs.debug } } buildFeatures { buildConfig true } + + compileOptions { + sourceCompatibility JavaVersion.VERSION_11 + targetCompatibility JavaVersion.VERSION_11 + } + + flavorDimensions 'version' + productFlavors { + global { + dimension 'version' + } + playStore { + dimension 'version' + } + } } dependencies { implementation 'androidx.appcompat:appcompat:1.7.1' - implementation 'com.google.android.material:material:1.12.0' - implementation 'androidx.constraintlayout:constraintlayout:2.2.1' - implementation 'androidx.preference:preference:1.2.1' - implementation 'androidx.core:core:1.17.0' } + +configurations.all { + resolutionStrategy { + force('org.jetbrains.kotlin:kotlin-stdlib-jdk8:2.2.0') + } +} \ No newline at end of file From 166d72652951df34aa930afde30c02ac7ba05df7 Mon Sep 17 00:00:00 2001 From: Ratul Hasan Date: Fri, 7 Nov 2025 14:28:19 +0600 Subject: [PATCH 12/27] update launcher icon --- app/src/main/res/drawable/ic_launcher.png | Bin 7035 -> 0 bytes .../main/res/drawable/ic_launcher_foreground.png | Bin 2307 -> 0 bytes app/src/main/res/drawable/ic_launcher_round.png | Bin 9830 -> 0 bytes .../main/res/mipmap-anydpi-v26/ic_launcher.xml | 4 ++++ .../res/mipmap-anydpi-v26/ic_launcher_round.xml | 4 ++++ app/src/main/res/mipmap-xhdpi/ic_launcher.webp | Bin 0 -> 1106 bytes .../res/mipmap-xhdpi/ic_launcher_foreground.webp | Bin 0 -> 1298 bytes .../main/res/mipmap-xhdpi/ic_launcher_round.webp | Bin 0 -> 2276 bytes app/src/main/res/mipmap-xxhdpi/ic_launcher.webp | Bin 0 -> 1640 bytes .../mipmap-xxhdpi/ic_launcher_foreground.webp | Bin 0 -> 1862 bytes .../res/mipmap-xxhdpi/ic_launcher_round.webp | Bin 0 -> 3674 bytes app/src/main/res/mipmap-xxxhdpi/ic_launcher.webp | Bin 0 -> 2052 bytes .../mipmap-xxxhdpi/ic_launcher_foreground.webp | Bin 0 -> 2374 bytes .../res/mipmap-xxxhdpi/ic_launcher_round.webp | Bin 0 -> 5006 bytes app/src/main/res/values/colors.xml | 4 ++++ 15 files changed, 12 insertions(+) delete mode 100644 app/src/main/res/drawable/ic_launcher.png delete mode 100644 app/src/main/res/drawable/ic_launcher_foreground.png delete mode 100644 app/src/main/res/drawable/ic_launcher_round.png create mode 100644 app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml create mode 100644 app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml create mode 100644 app/src/main/res/mipmap-xhdpi/ic_launcher.webp create mode 100644 app/src/main/res/mipmap-xhdpi/ic_launcher_foreground.webp create mode 100644 app/src/main/res/mipmap-xhdpi/ic_launcher_round.webp create mode 100644 app/src/main/res/mipmap-xxhdpi/ic_launcher.webp create mode 100644 app/src/main/res/mipmap-xxhdpi/ic_launcher_foreground.webp create mode 100644 app/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp create mode 100644 app/src/main/res/mipmap-xxxhdpi/ic_launcher.webp create mode 100644 app/src/main/res/mipmap-xxxhdpi/ic_launcher_foreground.webp create mode 100644 app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp create mode 100644 app/src/main/res/values/colors.xml diff --git a/app/src/main/res/drawable/ic_launcher.png b/app/src/main/res/drawable/ic_launcher.png deleted file mode 100644 index e3ce3a37b96335902a62fed2abd970cd993bf6bc..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 7035 zcmbVRXH-*7w7m(5B-BVVKoC&62%$(XAt232mm)0`1wpAQ9Rh?RQUx?1RRlp%0jbh! z-~&NKKgj5kfNjga z58@2?Z8C9}7HlBCCOUZFT|Z_Se1Q4l^~@096^w9>1psbAJuMA0|E#raD>F0dN9y0I z`a3ujduDz{<{2%m+eQUaZbHIZILy3aW=HKhr+G!9;^IQ-k=O6ukOsZ}>ps7&E~N@7 zN(s5Lxg>1EjI~=Iai#4G|f%L^Y~665zNwH^I<_s`1Z}1iX?=4smaWIjXCxzA*sVrhUjAH$PlG75`}pJ}jE{Ub!|^Ud z^rxACQ=Fz|`)|lnm$HWqd`Ld%g%ZpvY?$zR9D#%`^m3!ozD z{{_%Ry`Z38lo|LlME}W8Q=1P6^>%Wax6Sv_fTZa!5Tfvdx`+&i$qh8ail*q=^2&;7 zRZWdwqQpEb(a%JLt*&%SrUT0F9R2w5H74NuQiT+>*zC0vIr%{D5g5=}@J1~CSN&ja zGapI6@V^-akE*pcN9kYuNw;lJ8k>&3AbL@Gsp9 zTLj|LRZ4Sn*g5`=$tHd&bakZ3VQEuSsLo;Y-GwmZr`oow)*`BFzEP9t@ zlGy=?t@Pt#h*sqz!@SAKUO}{N#BVfsT@hMhP9u#2b`?@6n?Zwe`i(;~D4%UVi&t6Y zfk!$pBlyqbS0HGHo)#EUmrDrH{DOs`pF|^Dl4S`%^h*aQR)CR}#D9kZFzB`ae}9rP zt_(z<%qlQ#ZhBib1#?1aZY1|Ep)Qr;!sE=ndH5F%hUU;IlidK+|1m3et(nIe`6-UvAtSEfRB$fri_Tb zm(t_>tto{5sf2Ajnd}ccb4UZk;>PYPnJJHr=jK)JoDV%%K=a%%S|08RDMOp893apEbMQMh=@p~TWK}vN;u5R*H_cbjIFI* z6UFs9++-P!?=}*oFzwMtWM*<R3du$T-)>__SAjc1dUh*{Q_w{TticktT|?c6N4NzRw}j zW;9E(#ed05MG7?cy5$ByW z{qYKG*nWGx(VNJkV{QcGcK>~9^}XlD78XhFqwk!&yu93mt5~0~fjgRZdHIh2!NM~X zk1FrflpVI}vP$-h0&(F#3$KH%D__5=w6(O5Qsx!Jtt!xN56T7;B?@sK>-TIL19^CO z);6}b+I|gt5>Jm2-OgK5(-&c}3AQ9g?vWQIC1-ElVrLQ!e+k3JhnCvZVZ6Pi!0CWs zL)L%�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 MyK12I4o{5uA3IX{X#fBK diff --git a/app/src/main/res/drawable/ic_launcher_foreground.png b/app/src/main/res/drawable/ic_launcher_foreground.png deleted file mode 100644 index 645f29e9769a7e77fbce5322a6121f0fa38eee80..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2307 zcmV+e3H0&PHzNQp_KMntQLt;7(5L;^xY5tIao1}e2sK%#<* zXpji{0gJV1w6^`AD7GLLsHs8``T*M7TKc$;pC9%a?wK=>&dfb$?r^#PTm(_Dw^WIugKt7>2BpDgPi2$OFchtqK;OtP@hl_)ll_zU_iaChKwIn4_Haa3+lt_57jm5 z-YR7tQ)lEs)EM;~b-ja{G+ZdnJvY^m^FAwySfjpI9g~!sqApgqWy-#$esZW}jaM&K zcUYaMw2Jo|HSa)y*Isq4`t~ZaPF0`J$oH~(YL&8G>eWUCNcZLTY}v8RkOf=;d<&S& z;N)4FZ2N#0fsMdpz!qRP(BEhqE#M&VR0v^bmEWcTZ_RwS7TBCE7(y6O9|68XT&zlX zN49K3gsEM?BH)`;lGP793ETzz4)|}a6|2pdK(w>cc$M0J;J)NaV^T{kt8>*CtIP+x z)f>!Xa?Ba(tYjWaW4$`1M)|YVo=pE9YNg?6>dGo)?Nk>Ixn~7Iov1#Zk^7MP`DDbT z%T7~&nJL?^exsF!7bg>JnyfwQqTG5{0MwvfZ@IZs8Wq>5$E(xT)74+8y_s^asHZpE z=n;t;rz`4Lml-Ylj)r=S)mQX^Lyh=oRvMY6Zm@hfzNEgZfIbxp<9zlJ<94Uk z5ZtHUs~%sku6lOZNmLqso2X*=bvhEeaJBj&;A~(%@HSu~(Kg!v{1$k&Weqr>)wHE*@fd_y`llw++8j-A0MCll!jaC&S zf-vCyL@nti_Ng1Vs=;ToqpXWMybLR0iSan2S>rKN$Fabzz#PhBj)nAX*a%Zk27W*s zK1*%E1ENj_t_RMd+-<%exFaV~%P=gHzIqgJCvaZ!)fvEC^-I)=VrS~;0xlxP8nQ8l z9|J$nTW%Nz4KqfczE0c#mnPaS;ym;SurOKi4u^Aq>xjXQG-2z2>p}>HM623LShAXZ z4!DHM9EU)htbYpJSkH)5PXfLN%%YsE=YUH?2)lC@{dKfk!%inAdQ76cqopAjfN?|( zd|1uyXHlmDONlmDx{f`-l|`p3wT&>f8(2=XbJ88{CC)o((gN^NV4XTQRYxF_xqxyF z?FW{I5Pnl+AD~TysS|)(h#L0#*TmKAVq%ipF3PuFf#}3srCywv9-jd&C#F!P>-jaX zq$v5*XxA$FWuO$pENR97@O|L^5JJEDG;wu%cdASPrVvep`9$+!3gsHQ0l2Esl*_`P z-j?xw_o(w)sAs-0=$rMUKWZjou6C;rS{_SG``xqOZL>yhSQGMHW@VtKX4X!jL(&+k zS_T|RxmIi@PS9nmSqNb}@CD#nVxmcQUQ5?;fS4GwuD~u-pfJLWISk8yQz-A~Zs4o6 zR5N#Gu05^q~wPK6MbtY+5`SGw$qcq=huxh6sg{mF{A09a3)?@Gi7 z`~kQrgm55#>Fc8?4LcvWjA&D(33~`w-e@Q*gzzNrDWW#*Cla@jIGnfVEp#KueU((_ z0N(|Upq#9~6SpjTnyD{@utU8Z_!%&hxYyj8qsUF62(#i`;JDPizz*Q*5W<#LDop0J zwK>Q(WE3$ZUuH1NPvUBKBe14`w%U#&2wMgGf=JwU;5OjiqPz#~M(#s0gs?yHYu!#v z6n-Xz(3^KV!-Yb&Mj?cQ#4XE+L$gD&w$WNZ6O}EO1n=^Nv@HCc~mA2{;i%D zq$Xh@guRqI=SoMEKQR;uI|a#bTts<%pqIE)X}Qw*>i;rs;b+z34*zs#L;aZLCvi(T z`mG<@Fdm&*o2j%h5+k_Tp&kiR7peO*74K2Mn3Mc%h4GZzk1Rjn zFrYqX9)~uJCqheecx^{7j%64LK97!Ss; zaPSQX>3;lPot0-}U5PgJRB5bF{fBy``cCV-RixcWG-{rDhl6ho$jZM-eNUrxHax+p zsZxmp-=z(I;^Hti?{?~mKn&~k5TjOGi7y_>|Fu@57{w?? dF^Z9o{{yG!OclREZ~p)Q002ovPDHLkV1j7LPIv$S diff --git a/app/src/main/res/drawable/ic_launcher_round.png b/app/src/main/res/drawable/ic_launcher_round.png deleted file mode 100644 index 7b1dffbd2945bf03c83005b6ae78694a538b12b2..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 9830 zcmW++2RxMjAAgR+*)E%K&P-NL_N+61WTvu7M`mXB9%qxX_eiqI-XoH;QnEs}?Ckx2 z`adt+>)iN0pYi>C-k#(Bg`9+m1ONbXHC41O_}KaH7e)yF)t$8`0v{l*x+)KV zis9QE;1j6p12ugZc=^JtumFGn)X<9ho|)TO)^7T1btg9$xEPXe9}vWva9f&aK6V{T z9zx>{WrVOf^(&5}=|Qd`C%IOy4$hMbtEu5S*Cb}1IHMRA{P(G>_MNGg-qe3?J#Axu zsr;fat#+RB8;pHOl|xg~Re7z!z|zQi)vI3gLVjdUYX(XX52vRu9=8!K!DaHn9=zd= zdLGG(7nqDircPaJU5r=)foaUZC#uBAG@l#d+^{swV1#H?zGo6vz0APQ*}=gf_HBnX zLQ$6)A)a4Q!13_GgB`AXeV_!;jpTiorWdKYNy?l$g+_DXjPY_)vFd0Yew`A1>%qZ6 zW%c)K3MmYCJy(&v#pQ3X~Icj|xt#JF`rlI;D;#N;`X)F;rjt{{8#Mwi$&OQBsA` z&7*i&a8+X36Sz+5cfzw<7)P%Bk<_!0uV23g;8PXVtC1*Y0Wr$Y2~kd*`8>dSQGLJG z2dmX`^r51X(&rZ?vHM&F4*ALmQalI?x#RLS@>c|<-X-`%?%@1|Lus7LXz z@$r<@P>W~;tP)U7m}X7W5sX@7L+e}`A=XGBcLGC0L#y+7+kpl7t!PaWjsok%9Zf~5 zIkH~H!oXXBV>TMV9tp~c(Lt@eVM8tbhGd~GDk{naT#P0N8E78TwP%MsCkQkzi6wr; zkGnK`_wHQ>fqCLI!|TL0@a~sf04E?7Q72FkV+qKA`0(NMf$hUt#dAR4u;!9=Pgl*M6Q<2f7H$TdzQw**bHLd|VBh1P<{6aMrD?oJB}@gUmnj1U zW2XpIhZm#BUgLq`d=`xG#al6w zALXS}ayEJV_=i^s`9`$7X2_c{8{agn93j=+x_cz7*8Ff;7C78OEKQ@hNUSfe1BRG1 z7rqpNUy)otPYPbsfjlkzVN0#aJ#Gr{*D1bd0oilyCBS3&qEYkHWAK&044)PNOUD{|+q{{-O+SqKTy-Zepr|v##BU*9f-Y=Ks ze2;;Q8Sq7;naqw$5v1R7nbfSTrj}wEm8T!|a=5y{Z_Pu%A|h3{OXX;nRYq1!qJ8TM zzVqOXZn(KZ6(tr+2cOd}lcO@wI=+p~&F9QcCoArd-v0jLkNO{--p(-6gyW;cpO#N} z)z#H~p4;j#ReNP`U#3`Yz-EwXX3{ zbv`>z?qdvixB1h;uja5+>T(qvU{2w*3>uyoi~s ztSmiQugSS2$-vw(8@bTMOOiPb!-6qifbzV&{{aHr3I8GgZsL!U{Efis))_iP3|LA1 zPCS+w!#*m`DAg@#$D>+~Jf@)u&mFg|8?G!Vkz8_o=t#+>175NbleBA3_GlHs^tAK! zZJl|t&>|3c?|I*481~IC2NgvN2`Zf^Fmg#V+l>d9Hq(x$RH0WpOnJG&x@a9^-N%pJ z%?o#5TSH;o`Qo#l9l^mfRAZa33V6R_t%Jx2dqyH{eyPq^<}MIpc@0W`)W^9Q*r3_9 zwVb0izg}N=Do{bKtO}oBU+%KAD^k`Ol4Bmce0it+{Eyx83TVO_=E@Rl*rBKOe~sgJN>?^56$+0rdCpAMxI~)3cVd ztK{z=^c_PPi2a1S^Z_;_uI7HXE2{af#H$x|hm*%IwO_1SOq7vva=JM+@es{*%D!&6 zFDCZ;{D}E%*P#|_kf zFQoY1YezaH5~;8}c?LO@BPAzS)cxkEkuC~9nN12$PiNA9a`EJf6q9Wyl6DRjC zwxlv{PLy{g3utk$cP)J1U^$*VnEw8qlOdK6N>H+2EPqAtvvQ4M++$Y}{SvGzXCFWE zrC9TrTvMZ!l$654!rmbP@fJ9|ruNC=oX;APS2ZLd!F=6Ks<%&>gPWVs!s5AtENiF# z!VUV@{#l*fndfGC$HL*upMpmIi;+jC16uWnJ1;M*GCSmPfdf{3yZ$Fc_Vex3U|ryF z!X3Dj~)V}+s%U%JS>{9&!{;vT1a~THXecA6H(!a;;&_WJ zhDDl=@7*Z#!FhB6B_W)Oo<4eZR_1MTau=pn(l-kM^W14F-pks>g(1i;Kc}|bygoma zwEuN}NAAW~UeKhOq}(7nHPwcS82_3T{VPBvV<@VoCd0WiL+yRXm=*KAwsXBVFT=^&@m^b_SMzZw+IkqLiOLl?V=QK0$hTcu;r_ zHM>iG`I=6k$k4bqLMAFEW;v3LKiP3Z1-84fiHY#4Dq-U$7xI@cld4@-Tr{%MSGA#} zbhGhG{T+SfM!)D~E(TQ1|E&lWwh~;30=@?$F1!6Q3b_QfS^v4c)Sz6!(h?7NQ@4cw zYuIO@)55qTn-uB77hG1x&&kbAaq5=_0S)@qa*Oy{!abJUA)*np$h-|ho?KaWcTqtKrY!vCOOClQ-u1! zt?>NMchL{}e-v5fSxNC@&d;T8OS+IXIKC@rYs07eFQQVzBWTAgzp9D>L@%#DUtg&N z@9n(`4V9R=+t=v1FVcSHv3E`brj>-xF`kGB<~SzXkDuNA=uf}4u5S3jn$YSh#c<$MmI6zn|RC&r)t`Xx1Lf9Xgf z;M&sZ<{E*AOt%+iFaWO|x8w9Kr~=@><5lY$(v{m^5HA;VNADW~##cOeiR%Pw!>gTH zFB%$}ysE0nN^$?DC=+O2UfyfX?c<`N&!NX2Kb7nM{IL}kZy+lT2%v%ln&D3p@Dv2< z{p*B0_^B%_8LiRE1&WUziHV?4gzndW{upk}yru$!(mRyVaEW0W(W8Qcy>4uFmTWbs z)+91g4IAseJw36$&KnvL?|fQT8jXm;zxm>i3@&SIY$SGfcUOvIm7)z)FPhfi9MN~~ z3Gc7A=rN3879TD-V3T;o5J4Fb>AEJETTwB5qI?cZ8VHS}i0-j|-mlEg$43G-qc2oW zQ#D+va(?MOX@$@G+m#iAmck@TloZf~V>V)Vr?CZV!DBxpBuWGjY^ZsE+8KnCD$H%6NK}2+x-wGosa@_kbF81RCe6ii#me08AcV6u; z(#|$NmNRFgh9_jpkqfn->iO>aoRFu=aUsES_k1w9I5AUZPHmH{c8VKQb|4d6X>^4d#%!@cM1Xm#O!j+m5JL z!jOcufY0}Z%iI_&${OsGk()*}MYkZRN|lqcRg)|V*uRc0f{Z$NXOWFA=PtgR-ST?3 zXXlsC)e&dX&$GXS1&totO!i`>Jp#Ybfd~MN2Rz=jJu|oCnW^9I{%MvI^h0VnyVl?D zOzt)^-?Pp1M*Aj5`YXhW@ml6=SqhgeJNTOjQ~S($71yLge|}ih+|0Dwe!(ti+KPwq z*fhpRRoVSCZ9Nz!YIL`oTpNX`atA}&f0+SjbhNKkyh<9%TI|i6H-wk7*{7z>->gWBI8{d>bWD(qh-Y$s04ntWF$9Y2lg~yNYfBov1UtiB!U0sch+nHOD)BoB}mMQ(3 z)u_Qg%3((CVA4h%tzDvTjxpm$hbyDeTcT+iZ4qg^>cL7n#_KjCjUBb#?qc7@t)+Y? z!0I3%@IKIJ#XVv$rSkVgIf-$*FL`7n@t0xK@R#H7^KW`1{7O~z^iW_QVxwS{2@MWL zeyaCAh7}4?Ki8q5$7{5@*=>O;ph?@NTT)WR1jxOwIv<;17Dn?pz6>4NJkAPSINqL- za9*^75)gp(0j694;d}S-WaeqnE%Q3Vu^%rU8W~Afn6|C{Fhclp1+%j4%JLSpUoZ;n z8IG8SE!gD6Gd4Oe5q|u5xp__zkY8I%Z9S6RKUKTN4tuc6JL*SDc;WVSk{*f3zZlCR z!Ybs1=2{nNB=@rtMVqxW+pC{0A@g~=F|}Z$?Xs;?uQ6Q=>Gdodv)PJG@geBMMYsJZ z5Z_>}CmJ+*+xx`P(+Dc-1q90BCD>iEF)~Juj#5PwDERpa7#a<=i>r4zwB8ABZ+E0u z5Dwh+Y~^7CO|YnwV*OY?QK8eY&7QEA3_D+j{JJR~-`ELbRw67c^yz3>qBj23k639a zR{Kq1dP~uXb+jB$an!5E-RxUdndBpvmY;1jkS{Dw*ub>$KxuaE^nSzRdm)uOe8aoM zt3w$PIagZ*zH8F8S=mCzVy0AzOs}k25L0^Pd{8<`$*HHcnETwC>dFQa{Ijjk;=mN> zIXj^DYp?6=*@O-#!~dXB*EUmt$h{tH2A>7WCT*H(3r=lRAi$Nl?^Ktkd@>WvN5 zJ^xlnW!o|La88G)C%$Q?9Eo1Q*uFmTYWn z7<4jft*zN5&vs@CBLib%+&DQoRgr;?%reMeM@aAI&l>>RyHAv$9# ziq~2i8lA0Pwf7t|#VJnJI=XipEpOA&C3An!|7bOmUbOJvd##*c+Ple!I|KXoh1uD= zv`bYC$-dt>>p@=z`^o7m`on?)BiQ_@KqT{G9LE)BQ^4zsq-0HMrxC*kO1RWdnV0xZA=w-P(5ypPmnPGeFvVM*BQ~7iLnPxYQ zr2qDKdb(l5`5WdQ8pXE?=qNxYa0t^g+w@FTQ#e3G+eZp$cD%P#UpUH4T9{7er0H$zmLA;xCC_1n zdB0SY;veO{+3ZxwN&&X=r}g&tFvFR@s}_h*+K(TH2zAKF*=EhhMT0h=T(LDTCS?sO zO~V9?vR$NTU-nUWo0eYA4U5goP}lk@Vwvef@0y% z|(2mE+%x@9tjlPL_$Bj6Ikt2>X`GCiEZBj;5CnR!h>2xH8S(`4j89YPGnM zlA{9dk7BQ`V1oJ2=SOzlm}J6kvaQK#=75`vi?$$L~N96d6um5v&ijKB+C>Re#?{hZ*zhfX0()$-a&eQSbCT8*}CCx$8&7%!$2gELQGEnnIm2%^wXyS#I4(XOSH6)CEV6Y-@g0R zx|s%MbCc`Z{`sbp4O>vzOJ(*O_KSuBF8K@uW^b+_pKPq0!9# zN=mil+ZKV_L5K7b1yk-M1XIM{1y5`VQl?f!jYVxcI-Q~`rg zcFHL)cbKfTp8rthyrqf#U`XDHQhAFPv$fT~w^f@FA>md-4W^3L+mt8Xg<6VKuYPyG z0Q1hMaV>j*0mV&IUS4kF=-9V1_(a7a_PG;#lx220mIfkWe!TT8WVk0s!kHw;w}!mI z(X0J2*l<6sdvITvtDgfg|nhS2d*T9@ikOq60CZ zlCyKEfknAxMR4*!*cn6+E+jei?au>`}a?md1E-!q!)!XZ_a8(@Rg! zz+l3vgVlsMWf5j=^7 z?y$i&B0UalZO|cC&dGg#igY*64?i6ZIJ+YpyYpwl^uJ5Ny8Z z_p!TISy(JAG(23&_q{NQY65|y<1060V;DmDNiByFaoXOg!7M33;}1|*KT<%{z2AYfxr*3``E z(E-Ofe6Yo3nL2#{$_$SfFhl7ZdyJ?ma2_^p=Il6trk81t zcjd9O#%n6fbo`BMAd&X=1>Ty2iwkSdxR(4z)q2DgH`oy3@>-4ke^bKSD0!llhM~Y0 zVKPvU=>fYD$V1Hh=KV)|6=zRlFLrMPgM)AHB3NSi4G*<*NKWuA2q|u#idUEp9aX>B z>G{>Vw$(HqE5e;rB8Nm;(gIme_z!L!9g(L>x$}Vo*4(->bp6O1td<2$O$4Ce@TgLr zQDAwwtkZSGL0Mg$1gf}F2%9JO{W~D`Y=Q%kzjStX<|N@GxBlo}xxow?Z71WDd}3qY z8vF61tww4BUYqHfHgu`)GrOcDh`iK3l$SIAmAg?umm6^K@GygAkVaRJMOuEe?cMTH ze8X=L{8l}c@^g4UgUvs+efThB{Oj)!l1?j;m6vtXM`)TQukltDFE2@ukiF;i7abZA zAx)#Gp+Uy|C^L|lnmf02Flu_*@Y%2<89nj=NPCDm8pppFq&u4P{ylltvMYbJoV4vC z&~B2NlXIg7JQ5EfuY2+|28*r2d%B}j>#LxtDFB#Xow+z$?@}({ew&(^TBUa4|QF`u#1S)G;lu)*rA#C*BU-ST$Q!AUw4}e zF}P^iJ$Ued7ex;d_QdhCfhpNr>3>850-VX0StdXmaqWOrcb#1mSTOKwvGw&HG<0+v z@*Tka`*j~GD^D(TEI}{@DsB-5%;A!*7>;{mut2KYw?hvPH$cIQVpnE6x(#n-{^pw1 zaqjSPr9&>CPe@1z-kFNcCT3-zehEUA@X$T0^Vb#_59%ftpX(yln z7(f;ajLJjMazjH6;SA07KYw=zZF_opsNnFRg#~j?E-oZDHRD0O8#8G^VuXl@h?I;>D??}JRkeuu-{nY z-uO)7V;pTkLilY;N(1GQVahP6A%8MOxdF2}n)FxwBRnQ1CLKe=@Te$0a9M@QpIy%u z#hEM!D~y}s%8led7w7CGY?|hnV%Iy=)zz=JzuB2Me6ptb04$u65HeCRF-3VDU^wpF zftNn1{6`BtO6nW~P$0n`^Dv^lvqWzmA>Tp8oup=4I~$xfBS06OS5}5AN+V0riaCkF zV`_@S1Hi#k$HXKWq=P`%gm!df?Td@;Zgh5L5a0-w?SE-kYkqNTa=Om^ete0Q^x@?jvJ}Ro2LsA*Pi5 zM5SDCT~XfYLjO6dkQHP^yCSKJb#!$JYny0Ogv|ai`kx5BsW8J0Q}!F+GeNB%ncdpJWtwy#4JPH;0te$Jgn?TwDato;?GZ4PH##>5Ng5!-z{$yvc=`AgO-vpt7-U$ja)CQoFyI28qZQR_F1*E=|Bl0} zQhv+~>c@`k?d?U}xkK#i>w*#k699ylnjTp(Fmc`v!u(*OQBycdjueddr*|wiGs9$ z5E5@H0n})+og3f{1lrG@O>svpN&$b(l(!V&LG$C7I>VnJC)?~NU!d|{4u^3y@$_s= z!_xWW%LXWF^$!V)Q>FqZ!ok zd1+AaEs8VR7j)4pceKRTbs*q4e4oHj4&X)ZQ8$B<RB{suM)$eM?~V{*zH_46BZU0Nua{Jno>>M1uw^$TtTdL`7)5w7Ted`%K)BT z7zSXCB(z^u7i3eL7&^fZU#dGDFAc!~U=$q9Eb0tXgk7T>F8LIrJEi1j1X3l^j89_;IuBQH$S@Y$i(EwHstf1NygES+hya1rlfD)8}JFq?Z{} zpFykM=jJYunjLM7YvJt0*1%GZ2TY-tlg9d=@FHJPV(I};5qbF=l-cp!0rBcF8{=Ud z8?{a<&6N)|*F9Fa1CYGBvchuU-v1^H2`a-C2$&DnCR1O`lT-;>(SvgbUte3xNy-mU zd%h2{)R9cFtDp>GoT=W&i)3KJ2-Z*8NBh3plX~z?qP3!;0@nFDk3Tt9xnjn?-lxdT zzq4PhibI22FB&AZnP_N4DHWo=AA8>7y65q=dU$wPB`P|axk#*6NG>f7L?%fChlvKI zKpv>+<>eJo zC{`%s&jSDq;*Q3xhUNY_Sk`ybbXp=&O0T|HR@?Il2$UyICtRNv0p9=AUlRBgokFMQ z5HGbNJ?cgZbP?s=xLw`VGw@(dn`sUgteXemR&|IjW*|qJuUaAvQ&Li1o7x%?_Uxii zwNu8lw{HE7Q!i473hUYW$SCIW^x-b^)Qb$Am-=EebZ10p{N?cuKii1PeZe{18q+Uv z*oOv*-4b?XgRPwzqI zFV19iLzsh&goK3G1d3Sv1i>|Te94H1vIpmEpa4$`mM<0HOJ3-($(IS|Ee5ji3!qit zq)OG11A;Q6Q`(OJ#Y^kL`p+y@LV>J!Nd7k=u=7yqfKalI{R@r`=b!iTr|jieKo#zZ zTYv5b@PM=a<>aZWL@#a#cL|OvGtJ+=eG~d!d~n{wrL7#;f(2tlMoxYO2~3Gp<*AeH z`8=W=%!KhTFD=~+_)lFu9Xud04lM-EsVs#V>Veay+2Px&0(clfqCKDJ&wqc`)YMQ6 zknM{E2?EkgAd&qE0qcM!@YUU`K!(A*SO4CigoJiE07yWt#V1%UeZg327mhh{ofz;g z*=8hRi_9hI><6wlc8%y|hCWa$utC9N5D97GcwhF{ra1mFkw#dXh#|~{wS~oRdRQQ1 zR-$k^!DtEr% zZwNpMq$;8P?+Hm7!-Z?fJCy(xB^{ZMV>WRstE=g4m|QX)s4!Gk@8dz_It1enbZXoY zI%3j*Ua`z!YO`RyCI4yV!^~4bS}~^1u>3%u?*|Pg8_%2st_cyIcp`R)%}q>m0vfw; z;#l4W(06Ya_j(?}10%o*WV}TGsA&WRxs75bHQ;U(by5EdWm~8N4wQ?L587O8WBUWjH}Gn9_in M(j#=m1M}ej0efhZfB*mh diff --git a/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml b/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml new file mode 100644 index 0000000..79d695e --- /dev/null +++ b/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml b/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml new file mode 100644 index 0000000..79d695e --- /dev/null +++ b/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/app/src/main/res/mipmap-xhdpi/ic_launcher.webp b/app/src/main/res/mipmap-xhdpi/ic_launcher.webp new file mode 100644 index 0000000000000000000000000000000000000000..968c43011c246a0aef50de6c32b66f664824ac7d GIT binary patch literal 1106 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 literal 0 HcmV?d00001 diff --git a/app/src/main/res/mipmap-xxxhdpi/ic_launcher_foreground.webp b/app/src/main/res/mipmap-xxxhdpi/ic_launcher_foreground.webp new file mode 100644 index 0000000000000000000000000000000000000000..537faf6ec2ce32204a302bd12c2f23d0ae8b2ba0 GIT binary patch literal 2374 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

_D^;J|yz)4C? zIw^u1ZONFmeJenX5tgX6pDn`JmA|io)}$>55R5^oQ{9FmvX2oin4{W(CP_sVB>$T| z=*X&$7nF*??72gRhkzK*DT*A3*gsfdtMxX!*V&WDfaichR8>olS$*(FOpqe#b(v{^ zPwrR`#zvc%K_I#Yy)Y}F=|Nu04PI6w1x5R5KPPXAgltQ_@3E|VS3IHJESHFY8!)d1 zsb#}H($^X88HGrVIqS)b zJU_jnQf}YZPe~u)x{{?f_d~l`WnJ|!M0iJiaRj0EewO!-Q-L$bK55WCOYvur!;&VK+&lOKzN_!4AQX}|lo1ZN4|6lA8>ebblEfDsITN)*X!o1phKlAQB_`aHM8VdB*@73O=TvCt~Otwjx+dWr|M)x8o(N>7< z_{U%3QxWEy;1$b({zwiBFvQuOjsx6`lYtIn`=gNfl7un+)O5S&wZ{DKpk89U3l`RV z8hMcCD$dROnC&jqm_D?QW|#37P{As(wCX+yA3)$*;1RP&KCE8{Gne`gcIFh}NkT_; zhOX^5PnTRSA%300qwQ}k2@L-+GIvB}-nV`mud1$=i9efe#B(rmA1V;gm^G%}xf)c# zp_ltQLUUp*{f%A^_*&8)+1&N^BfI~CYCEYBrX1rwxAu01yvaA+!S!%i`0WL*id1+n z5p$0>u^GTNZ#F((@4v6D9;1$4kVni+ewSe$yZR?;3AbECZ-N@`*ASTyWO8988r8Hr{U~F(zt?NL+Z|{;?U`CVERBr!=W$1jH{Qz|TiB;{X9p09N|>n9?nGO~QCW$}l@#eSbx z#Jmp6MEm&)QG^&`3`P@UoYwdqejJ3c1oCU<7}4%j8n2%~U$*MO%Ft;k>buaHdOm|} zvvs>PGVmgm^8Q+rGOViS!5lX9zkOYPekY`~7L;GFJSj5Gt+XR)QA*A(cr0Zn?^%Hi z@P^)dsFhhh*)Bvh?;V7&ch|<~kf`er&&FH1e~JF>1cIi|W&J@f5)!dPsJj5YZ4!XA zzXvA%K{-6_6v^OAR56JVnV`H|_wz1@nPG4CcR$IrHKV`|2~Z2@Fx}aKAs-4V1P+IG zN8q$MN*&`j>}i^fRE(FGMUt>oZe8~7IjkbLiTB;O2)Wfba$USvyC|WxWOyMovS)zK zYA+O7Fm1SbmT|gA{t&YSLf&PT2i6|}a*1DyRV^+4BLgwVi2&N=2+VCWz?~FQU|i%g zpI*~ni5tAyn5QN^CdeW3J5b-MWs6Wmro)9AD7egi)J1a!R^af#lwtyv@6-sfROhbq z3p^O}o$uT;X}Jo1F?bSJ&|H008y)4!>ReKn?HjkAr&h|1C!XWO>+EG?5a+j+$$`aD zYEQ@B(vCTR%+4x0uo-gzLyX8g%i51ZB7fXtm4R literal 0 HcmV?d00001 diff --git a/app/src/main/res/values/colors.xml b/app/src/main/res/values/colors.xml new file mode 100644 index 0000000..33aa166 --- /dev/null +++ b/app/src/main/res/values/colors.xml @@ -0,0 +1,4 @@ + + + #1e1e1e + \ No newline at end of file From bd4e3ad7857d39f9eb7e03fc9970366b80f607bc Mon Sep 17 00:00:00 2001 From: Ratul Hasan Date: Fri, 7 Nov 2025 14:28:46 +0600 Subject: [PATCH 13/27] fix drag in popup window --- .../main/res/layout/content_activity_info.xml | 110 ++++++++++++++++ app/src/main/res/layout/window_tasks.xml | 123 ------------------ 2 files changed, 110 insertions(+), 123 deletions(-) create mode 100644 app/src/main/res/layout/content_activity_info.xml delete mode 100644 app/src/main/res/layout/window_tasks.xml diff --git a/app/src/main/res/layout/content_activity_info.xml b/app/src/main/res/layout/content_activity_info.xml new file mode 100644 index 0000000..95609fa --- /dev/null +++ b/app/src/main/res/layout/content_activity_info.xml @@ -0,0 +1,110 @@ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/layout/window_tasks.xml b/app/src/main/res/layout/window_tasks.xml deleted file mode 100644 index 67758ca..0000000 --- a/app/src/main/res/layout/window_tasks.xml +++ /dev/null @@ -1,123 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - From 70bfbe0def1ed75be83a304f72b0632939a7efcd Mon Sep 17 00:00:00 2001 From: Ratul Hasan Date: Fri, 7 Nov 2025 14:29:16 +0600 Subject: [PATCH 14/27] add icons --- app/src/main/res/drawable/ic_cancel.xml | 10 ++++++++ app/src/main/res/drawable/ic_class.xml | 10 ++++++++ app/src/main/res/drawable/ic_github.xml | 7 +++--- app/src/main/res/drawable/ic_logo.xml | 29 ++++++++++++++++++++++++ app/src/main/res/drawable/ic_package.xml | 10 ++++++++ 5 files changed, 62 insertions(+), 4 deletions(-) create mode 100644 app/src/main/res/drawable/ic_cancel.xml create mode 100644 app/src/main/res/drawable/ic_class.xml create mode 100644 app/src/main/res/drawable/ic_logo.xml create mode 100644 app/src/main/res/drawable/ic_package.xml diff --git a/app/src/main/res/drawable/ic_cancel.xml b/app/src/main/res/drawable/ic_cancel.xml new file mode 100644 index 0000000..fe302f5 --- /dev/null +++ b/app/src/main/res/drawable/ic_cancel.xml @@ -0,0 +1,10 @@ + + + diff --git a/app/src/main/res/drawable/ic_class.xml b/app/src/main/res/drawable/ic_class.xml new file mode 100644 index 0000000..86cec13 --- /dev/null +++ b/app/src/main/res/drawable/ic_class.xml @@ -0,0 +1,10 @@ + + + diff --git a/app/src/main/res/drawable/ic_github.xml b/app/src/main/res/drawable/ic_github.xml index 03381d5..d56a2c9 100644 --- a/app/src/main/res/drawable/ic_github.xml +++ b/app/src/main/res/drawable/ic_github.xml @@ -2,10 +2,9 @@ + android:viewportWidth="24" + android:viewportHeight="24"> - + android:pathData="M12,2A10,10 0,0 0,2 12C2,16.42 4.87,20.17 8.84,21.5C9.34,21.58 9.5,21.27 9.5,21C9.5,20.77 9.5,20.14 9.5,19.31C6.73,19.91 6.14,17.97 6.14,17.97C5.68,16.81 5.03,16.5 5.03,16.5C4.12,15.88 5.1,15.9 5.1,15.9C6.1,15.97 6.63,16.93 6.63,16.93C7.5,18.45 8.97,18 9.54,17.76C9.63,17.11 9.89,16.67 10.17,16.42C7.95,16.17 5.62,15.31 5.62,11.5C5.62,10.39 6,9.5 6.65,8.79C6.55,8.54 6.2,7.5 6.75,6.15C6.75,6.15 7.59,5.88 9.5,7.17C10.29,6.95 11.15,6.84 12,6.84C12.85,6.84 13.71,6.95 14.5,7.17C16.41,5.88 17.25,6.15 17.25,6.15C17.8,7.5 17.45,8.54 17.35,8.79C18,9.5 18.38,10.39 18.38,11.5C18.38,15.32 16.04,16.16 13.81,16.41C14.17,16.72 14.5,17.33 14.5,18.26C14.5,19.6 14.5,20.68 14.5,21C14.5,21.27 14.66,21.59 15.17,21.5C19.14,20.16 22,16.42 22,12A10,10 0,0 0,12 2Z" /> diff --git a/app/src/main/res/drawable/ic_logo.xml b/app/src/main/res/drawable/ic_logo.xml new file mode 100644 index 0000000..ca4573d --- /dev/null +++ b/app/src/main/res/drawable/ic_logo.xml @@ -0,0 +1,29 @@ + + + + + + + diff --git a/app/src/main/res/drawable/ic_package.xml b/app/src/main/res/drawable/ic_package.xml new file mode 100644 index 0000000..a1e3029 --- /dev/null +++ b/app/src/main/res/drawable/ic_package.xml @@ -0,0 +1,10 @@ + + + From ffd6b8907c5e8cd9f8d80d8e0bf2006059a1a5b2 Mon Sep 17 00:00:00 2001 From: Ratul Hasan Date: Fri, 7 Nov 2025 14:29:37 +0600 Subject: [PATCH 15/27] add view to configure width --- app/src/global/res/values/integers.xml | 5 ++++ .../res/layout/content_configure_width.xml | 26 +++++++++++++++++++ app/src/main/res/values/integers.xml | 5 ++++ 3 files changed, 36 insertions(+) create mode 100644 app/src/global/res/values/integers.xml create mode 100644 app/src/main/res/layout/content_configure_width.xml create mode 100644 app/src/main/res/values/integers.xml diff --git a/app/src/global/res/values/integers.xml b/app/src/global/res/values/integers.xml new file mode 100644 index 0000000..5537e9c --- /dev/null +++ b/app/src/global/res/values/integers.xml @@ -0,0 +1,5 @@ + + + 0 + 2 + \ No newline at end of file diff --git a/app/src/main/res/layout/content_configure_width.xml b/app/src/main/res/layout/content_configure_width.xml new file mode 100644 index 0000000..d34a5de --- /dev/null +++ b/app/src/main/res/layout/content_configure_width.xml @@ -0,0 +1,26 @@ + + + + + + diff --git a/app/src/main/res/values/integers.xml b/app/src/main/res/values/integers.xml new file mode 100644 index 0000000..caffa71 --- /dev/null +++ b/app/src/main/res/values/integers.xml @@ -0,0 +1,5 @@ + + + 2 + 0 + \ No newline at end of file From 524042fa53c72ad8494b13d8440b7987234b925f Mon Sep 17 00:00:00 2001 From: Ratul Hasan Date: Fri, 7 Nov 2025 14:30:15 +0600 Subject: [PATCH 16/27] refactor notification receiver --- .../model/NotificationMonitor.java | 116 ------------------ .../receivers/NotificationReceiver.java | 113 +++++++++++++++++ 2 files changed, 113 insertions(+), 116 deletions(-) delete mode 100644 app/src/main/java/io/github/ratul/topactivity/model/NotificationMonitor.java create mode 100644 app/src/main/java/io/github/ratul/topactivity/receivers/NotificationReceiver.java diff --git a/app/src/main/java/io/github/ratul/topactivity/model/NotificationMonitor.java b/app/src/main/java/io/github/ratul/topactivity/model/NotificationMonitor.java deleted file mode 100644 index 97b1c7e..0000000 --- a/app/src/main/java/io/github/ratul/topactivity/model/NotificationMonitor.java +++ /dev/null @@ -1,116 +0,0 @@ -/* - * Copyright (C) 2022 Ratul Hasan - * - * 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.ratul.topactivity.model; - -import android.app.Notification; -import android.app.NotificationChannel; -import android.app.NotificationManager; -import android.app.PendingIntent; -import android.app.TaskStackBuilder; -import android.content.BroadcastReceiver; -import android.content.Context; -import android.content.Intent; -import android.os.Build; - -import io.github.ratul.topactivity.R; -import io.github.ratul.topactivity.service.QuickSettingsTileService; -import io.github.ratul.topactivity.ui.MainActivity; -import io.github.ratul.topactivity.utils.DatabaseUtil; -import io.github.ratul.topactivity.utils.WindowUtil; - -/** - * Created by Ratul on 04/05/2022. - */ -public class NotificationMonitor extends BroadcastReceiver { - public static final int NOTIFICATION_ID = 696969691; - private static final int ACTION_STOP = 2; - private static final String EXTRA_NOTIFICATION_ACTION = "command"; - public static Notification.Builder builder; - public static NotificationManager notifManager; - - public static void showNotification(Context context, boolean isPaused) { - if (!DatabaseUtil.isNotificationToggleEnabled()) { - return; - } - notifManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE); - - Intent intent = new Intent(context, MainActivity.class); - TaskStackBuilder stackBuilder = TaskStackBuilder.create(context); - stackBuilder.addParentStack(MainActivity.class); - stackBuilder.addNextIntent(intent); - int flag; - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) { - flag = PendingIntent.FLAG_IMMUTABLE; - } else { - flag = PendingIntent.FLAG_UPDATE_CURRENT; - } - PendingIntent pIntent = stackBuilder.getPendingIntent(0, flag); - - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { - String CHANNEL_ID = context.getPackageName() + "_channel_007"; - CharSequence name = "Activity Info"; - - NotificationChannel mChannel = new NotificationChannel(CHANNEL_ID, name, NotificationManager.IMPORTANCE_DEFAULT); - mChannel.setDescription("Shows current activity info"); - mChannel.enableLights(false); - mChannel.enableVibration(false); - mChannel.setShowBadge(false); - notifManager.createNotificationChannel(mChannel); - - builder = new Notification.Builder(context, CHANNEL_ID); - } else { - builder = new Notification.Builder(context); - } - - builder.setContentTitle(context.getString(R.string.is_running, context.getString(R.string.app_name))) - .setSmallIcon(R.drawable.ic_shortcut) - .setContentText(context.getString(R.string.touch_to_open)) - .setColor(context.getColor(R.color.layerColor)) - .setVisibility(Notification.VISIBILITY_SECRET) - .setOngoing(!isPaused) - .setAutoCancel(true) - .setContentIntent(pIntent); - -// builder.addAction(R.drawable.ic_launcher_foreground, context.getString(R.string.noti_action_stop), -// getPendingIntent(context, ACTION_STOP)).setContentIntent(pIntent); - - notifManager.notify(NOTIFICATION_ID, builder.build()); - } - - public static PendingIntent getPendingIntent(Context context, int command) { - Intent intent = new Intent("io.github.ratul.topactivity.ACTION_NOTIFICATION_RECEIVER"); - intent.putExtra(EXTRA_NOTIFICATION_ACTION, command); - return PendingIntent.getBroadcast(context, 0, intent, PendingIntent.FLAG_IMMUTABLE); - } - - public static void cancelNotification(Context context) { - if (notifManager != null) - notifManager.cancel(NOTIFICATION_ID); - } - - @Override - public void onReceive(Context context, Intent intent) { - int command = intent.getIntExtra(EXTRA_NOTIFICATION_ACTION, -1); - if (command == ACTION_STOP) { - WindowUtil.dismiss(context); - DatabaseUtil.setIsShowWindow(false); - cancelNotification(context); - context.sendBroadcast(new Intent(MainActivity.ACTION_STATE_CHANGED)); - } - context.sendBroadcast(new Intent(QuickSettingsTileService.ACTION_UPDATE_TITLE)); - } -} diff --git a/app/src/main/java/io/github/ratul/topactivity/receivers/NotificationReceiver.java b/app/src/main/java/io/github/ratul/topactivity/receivers/NotificationReceiver.java new file mode 100644 index 0000000..a71f4fe --- /dev/null +++ b/app/src/main/java/io/github/ratul/topactivity/receivers/NotificationReceiver.java @@ -0,0 +1,113 @@ +package io.github.ratul.topactivity.receivers; + +import static android.app.PendingIntent.FLAG_IMMUTABLE; +import static android.app.PendingIntent.FLAG_UPDATE_CURRENT; + +import android.app.Notification; +import android.app.NotificationChannel; +import android.app.NotificationManager; +import android.app.PendingIntent; +import android.content.BroadcastReceiver; +import android.content.Context; +import android.content.Intent; +import android.os.Build; + +import androidx.annotation.NonNull; +import androidx.core.app.NotificationCompat; +import androidx.core.app.NotificationManagerCompat; + +import io.github.ratul.topactivity.App; +import io.github.ratul.topactivity.R; +import io.github.ratul.topactivity.ui.MainActivity; +import io.github.ratul.topactivity.utils.DatabaseUtil; +import io.github.ratul.topactivity.utils.WindowUtil; + +public class NotificationReceiver extends BroadcastReceiver { + public static final int NOTIFICATION_ID = 62345; + public static final String CHANNEL_ID = "activity_info"; + public static final int ACTION_COPY = 1; + public static final int ACTION_STOP = 2; + public static final String EXTRA_NOTIFICATION_ACTION = "command"; + + public static void createNotificationChannel(@NonNull NotificationManagerCompat notificationManager) { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { + NotificationChannel channel = new NotificationChannel(CHANNEL_ID, + "Activity Info", NotificationManager.IMPORTANCE_LOW); + channel.setDescription("Shows current activity info"); + notificationManager.createNotificationChannel(channel); + } + } + + public static void showNotification( + @NonNull Context context, @NonNull String title, String message) { + if (!DatabaseUtil.isShowNotification()) { + return; + } + NotificationManagerCompat notificationManager = App.getInstance().getNotificationManager(); + if (notificationManager.areNotificationsEnabled()) { + Notification notification = buildNotification(context, title, message); + notificationManager.notify(NOTIFICATION_ID, notification); + } + } + + public static void cancelNotification() { + App.getInstance().getNotificationManager() + .cancel(NOTIFICATION_ID); + } + + @Override + public void onReceive(Context context, Intent intent) { + int command = intent.getIntExtra(EXTRA_NOTIFICATION_ACTION, -1); + + switch (command) { + case ACTION_COPY: + App.copyString(context, + intent.getStringExtra(Intent.EXTRA_TEXT), + intent.getStringExtra(Intent.EXTRA_ASSIST_CONTEXT)); + break; + case ACTION_STOP: + DatabaseUtil.setShowingWindow(false); + NotificationReceiver.cancelNotification(); + WindowUtil.dismiss(context); + context.sendBroadcast(new Intent(MainActivity.ACTION_STATE_CHANGED)); + break; + } + } + + private static Notification buildNotification(Context context, String pkg, String cls) { + NotificationCompat.Action copyPkg = new NotificationCompat.Action(R.drawable.ic_package, "Package", + getCopyPendingIntent(context, 3429872, pkg, "Package copied")); + NotificationCompat.Action copyClass = new NotificationCompat.Action(R.drawable.ic_class, "Class", + getCopyPendingIntent(context, 3429873, cls, "Class copied")); + NotificationCompat.Action stop = new NotificationCompat.Action( + R.drawable.ic_cancel, "Stop", getStopPendingIntent(context)); + + return new NotificationCompat.Builder(context.getApplicationContext(), CHANNEL_ID) + .setContentTitle(pkg) + .setSmallIcon(R.drawable.ic_logo) + .setContentText(cls) + .setAutoCancel(false) + .setOngoing(true) + .addAction(copyPkg) + .addAction(copyClass) + .addAction(stop) + .build(); + } + + private static PendingIntent getCopyPendingIntent( + Context context, int requestCode, String text, String message) { + Intent intent = new Intent(context, NotificationReceiver.class) + .putExtra(EXTRA_NOTIFICATION_ACTION, ACTION_COPY) + .putExtra(Intent.EXTRA_TEXT, text) + .putExtra(Intent.EXTRA_ASSIST_CONTEXT, message); + return PendingIntent.getBroadcast(context, + requestCode, intent, FLAG_UPDATE_CURRENT | FLAG_IMMUTABLE); + } + + private static PendingIntent getStopPendingIntent(Context context) { + Intent intent = new Intent(context, NotificationReceiver.class) + .putExtra(EXTRA_NOTIFICATION_ACTION, ACTION_STOP); + return PendingIntent.getBroadcast(context, + 908435, intent, FLAG_UPDATE_CURRENT | FLAG_IMMUTABLE); + } +} From f5707a136cd1732d98bbe48d4251daf58af40150 Mon Sep 17 00:00:00 2001 From: Ratul Hasan Date: Fri, 7 Nov 2025 14:30:34 +0600 Subject: [PATCH 17/27] add null safety --- .../ratul/topactivity/utils/NullSafety.java | 145 ++++++++++++++++++ 1 file changed, 145 insertions(+) create mode 100644 app/src/main/java/io/github/ratul/topactivity/utils/NullSafety.java diff --git a/app/src/main/java/io/github/ratul/topactivity/utils/NullSafety.java b/app/src/main/java/io/github/ratul/topactivity/utils/NullSafety.java new file mode 100644 index 0000000..8e7a7f6 --- /dev/null +++ b/app/src/main/java/io/github/ratul/topactivity/utils/NullSafety.java @@ -0,0 +1,145 @@ +package io.github.ratul.topactivity.utils; + +import android.database.Cursor; +import android.os.Bundle; +import android.os.PersistableBundle; +import android.util.SparseArray; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; + +import java.util.Collection; +import java.util.Map; +import java.util.Objects; + +/** + * Can be used up to Java 8 + */ +public class NullSafety { + @NonNull + public static T requireNonNullElse(@Nullable T obj, @NonNull T defaultObj) { + return (obj != null) ? obj : Objects.requireNonNull(defaultObj, "defaultObj"); + } + + /** + * Returns {@code true} if the given {@link CharSequence} is {@code null} or + * consists only of whitespace characters. + */ + public static boolean isNullOrEmpty(@Nullable CharSequence charSequence) { + return charSequence == null || isBlank(charSequence); + } + + /** + * Returns {@code true} if the given array is {@code null} or has no elements. + */ + public static boolean isNullOrEmpty(@Nullable T[] array) { + return array == null || array.length == 0; + } + + /** + * Returns {@code true} if the given array is {@code null} or has no elements. + */ + public static boolean isNullOrEmpty(@Nullable int[] array) { + return array == null || array.length == 0; + } + + /** + * Returns {@code true} if the given array is {@code null} or has no elements. + */ + public static boolean isNullOrEmpty(@Nullable char[] array) { + return array == null || array.length == 0; + } + + /** + * Returns {@code true} if the given array is {@code null} or has no elements. + */ + public static boolean isNullOrEmpty(@Nullable byte[] array) { + return array == null || array.length == 0; + } + + /** + * Returns {@code true} if the given array is {@code null} or has no elements. + */ + public static boolean isNullOrEmpty(@Nullable short[] array) { + return array == null || array.length == 0; + } + + /** + * Returns {@code true} if the given array is {@code null} or has no elements. + */ + public static boolean isNullOrEmpty(@Nullable long[] array) { + return array == null || array.length == 0; + } + + /** + * Returns {@code true} if the given array is {@code null} or has no elements. + */ + public static boolean isNullOrEmpty(@Nullable double[] array) { + return array == null || array.length == 0; + } + + /** + * Returns {@code true} if the given array is {@code null} or has no elements. + */ + public static boolean isNullOrEmpty(@Nullable float[] array) { + return array == null || array.length == 0; + } + + /** + * Returns {@code true} if the given {@link Collection} is {@code null} or empty. + */ + public static boolean isNullOrEmpty(@Nullable Collection collection) { + return collection == null || collection.isEmpty(); + } + + /** + * Returns {@code true} if the given {@link SparseArray} is {@code null} or has no + * elements. + */ + public static boolean isNullOrEmpty(@Nullable SparseArray sparseArray) { + return sparseArray == null || sparseArray.size() == 0; + } + + /** + * Returns {@code true} if the given {@link Map} is {@code null} or empty. + */ + public static boolean isNullOrEmpty(@Nullable Map map) { + return map == null || map.isEmpty(); + } + + /** + * Returns {@code true} if the given {@link Bundle} is {@code null} or empty. + */ + public static boolean isNullOrEmpty(@Nullable Bundle bundle) { + return bundle == null || bundle.isEmpty(); + } + + /** + * Returns {@code true} if the given {@link PersistableBundle} is {@code null} or empty. + */ + public static boolean isNullOrEmpty(@Nullable PersistableBundle bundle) { + return bundle == null || bundle.isEmpty(); + } + + /** + * Returns {@code true} if the given {@link Cursor} is {@code null}, closed, or has no + * rows. + */ + public static boolean isNullOrEmpty(@Nullable Cursor cursor) { + return cursor == null || cursor.isClosed() || cursor.getCount() == 0; + } + + private static boolean isBlank(@NonNull CharSequence charSequence) { + int length = charSequence.length(); + int left = 0; + + while (left < length) { + char ch = charSequence.charAt(left); + if (ch != ' ' && ch != '\t' && !Character.isWhitespace(ch)) { + return false; + } + left++; + } + return true; + } +} From d41bac5b2e2d53cefedee9ba8d0e9e0fdf35acaf Mon Sep 17 00:00:00 2001 From: Ratul Hasan Date: Fri, 7 Nov 2025 14:30:53 +0600 Subject: [PATCH 18/27] remove unnecessary strings --- app/src/global/res/values/strings.xml | 4 ++++ app/src/main/res/values/strings.xml | 7 ------- 2 files changed, 4 insertions(+), 7 deletions(-) create mode 100644 app/src/global/res/values/strings.xml diff --git a/app/src/global/res/values/strings.xml b/app/src/global/res/values/strings.xml new file mode 100644 index 0000000..bdb49b2 --- /dev/null +++ b/app/src/global/res/values/strings.xml @@ -0,0 +1,4 @@ + + + We use accessibility permission to monitor window change events. So that we can show the current activity info. + diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 661e53d..7e2d536 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -1,11 +1,4 @@ Current Activity - Show Window - We use accessibility permission to monitor window change events. So that we can show the current activity info. - Show floating window - Don\'t show notification - %s is running - Touch for settings. - Stop From 8df12ee2365af9ba85f72066aeb66fbe8b5c1200 Mon Sep 17 00:00:00 2001 From: Ratul Hasan Date: Fri, 7 Nov 2025 14:31:10 +0600 Subject: [PATCH 19/27] refactor package monitor --- .../service/MonitoringService.java | 136 ------------------ .../services/PackageMonitoringService.java | 132 +++++++++++++++++ 2 files changed, 132 insertions(+), 136 deletions(-) delete mode 100644 app/src/main/java/io/github/ratul/topactivity/service/MonitoringService.java create mode 100644 app/src/main/java/io/github/ratul/topactivity/services/PackageMonitoringService.java diff --git a/app/src/main/java/io/github/ratul/topactivity/service/MonitoringService.java b/app/src/main/java/io/github/ratul/topactivity/service/MonitoringService.java deleted file mode 100644 index c55a382..0000000 --- a/app/src/main/java/io/github/ratul/topactivity/service/MonitoringService.java +++ /dev/null @@ -1,136 +0,0 @@ -/* - * Copyright (C) 2022 Ratul Hasan - * - * 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.ratul.topactivity.service; - -import android.app.AlarmManager; -import android.app.PendingIntent; -import android.app.Service; -import android.app.usage.UsageEvents; -import android.app.usage.UsageStatsManager; -import android.content.Context; -import android.content.Intent; -import android.os.Handler; -import android.os.IBinder; -import android.os.SystemClock; - -import io.github.ratul.topactivity.utils.DatabaseUtil; -import io.github.ratul.topactivity.utils.WindowUtil; - -/** - * Created by Wen on 16/02/2017. - * Refactored by Ratul on 04/05/2022. - */ -public class MonitoringService extends Service { - public boolean serviceAlive = false; - private boolean firstRun = true; - public static MonitoringService INSTANCE; - private UsageStatsManager usageStats; - public Handler mHandler = new Handler(); - private String text; - private String text1; - - @Override - public void onCreate() { - super.onCreate(); - INSTANCE = this; - - serviceAlive = true; - usageStats = (UsageStatsManager) getSystemService(Context.USAGE_STATS_SERVICE); - } - - @Override - public void onDestroy() { - serviceAlive = false; - super.onDestroy(); - } - - public void getActivityInfo() { - long currentTimeMillis = System.currentTimeMillis(); - UsageEvents queryEvents = usageStats.queryEvents(currentTimeMillis - (firstRun ? 600000 : 60000), - currentTimeMillis); - while (queryEvents.hasNextEvent()) { - UsageEvents.Event event = new UsageEvents.Event(); - queryEvents.getNextEvent(event); - int type = event.getEventType(); - if (type == UsageEvents.Event.MOVE_TO_FOREGROUND) { - text = event.getPackageName(); - text1 = event.getClassName(); - } else if (type == UsageEvents.Event.MOVE_TO_BACKGROUND) { - if (event.getPackageName().equals(text)) { - text = null; - text1 = null; - } - } - } - } - - @Override - public IBinder onBind(Intent intent) { - return null; - } - - @Override - public int onStartCommand(Intent intent, int flags, int startId) { - INSTANCE = this; - Runnable runner = new Runnable() { - @Override - public void run() { - if (!DatabaseUtil.isShowWindow()) { - MonitoringService.INSTANCE.mHandler.removeCallbacks(this); - MonitoringService.INSTANCE.stopSelf(); - } - - String preText = MonitoringService.INSTANCE.text; - String preText1 = MonitoringService.INSTANCE.text1; - getActivityInfo(); - if (MonitoringService.INSTANCE.text == null) - return; - if (preText != null && preText.equals(MonitoringService.INSTANCE.text) - && preText1 != null && preText1.equals(MonitoringService.INSTANCE.text1)) { - // not change, return - return; - } - - MonitoringService.INSTANCE.firstRun = false; - if (DatabaseUtil.isShowWindow()) { - WindowUtil.show(MonitoringService.INSTANCE, MonitoringService.INSTANCE.text, - MonitoringService.INSTANCE.text1); - } else { - MonitoringService.INSTANCE.stopSelf(); - } - mHandler.postDelayed(this, 500); - } - }; - - mHandler.postDelayed(runner, 500); - return super.onStartCommand(intent, flags, startId); - } - - @Override - public void onTaskRemoved(Intent rootIntent) { - Intent restartServiceIntent = new Intent(getApplicationContext(), this.getClass()); - restartServiceIntent.setPackage(getPackageName()); - - PendingIntent restartServicePendingIntent = PendingIntent.getService(getApplicationContext(), 1, - restartServiceIntent, PendingIntent.FLAG_ONE_SHOT | PendingIntent.FLAG_IMMUTABLE); - AlarmManager alarmService = (AlarmManager) getApplicationContext().getSystemService(Context.ALARM_SERVICE); - alarmService.set(AlarmManager.ELAPSED_REALTIME, SystemClock.elapsedRealtime() + 500, - restartServicePendingIntent); - - super.onTaskRemoved(rootIntent); - } -} diff --git a/app/src/main/java/io/github/ratul/topactivity/services/PackageMonitoringService.java b/app/src/main/java/io/github/ratul/topactivity/services/PackageMonitoringService.java new file mode 100644 index 0000000..52c056c --- /dev/null +++ b/app/src/main/java/io/github/ratul/topactivity/services/PackageMonitoringService.java @@ -0,0 +1,132 @@ +/* + * Copyright (C) 2022 Ratul Hasan + * + * 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.ratul.topactivity.services; + +import static android.app.PendingIntent.FLAG_IMMUTABLE; +import static android.app.PendingIntent.FLAG_UPDATE_CURRENT; + +import static io.github.ratul.topactivity.utils.NullSafety.isNullOrEmpty; + +import android.app.AlarmManager; +import android.app.PendingIntent; +import android.app.Service; +import android.app.usage.UsageEvents; +import android.app.usage.UsageStatsManager; +import android.content.Context; +import android.content.Intent; +import android.os.Binder; +import android.os.Handler; +import android.os.IBinder; +import android.os.SystemClock; +import android.util.Log; + +import androidx.core.util.Pair; + +import io.github.ratul.topactivity.BuildConfig; +import io.github.ratul.topactivity.utils.DatabaseUtil; +import io.github.ratul.topactivity.utils.WindowUtil; + +/** + * Created by Wen on 16/02/2017. + * Refactored by Ratul on 04/05/2022. + */ +public class PackageMonitoringService extends Service { + private final IBinder binder = new LocalBinder(); + private final Handler handler = new Handler(); + private Runnable observerTask; + private UsageStatsManager usageStats; + + public class LocalBinder extends Binder { + public PackageMonitoringService getService() { + return PackageMonitoringService.this; + } + } + + @Override + public IBinder onBind(Intent intent) { + return binder; + } + + @Override + public void onCreate() { + super.onCreate(); + usageStats = (UsageStatsManager) getSystemService(Context.USAGE_STATS_SERVICE); + observerTask = () -> { + if (!DatabaseUtil.isShowingWindow()) { + handler.removeCallbacks(observerTask); + stopSelf(); + return; + } + + Pair currentApp = getForegroundApp(); + String currentPkgName = currentApp.first; + String currentClassName = currentApp.second; + + if (!isNullOrEmpty(currentPkgName) && !isNullOrEmpty(currentClassName)) { + if (BuildConfig.DEBUG) { + Log.d("PackageMonitoring", "Pkg: " + currentPkgName + ", Class: " + currentClassName); + } + if (WindowUtil.isViewVisible()) { + WindowUtil.show(this, currentPkgName, currentClassName); + } + } + handler.postDelayed(observerTask, 500); + }; + } + + @Override + public int onStartCommand(Intent intent, int flags, int startId) { + handler.removeCallbacks(observerTask); + handler.post(observerTask); + return START_STICKY; + } + + @Override + public void onTaskRemoved(Intent rootIntent) { + Intent intent = new Intent(this, getClass()); + PendingIntent pendingIntent = PendingIntent.getService(getApplicationContext(), + 264593, intent, FLAG_UPDATE_CURRENT | FLAG_IMMUTABLE); + AlarmManager alarmService = (AlarmManager) getSystemService(ALARM_SERVICE); + alarmService.set(AlarmManager.ELAPSED_REALTIME, + SystemClock.elapsedRealtime() + 500, pendingIntent); + super.onTaskRemoved(rootIntent); + } + + private Pair getForegroundApp() { + long currentTime = System.currentTimeMillis(); + // Query events in the last 10 seconds + UsageEvents usageEvents = usageStats.queryEvents(currentTime - 10000, currentTime); + String latestPackage = null; + String latestClass = null; + long latestTimestamp = 0; + + UsageEvents.Event event = new UsageEvents.Event(); + while (usageEvents.hasNextEvent()) { + usageEvents.getNextEvent(event); + + if (event.getEventType() == UsageEvents.Event.MOVE_TO_FOREGROUND) { + if (event.getTimeStamp() > latestTimestamp) { + latestTimestamp = event.getTimeStamp(); + latestPackage = event.getPackageName(); + latestClass = event.getClassName(); + } + } + } + + return new Pair<>(latestPackage, latestClass); + } +} From b2a834e426787c39c9acdf51eae78a508dcc3a6a Mon Sep 17 00:00:00 2001 From: Ratul Hasan Date: Fri, 7 Nov 2025 14:31:26 +0600 Subject: [PATCH 20/27] refactor tile service --- .../service/QuickSettingsTileService.java | 119 ----------------- .../services/QuickSettingsTileService.java | 120 ++++++++++++++++++ 2 files changed, 120 insertions(+), 119 deletions(-) delete mode 100644 app/src/main/java/io/github/ratul/topactivity/service/QuickSettingsTileService.java create mode 100644 app/src/main/java/io/github/ratul/topactivity/services/QuickSettingsTileService.java diff --git a/app/src/main/java/io/github/ratul/topactivity/service/QuickSettingsTileService.java b/app/src/main/java/io/github/ratul/topactivity/service/QuickSettingsTileService.java deleted file mode 100644 index 67fa79c..0000000 --- a/app/src/main/java/io/github/ratul/topactivity/service/QuickSettingsTileService.java +++ /dev/null @@ -1,119 +0,0 @@ -/* - * Copyright (C) 2022 Ratul Hasan - * - * 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.ratul.topactivity.service; - -import android.annotation.TargetApi; -import android.content.BroadcastReceiver; -import android.content.ComponentName; -import android.content.Context; -import android.content.Intent; -import android.content.IntentFilter; -import android.os.Build; -import android.provider.Settings; -import android.service.quicksettings.Tile; -import android.service.quicksettings.TileService; -import android.text.style.BackgroundColorSpan; -import io.github.ratul.topactivity.utils.DatabaseUtil; -import io.github.ratul.topactivity.ui.MainActivity; -import io.github.ratul.topactivity.utils.WindowUtil; -import io.github.ratul.topactivity.model.NotificationMonitor; -import io.github.ratul.topactivity.ui.BackgroundActivity; - -/** - * Created by Wen on 5/3/16. - * Refactored by Ratul on 04/05/2022. - */ -@TargetApi(Build.VERSION_CODES.N) -public class QuickSettingsTileService extends TileService { - public static final String ACTION_UPDATE_TITLE = "io.github.ratul.topactivity.ACTION.UPDATE_TITLE"; - private UpdateTileReceiver mReceiver; - - public static void updateTile(Context context) { - TileService.requestListeningState(context, new ComponentName(context, QuickSettingsTileService.class)); - context.sendBroadcast(new Intent(QuickSettingsTileService.ACTION_UPDATE_TITLE)); - } - - public void updateTile() { - getQsTile().setState(DatabaseUtil.isShowWindow() ? Tile.STATE_ACTIVE : Tile.STATE_INACTIVE); - getQsTile().updateTile(); - } - - @Override - public void onCreate() { - super.onCreate(); - mReceiver = new UpdateTileReceiver(); - } - - @Override - public void onTileAdded() { - DatabaseUtil.setQSTileAdded(true); - sendBroadcast(new Intent(MainActivity.ACTION_STATE_CHANGED)); - } - - @Override - public void onTileRemoved() { - super.onTileRemoved(); - DatabaseUtil.setQSTileAdded(false); - sendBroadcast(new Intent(MainActivity.ACTION_STATE_CHANGED)); - } - - @Override - public void onStartListening() { - registerReceiver(mReceiver, new IntentFilter(ACTION_UPDATE_TITLE)); - super.onStartListening(); - updateTile(); - } - - @Override - public void onStopListening() { - unregisterReceiver(mReceiver); - super.onStopListening(); - } - - @Override - public void onClick() { - if (DatabaseUtil.isShowWindow()) - return; - if (!MainActivity.usageStats(this) || !Settings.canDrawOverlays(this)) { - Intent intent = new Intent(this, MainActivity.class); - intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); - intent.putExtra(MainActivity.EXTRA_FROM_QS_TILE, true); - startActivityAndCollapse(intent); - } else { - if (DatabaseUtil.hasAccess() && AccessibilityMonitoringService.getInstance() == null) - startService(new Intent().setClass(this, AccessibilityMonitoringService.class)); - DatabaseUtil.setIsShowWindow(!DatabaseUtil.isShowWindow()); - if (DatabaseUtil.isShowWindow()) { - if (WindowUtil.sWindowManager == null) - WindowUtil.init(this); - NotificationMonitor.showNotification(this, false); - startService(new Intent(this, MonitoringService.class)); - } else { - WindowUtil.dismiss(this); - NotificationMonitor.showNotification(this, true); - } - sendBroadcast(new Intent(MainActivity.ACTION_STATE_CHANGED)); - } - } - - class UpdateTileReceiver extends BroadcastReceiver { - @Override - public void onReceive(Context context, Intent intent) { - updateTile(); - } - } -} diff --git a/app/src/main/java/io/github/ratul/topactivity/services/QuickSettingsTileService.java b/app/src/main/java/io/github/ratul/topactivity/services/QuickSettingsTileService.java new file mode 100644 index 0000000..afe4227 --- /dev/null +++ b/app/src/main/java/io/github/ratul/topactivity/services/QuickSettingsTileService.java @@ -0,0 +1,120 @@ +/* + * Copyright (C) 2022 Ratul Hasan + * + * 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.ratul.topactivity.services; + +import static android.app.PendingIntent.FLAG_IMMUTABLE; +import static android.app.PendingIntent.FLAG_UPDATE_CURRENT; + +import android.annotation.SuppressLint; +import android.app.PendingIntent; +import android.content.BroadcastReceiver; +import android.content.ComponentName; +import android.content.Context; +import android.content.Intent; +import android.content.IntentFilter; +import android.os.Build; +import android.service.quicksettings.Tile; +import android.service.quicksettings.TileService; + +import androidx.core.content.ContextCompat; + +import io.github.ratul.topactivity.receivers.NotificationReceiver; +import io.github.ratul.topactivity.ui.MainActivity; +import io.github.ratul.topactivity.utils.DatabaseUtil; +import io.github.ratul.topactivity.utils.WindowUtil; + +/** + * Created by Wen on 5/3/16. + * Refactored by Ratul on 04/05/2022. + */ +public class QuickSettingsTileService extends TileService { + private static final String ACTION_UPDATE_TITLE = "io.github.ratul.topactivity.ACTION_UPDATE_TILE"; + private UpdateTileReceiver mReceiver; + + public static void updateTile(Context context) { + TileService.requestListeningState(context.getApplicationContext(), + new ComponentName(context, QuickSettingsTileService.class)); + context.sendBroadcast(new Intent(QuickSettingsTileService.ACTION_UPDATE_TITLE)); + } + + public void updateTile() { + getQsTile().setState(DatabaseUtil.isShowingWindow() ? Tile.STATE_ACTIVE : Tile.STATE_INACTIVE); + getQsTile().updateTile(); + } + + @Override + public void onCreate() { + super.onCreate(); + mReceiver = new UpdateTileReceiver(); + } + + @Override + public void onTileAdded() { + sendBroadcast(new Intent(MainActivity.ACTION_STATE_CHANGED)); + } + + @Override + public void onTileRemoved() { + super.onTileRemoved(); + sendBroadcast(new Intent(MainActivity.ACTION_STATE_CHANGED)); + } + + @Override + public void onStartListening() { + ContextCompat.registerReceiver(getApplicationContext(), mReceiver, + new IntentFilter(ACTION_UPDATE_TITLE), ContextCompat.RECEIVER_EXPORTED); + updateTile(); + super.onStartListening(); + } + + @Override + public void onStopListening() { + getApplicationContext().unregisterReceiver(mReceiver); + super.onStopListening(); + } + + @SuppressLint("StartActivityAndCollapseDeprecated") + @Override + public void onClick() { + if (DatabaseUtil.isShowingWindow() && WindowUtil.isViewVisible()) { + DatabaseUtil.setShowingWindow(false); + NotificationReceiver.cancelNotification(); + WindowUtil.dismiss(this); + sendBroadcast(new Intent(MainActivity.ACTION_STATE_CHANGED)); + updateTile(); + return; + } + + Intent intent = new Intent(this, MainActivity.class) + .setFlags(Intent.FLAG_ACTIVITY_NEW_TASK) + .putExtra(MainActivity.EXTRA_FROM_QS_TILE, true); + + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.UPSIDE_DOWN_CAKE) { + startActivityAndCollapse(PendingIntent.getActivity(this, + 7456435, intent, FLAG_UPDATE_CURRENT | FLAG_IMMUTABLE)); + } else { + startActivityAndCollapse(intent); + } + } + + class UpdateTileReceiver extends BroadcastReceiver { + @Override + public void onReceive(Context context, Intent intent) { + updateTile(); + } + } +} From a0071818aa20204d6db8676b98cebcde65413541 Mon Sep 17 00:00:00 2001 From: Ratul Hasan Date: Fri, 7 Nov 2025 14:31:52 +0600 Subject: [PATCH 21/27] use appcompat theme --- app/src/main/res/values/themes.xml | 42 ++++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) create mode 100644 app/src/main/res/values/themes.xml diff --git a/app/src/main/res/values/themes.xml b/app/src/main/res/values/themes.xml new file mode 100644 index 0000000..76b2f28 --- /dev/null +++ b/app/src/main/res/values/themes.xml @@ -0,0 +1,42 @@ + + + + + + + + + + + + + + + From 739136598910811d55ccd7c677f66848aada8110 Mon Sep 17 00:00:00 2001 From: Ratul Hasan Date: Fri, 7 Nov 2025 14:32:09 +0600 Subject: [PATCH 22/27] optimize window updates --- .../ratul/topactivity/utils/WindowUtil.java | 311 ++++++++---------- 1 file changed, 142 insertions(+), 169 deletions(-) diff --git a/app/src/main/java/io/github/ratul/topactivity/utils/WindowUtil.java b/app/src/main/java/io/github/ratul/topactivity/utils/WindowUtil.java index e797c92..1c856d1 100644 --- a/app/src/main/java/io/github/ratul/topactivity/utils/WindowUtil.java +++ b/app/src/main/java/io/github/ratul/topactivity/utils/WindowUtil.java @@ -16,186 +16,159 @@ */ package io.github.ratul.topactivity.utils; +import android.annotation.SuppressLint; import android.content.Context; +import android.content.Intent; +import android.content.pm.PackageManager; import android.graphics.PixelFormat; import android.os.Build; -import android.view.MotionEvent; -import android.view.View; import android.view.Gravity; import android.view.LayoutInflater; +import android.view.MotionEvent; +import android.view.View; import android.view.WindowManager; -import android.content.ClipboardManager; -import android.content.ClipData; -import android.widget.Toast; -import android.widget.LinearLayout; -import android.graphics.Typeface; -import android.content.Intent; -import com.google.android.material.imageview.ShapeableImageView; +import android.widget.ImageView; +import android.widget.TextView; + +import androidx.annotation.NonNull; + +import io.github.ratul.topactivity.App; import io.github.ratul.topactivity.R; -import io.github.ratul.topactivity.model.NotificationMonitor; -import com.google.android.material.textview.MaterialTextView; +import io.github.ratul.topactivity.receivers.NotificationReceiver; +import io.github.ratul.topactivity.services.QuickSettingsTileService; import io.github.ratul.topactivity.ui.MainActivity; -import io.github.ratul.topactivity.ui.BackgroundActivity; -import io.github.ratul.topactivity.service.QuickSettingsTileService; -import io.github.ratul.topactivity.service.MonitoringService; -import io.github.ratul.topactivity.service.AccessibilityMonitoringService; -import android.content.pm.PackageInfo; -import android.content.pm.PackageManager; -import io.github.ratul.topactivity.App; /** * Created by Ratul on 04/05/2022. */ public class WindowUtil { - private static WindowManager.LayoutParams sWindowParams; - public static WindowManager sWindowManager; - private static View sView; - private static int xInitCord = 0; - private static int yInitCord = 0; - private static int xInitMargin = 0; - private static int yInitMargin = 0; - private static String text, text1; - private static MaterialTextView appName, packageName, className; - private static ClipboardManager clipboard; - public static boolean viewAdded = false; - - public static void init(final Context context) { - sWindowManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE); - - sWindowParams = new WindowManager.LayoutParams(WindowManager.LayoutParams.WRAP_CONTENT, - WindowManager.LayoutParams.WRAP_CONTENT, - Build.VERSION.SDK_INT >= Build.VERSION_CODES.O ? WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY - : WindowManager.LayoutParams.TYPE_PHONE, - WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE, PixelFormat.TRANSLUCENT); - - sWindowParams.gravity = Gravity.CENTER; - sWindowParams.width = (DatabaseUtil.getDisplayWidth() / 2) + 300; - sWindowParams.windowAnimations = android.R.style.Animation_Toast; - - sView = LayoutInflater.from(context).inflate(R.layout.window_tasks, null); - clipboard = (ClipboardManager) context.getSystemService(Context.CLIPBOARD_SERVICE); - appName = sView.findViewById(R.id.text); - packageName = sView.findViewById(R.id.text1); - className = sView.findViewById(R.id.text2); - ShapeableImageView closeBtn = sView.findViewById(R.id.closeBtn); - - closeBtn.setOnClickListener(new View.OnClickListener() { - public void onClick(View v) { - dismiss(context); - DatabaseUtil.setIsShowWindow(false); - NotificationMonitor.cancelNotification(context); - context.sendBroadcast(new Intent(MainActivity.ACTION_STATE_CHANGED)); - } - }); - - appName.setOnLongClickListener(new View.OnLongClickListener() { - public boolean onLongClick(View v) { - copyString(context, text, "App name copied"); - return true; - } - }); - - packageName.setOnLongClickListener(new View.OnLongClickListener() { - public boolean onLongClick(View v) { - copyString(context, text, "Package name copied"); - return true; - } - }); - - className.setOnLongClickListener(new View.OnLongClickListener() { - public boolean onLongClick(View v) { - copyString(context, text1, "Class name copied"); - return true; - } - }); - - sView.setOnTouchListener(new View.OnTouchListener() { - public boolean onTouch(View view, MotionEvent event) { - WindowManager.LayoutParams layoutParams = sWindowParams; - - int xCord = (int) event.getRawX(); - int yCord = (int) event.getRawY(); - int xCordDestination; - int yCordDestination; - int action = event.getAction(); - - if (action == MotionEvent.ACTION_DOWN) { - xInitCord = xCord; - yInitCord = yCord; - xInitMargin = layoutParams.x; - yInitMargin = layoutParams.y; - } - else if (action == MotionEvent.ACTION_MOVE) { - int xDiffMove = xCord - xInitCord; - int yDiffMove = yCord - yInitCord; - xCordDestination = xInitMargin + xDiffMove; - yCordDestination = yInitMargin + yDiffMove; - - layoutParams.x = xCordDestination; - layoutParams.y = yCordDestination; - sWindowManager.updateViewLayout(view, layoutParams); - } - return true; - } - }); - } - - private static void copyString(Context context, String str, String msg) { - if (Build.VERSION.SDK_INT < 29) { - ClipData clip = ClipData.newPlainText("Current Activity", str); - clipboard.setPrimaryClip(clip); - } else { - context.startActivity( - new Intent(context, BackgroundActivity.class).putExtra(BackgroundActivity.STRING_COPY, str) - .putExtra(BackgroundActivity.COPY_MSG, msg).addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)); - } - App.showToast(msg, 0); - } - - public static String getAppName(Context context, String pkg) { - try { - PackageManager pm = context.getPackageManager(); - return pm.getApplicationLabel(pm.getApplicationInfo(pkg, 0)).toString(); - } catch (Exception e) { - return "Unknown"; - } - } - - public static void show(Context context, String pkg, String clas) { - if (sWindowManager == null) { - init(context); - } - appName.setText(getAppName(context, pkg)); - packageName.setText(pkg); - className.setText(clas); - - if (!viewAdded) { - viewAdded = true; - if (DatabaseUtil.isShowWindow()) { - sWindowManager.addView(sView, sWindowParams); - } - } - - if (NotificationMonitor.builder != null) { - NotificationMonitor.builder.setContentTitle(pkg); - NotificationMonitor.builder.setContentText(clas); - NotificationMonitor.notifManager.notify(NotificationMonitor.NOTIFICATION_ID, - NotificationMonitor.builder.build()); - } - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { - QuickSettingsTileService.updateTile(context); - } - } - - public static void dismiss(Context context) { - viewAdded = false; - try { - sWindowManager.removeView(sView); - } catch (Exception e) { - e.printStackTrace(); - } - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { - QuickSettingsTileService.updateTile(context); - } - } + private static WindowManager.LayoutParams layoutParams; + private static WindowManager windowManager; + private static PackageManager packageManager; + private static View baseView; + private static int xInitCord = 0; + private static int yInitCord = 0; + private static int xInitMargin = 0; + private static int yInitMargin = 0; + private static TextView appName, packageName, className; + + public static void show( + @NonNull Context context, @NonNull String pkg, @NonNull String cls) { + if (windowManager == null || baseView == null) { + init(context.getApplicationContext()); + } + + if (!isViewVisible()) { + int userWidth = DatabaseUtil.getUserWidth(); + if (userWidth != -1) { + layoutParams.width = userWidth; + } else { + double displaySize = Math.min(1100, DatabaseUtil.getDisplayWidth()); + layoutParams.width = (int) (displaySize * 0.65); + } + windowManager.addView(baseView, layoutParams); + QuickSettingsTileService.updateTile(context); + } + + boolean isPackageChanged = !packageName.getText().toString().equals(pkg); + boolean isClassChanged = !className.getText().toString().equals(cls); + + if (isPackageChanged) { + appName.setText(getAppName(pkg)); + packageName.setText(pkg); + } + + if (isClassChanged) { + className.setText(cls); + } + + if (isPackageChanged || isClassChanged) { + NotificationReceiver.showNotification(context, pkg, cls); + } + } + + public static void dismiss(@NonNull Context context) { + if (windowManager != null) { + windowManager.removeView(baseView); + } + QuickSettingsTileService.updateTile(context); + } + + public static boolean isViewVisible() { + return baseView != null && baseView.isAttachedToWindow(); + } + + @SuppressLint("ClickableViewAccessibility") + private static void init(@NonNull Context context) { + windowManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE); + packageManager = context.getPackageManager(); + + layoutParams = new WindowManager.LayoutParams(WindowManager.LayoutParams.WRAP_CONTENT, + WindowManager.LayoutParams.WRAP_CONTENT, + Build.VERSION.SDK_INT >= Build.VERSION_CODES.O ? WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY + : WindowManager.LayoutParams.TYPE_PHONE, + WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE, PixelFormat.TRANSLUCENT); + + layoutParams.gravity = Gravity.CENTER; + layoutParams.windowAnimations = android.R.style.Animation_Toast; + + baseView = LayoutInflater.from(context).inflate(R.layout.content_activity_info, null); + appName = baseView.findViewById(R.id.app_name); + packageName = baseView.findViewById(R.id.package_name); + className = baseView.findViewById(R.id.class_name); + ImageView closeBtn = baseView.findViewById(R.id.closeBtn); + + View.OnLongClickListener copyListener = v -> { + TextView textView = (TextView) v; + String label = ""; + + if (v.getId() == R.id.app_name) label = "App name"; + else if (v.getId() == R.id.package_name) label = "Package"; + else if (v.getId() == R.id.class_name) label = "Class"; + + App.copyString(context, textView.getText().toString(), label + " copied"); + return true; + }; + + closeBtn.setOnClickListener(v -> { + DatabaseUtil.setShowingWindow(false); + NotificationReceiver.cancelNotification(); + dismiss(context); + context.sendBroadcast(new Intent(MainActivity.ACTION_STATE_CHANGED)); + }); + + packageName.setOnLongClickListener(copyListener); + className.setOnLongClickListener(copyListener); + + baseView.setOnTouchListener((view, event) -> { + int xCord = (int) event.getRawX(); + int yCord = (int) event.getRawY(); + + switch (event.getAction()) { + case MotionEvent.ACTION_DOWN: + xInitCord = xCord; + yInitCord = yCord; + xInitMargin = layoutParams.x; + yInitMargin = layoutParams.y; + return true; + case MotionEvent.ACTION_MOVE: + int xDiffMove = xCord - xInitCord; + int yDiffMove = yCord - yInitCord; + layoutParams.x = xInitMargin + xDiffMove; + layoutParams.y = yInitMargin + yDiffMove; + windowManager.updateViewLayout(view, layoutParams); + return true; + } + return false; + }); + } + + private static String getAppName(@NonNull String pkg) { + try { + return packageManager.getApplicationLabel( + packageManager.getApplicationInfo(pkg, 0)).toString(); + } catch (PackageManager.NameNotFoundException ignored) { + return "Unknown"; + } + } } From 4000a522ba76db3cb4c69920993930c4e79239fc Mon Sep 17 00:00:00 2001 From: Ratul Hasan Date: Fri, 7 Nov 2025 14:32:25 +0600 Subject: [PATCH 23/27] remove unnecessary preferences --- .../ratul/topactivity/utils/DatabaseUtil.java | 113 ++++++++---------- 1 file changed, 51 insertions(+), 62 deletions(-) diff --git a/app/src/main/java/io/github/ratul/topactivity/utils/DatabaseUtil.java b/app/src/main/java/io/github/ratul/topactivity/utils/DatabaseUtil.java index a57d6fe..9d821f8 100644 --- a/app/src/main/java/io/github/ratul/topactivity/utils/DatabaseUtil.java +++ b/app/src/main/java/io/github/ratul/topactivity/utils/DatabaseUtil.java @@ -16,8 +16,6 @@ */ package io.github.ratul.topactivity.utils; -import android.content.Context; -import android.content.SharedPreferences; import io.github.ratul.topactivity.App; /** @@ -25,64 +23,55 @@ * Refactored by Ratul on 04/05/2022. */ public class DatabaseUtil { - private static SharedPreferences sp = App.getApp().getSharedPreferences("io.github.ratul.topactivity", 0); - - public static int getDisplayWidth() { - return sp.getInt("width", 720); - } - - public static void setDisplayWidth(int width) { - sp.edit().putInt("width", width).apply(); - } - - public static boolean isShowWindow() { - return sp.getBoolean("is_show_window", false); - } - - public static boolean hasBattery() { - return sp.getBoolean("hasBattery", false); - } - - public static void setHasBattery(boolean bool) { - sp.edit().putBoolean("hasBattery", bool).apply(); - } - - public static void setIsShowWindow(boolean isShow) { - sp.edit().putBoolean("is_show_window", isShow).apply(); - } - - public static boolean appInitiated() { - return sp.getBoolean("app_init", false); - } - - public static void setAppInitiated(boolean added) { - sp.edit().putBoolean("app_init", added).apply(); - } - - public static boolean hasAccess() { - return sp.getBoolean("has_access", true); - } - - public static void setHasAccess(boolean added) { - sp.edit().putBoolean("has_access", added).apply(); - } - - public static boolean hasQSTileAdded() { - return sp.getBoolean("has_qs_tile_added", false); - } - - public static void setQSTileAdded(boolean added) { - sp.edit().putBoolean("has_qs_tile_added", added).apply(); - } - - public static boolean isNotificationToggleEnabled() { - if (!hasQSTileAdded()) { - return true; - } - return sp.getBoolean("is_noti_toggle_enabled", true); - } - - public static void setNotificationToggleEnabled(boolean isEnabled) { - sp.edit().putBoolean("is_noti_toggle_enabled", isEnabled).apply(); - } + public static int getDisplayWidth() { + return App.getInstance().getSharedPreferences() + .getInt("width", 720); + } + + public static void setDisplayWidth(int width) { + App.getInstance().getSharedPreferences().edit() + .putInt("width", width) + .apply(); + } + + public static int getUserWidth() { + return App.getInstance().getSharedPreferences() + .getInt("user_width", -1); + } + + public static void setUserWidth(int width) { + App.getInstance().getSharedPreferences().edit() + .putInt("user_width", width) + .apply(); + } + + public static boolean isShowingWindow() { + return App.getInstance().getSharedPreferences() + .getBoolean("is_show_window", false); + } + + public static void setShowingWindow(boolean bool) { + App.getInstance().getSharedPreferences().edit() + .putBoolean("is_show_window", bool).apply(); + } + + public static boolean useAccessibility() { + return App.getInstance().getSharedPreferences() + .getBoolean("has_access", false); + } + + public static void setUseAccessibility(boolean bool) { + App.getInstance().getSharedPreferences().edit() + .putBoolean("has_access", bool).apply(); + } + + public static boolean isShowNotification() { + return App.getInstance().getSharedPreferences() + .getBoolean("show_notification", false); + } + + public static void setShowNotification(boolean bool) { + App.getInstance().getSharedPreferences().edit() + .putBoolean("show_notification", bool).apply(); + } } From ffb60798ba3812fd06f9c21545c24c7cacb90eeb Mon Sep 17 00:00:00 2001 From: Ratul Hasan Date: Fri, 7 Nov 2025 14:32:49 +0600 Subject: [PATCH 24/27] refactor main activity --- .../java/io/github/ratul/topactivity/App.java | 84 ++- .../ratul/topactivity/ui/MainActivity.java | 713 +++++++++--------- app/src/main/res/layout/activity_main.xml | 149 +++- 3 files changed, 528 insertions(+), 418 deletions(-) diff --git a/app/src/main/java/io/github/ratul/topactivity/App.java b/app/src/main/java/io/github/ratul/topactivity/App.java index 6ddf932..2faf088 100644 --- a/app/src/main/java/io/github/ratul/topactivity/App.java +++ b/app/src/main/java/io/github/ratul/topactivity/App.java @@ -16,46 +16,70 @@ */ package io.github.ratul.topactivity; +import static io.github.ratul.topactivity.receivers.NotificationReceiver.createNotificationChannel; + import android.app.Application; -import io.github.ratul.topactivity.model.CrashHandler; +import android.content.ClipData; +import android.content.ClipboardManager; import android.content.Context; -import java.io.File; -import android.app.Activity; -import io.github.ratul.topactivity.ui.MainActivity; import android.content.Intent; -import io.github.ratul.topactivity.ui.CrashActivity; +import android.content.SharedPreferences; +import android.os.Build; import android.widget.Toast; -import android.os.Environment; -public class App extends Application { - private static App sApp; +import androidx.annotation.NonNull; +import androidx.core.app.NotificationManagerCompat; - @Override - protected void attachBaseContext(Context base) { - super.attachBaseContext(base); - sApp = this; - Thread.setDefaultUncaughtExceptionHandler(new CrashHandler(this)); - } +import io.github.ratul.topactivity.ui.CopyToClipboardActivity; + +public class App extends Application { + private static App instance; + private SharedPreferences sharedPreferences; + private NotificationManagerCompat notificationManager; - @Override - public void onCreate() { - super.onCreate(); - } + @Override + public void onCreate() { + super.onCreate(); + instance = this; + sharedPreferences = getSharedPreferences(getPackageName(), 0); + notificationManager = NotificationManagerCompat.from(this); + createNotificationChannel(notificationManager); + } - public static String getCrashLogDir() { - return getCrashLogFolder().getAbsolutePath(); - } + public SharedPreferences getSharedPreferences() { + return sharedPreferences; + } - public static File getCrashLogFolder() { - return sApp.getExternalFilesDir(null); - } + public NotificationManagerCompat getNotificationManager() { + return notificationManager; + } - public static App getApp() { - return sApp; - } + public static App getInstance() { + return instance; + } - public static void showToast(String str, int length) { - Toast.makeText(getApp(), str, length).show(); - } + public static void copyString(Context context, String str, String msg) { + if (Build.VERSION.SDK_INT < Build.VERSION_CODES.Q) { + ClipboardManager clipboard = (ClipboardManager) context.getSystemService(Context.CLIPBOARD_SERVICE); + ClipData clip = ClipData.newPlainText(context.getString(R.string.app_name), str); + clipboard.setPrimaryClip(clip); + } else { + Intent copyActivity = new Intent(context, CopyToClipboardActivity.class) + .putExtra(Intent.EXTRA_TEXT, str) + .setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); + context.startActivity(copyActivity); + } + showToast(context, msg); + } + public static void showToast(@NonNull Context context, @NonNull String message) { + try { + Toast.makeText(context, message, Toast.LENGTH_SHORT).show(); + } catch (Throwable ignored) { + try { + Toast.makeText(instance, message, Toast.LENGTH_SHORT).show(); + } catch (Throwable ignored2) { + } + } + } } diff --git a/app/src/main/java/io/github/ratul/topactivity/ui/MainActivity.java b/app/src/main/java/io/github/ratul/topactivity/ui/MainActivity.java index 1b2b612..721934e 100644 --- a/app/src/main/java/io/github/ratul/topactivity/ui/MainActivity.java +++ b/app/src/main/java/io/github/ratul/topactivity/ui/MainActivity.java @@ -16,51 +16,48 @@ */ package io.github.ratul.topactivity.ui; -import android.Manifest; -import android.app.Activity; +import static android.Manifest.permission.PACKAGE_USAGE_STATS; +import static android.Manifest.permission.POST_NOTIFICATIONS; +import static android.content.pm.PackageManager.PERMISSION_GRANTED; +import static io.github.ratul.topactivity.utils.NullSafety.isNullOrEmpty; + import android.app.AppOpsManager; import android.content.BroadcastReceiver; +import android.content.ComponentName; import android.content.Context; -import android.content.DialogInterface; import android.content.Intent; import android.content.IntentFilter; -import android.content.pm.PackageManager; +import android.content.ServiceConnection; import android.graphics.Insets; import android.net.Uri; import android.os.Build; import android.os.Bundle; +import android.os.IBinder; +import android.os.Process; import android.provider.Settings; -import android.text.Spannable; -import android.text.SpannableString; import android.util.DisplayMetrics; import android.view.Menu; import android.view.MenuItem; import android.view.View; import android.view.WindowInsets; import android.view.WindowMetrics; -import android.widget.CompoundButton; -import android.widget.CompoundButton.OnCheckedChangeListener; -import android.widget.Toast; +import android.widget.Button; +import android.widget.EditText; +import android.widget.TextView; -import androidx.annotation.NonNull; -import androidx.appcompat.app.ActionBar; +import androidx.activity.result.ActivityResultLauncher; +import androidx.activity.result.contract.ActivityResultContracts; +import androidx.appcompat.app.AlertDialog; import androidx.appcompat.app.AppCompatActivity; +import androidx.appcompat.widget.SwitchCompat; import androidx.core.content.ContextCompat; -import com.google.android.material.dialog.MaterialAlertDialogBuilder; -import com.google.android.material.switchmaterial.SwitchMaterial; - -import java.io.BufferedReader; -import java.io.File; -import java.io.FileOutputStream; -import java.io.FileReader; - import io.github.ratul.topactivity.App; +import io.github.ratul.topactivity.BuildConfig; import io.github.ratul.topactivity.R; -import io.github.ratul.topactivity.model.NotificationMonitor; -import io.github.ratul.topactivity.model.TypefaceSpan; -import io.github.ratul.topactivity.service.AccessibilityMonitoringService; -import io.github.ratul.topactivity.service.MonitoringService; +import io.github.ratul.topactivity.receivers.NotificationReceiver; +import io.github.ratul.topactivity.services.AccessibilityMonitoringService; +import io.github.ratul.topactivity.services.PackageMonitoringService; import io.github.ratul.topactivity.utils.DatabaseUtil; import io.github.ratul.topactivity.utils.WindowUtil; @@ -69,328 +66,350 @@ * Refactored by Ratul on 04/05/2022. */ public class MainActivity extends AppCompatActivity { - public static final int REQUEST_CODE_NOTIFICATION = 100; - public static final String EXTRA_FROM_QS_TILE = "from_qs_tile"; - public static final String ACTION_STATE_CHANGED = "io.github.ratul.topactivity.ACTION_STATE_CHANGED"; - private SwitchMaterial mWindowSwitch, mNotificationSwitch, mAccessibilitySwitch; - private BroadcastReceiver mReceiver; - private MaterialAlertDialogBuilder fancy; - public static MainActivity INSTANCE; - - @Override - protected void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - setContentView(R.layout.activity_main); - INSTANCE = this; - if (AccessibilityMonitoringService.getInstance() == null && DatabaseUtil.hasAccess()) - startService(new Intent().setClass(this, AccessibilityMonitoringService.class)); - - DatabaseUtil.setDisplayWidth(getScreenWidth(this)); - fancy = new MaterialAlertDialogBuilder(this).setNegativeButton("Close", new DialogInterface.OnClickListener() { - @Override - public void onClick(DialogInterface di, int btn) { - di.dismiss(); - } - }).setCancelable(false); - - SpannableString s = new SpannableString(getString(R.string.app_name)); - s.setSpan(new TypefaceSpan(this, "fonts/google_sans_bold.ttf"), 0, s.length(), - Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); - ActionBar actionBar = getSupportActionBar(); - actionBar.setTitle(s); - - mWindowSwitch = findViewById(R.id.sw_window); - mNotificationSwitch = findViewById(R.id.sw_notification); - mAccessibilitySwitch = findViewById(R.id.sw_accessibility); - - if (Build.VERSION.SDK_INT < 24) { - mNotificationSwitch.setVisibility(View.INVISIBLE); - findViewById(R.id.divider_useNotificationPref).setVisibility(View.INVISIBLE); - } - - mReceiver = new UpdateSwitchReceiver(); - ContextCompat.registerReceiver(this, mReceiver, new IntentFilter(ACTION_STATE_CHANGED), ContextCompat.RECEIVER_NOT_EXPORTED); - - mNotificationSwitch.setOnCheckedChangeListener(new SwitchMaterial.OnCheckedChangeListener() { - @Override - public void onCheckedChanged(CompoundButton button, boolean isChecked) { - DatabaseUtil.setNotificationToggleEnabled(!isChecked); - } - }); - mAccessibilitySwitch.setOnCheckedChangeListener(new SwitchMaterial.OnCheckedChangeListener() { - @Override - public void onCheckedChanged(CompoundButton button, boolean isChecked) { - DatabaseUtil.setHasAccess(isChecked); - if (isChecked && AccessibilityMonitoringService.getInstance() == null) - startService(new Intent().setClass(MainActivity.this, AccessibilityMonitoringService.class)); - } - }); - mWindowSwitch.setOnCheckedChangeListener(new SwitchMaterial.OnCheckedChangeListener() { - @Override - public void onCheckedChanged(CompoundButton button, boolean isChecked) { - if (!Settings.canDrawOverlays(MainActivity.this)) { - fancy.setTitle("Overlay Permission") - .setMessage("Please enable overlay permission to show window over other apps") - .setPositiveButton("Settings", new DialogInterface.OnClickListener() { - @Override - public void onClick(DialogInterface di, int btn) { - Intent intent = new Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION); - intent.setData(Uri.parse("package:" + getPackageName())); - startActivity(intent); - di.dismiss(); - } - }).show(); - mWindowSwitch.setChecked(false); - } else if (DatabaseUtil.hasAccess() && AccessibilityMonitoringService.getInstance() == null) { - fancy.setTitle("Accessibility Permission").setMessage( - "As per your choice, please grant permission to use Accessibility Service for Current Activity app in order to get current activity info") - .setPositiveButton("Settings", new DialogInterface.OnClickListener() { - @Override - public void onClick(DialogInterface di, int btn) { - Intent intent = new Intent(); - intent.setAction("android.settings.ACCESSIBILITY_SETTINGS"); - startActivity(intent); - di.dismiss(); - } - }).show(); - mWindowSwitch.setChecked(false); - } else if (!usageStats(MainActivity.this)) { - fancy.setTitle("Usage Access").setMessage( - "In order to monitor current task, please grant Usage Access permission for Current Activity app") - .setPositiveButton("Settings", new DialogInterface.OnClickListener() { - @Override - public void onClick(DialogInterface di, int btn) { - Intent intent = new Intent(); - intent.setAction("android.settings.USAGE_ACCESS_SETTINGS"); - startActivity(intent); - di.dismiss(); - } - }).show(); - mWindowSwitch.setChecked(false); - } else { - DatabaseUtil.setAppInitiated(true); - DatabaseUtil.setIsShowWindow(isChecked); - if (!isChecked) { - WindowUtil.dismiss(MainActivity.this); - } else { - WindowUtil.show(MainActivity.this, getPackageName(), getClass().getName()); - startService(new Intent(MainActivity.this, MonitoringService.class)); - } - } - } - }); - - if (getIntent().getBooleanExtra(EXTRA_FROM_QS_TILE, false)) - mWindowSwitch.setChecked(true); - } - - public static int getScreenWidth(Activity activity) { - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) { - WindowMetrics windowMetrics = activity.getWindowManager().getCurrentWindowMetrics(); - Insets insets = windowMetrics.getWindowInsets().getInsetsIgnoringVisibility(WindowInsets.Type.systemBars()); - return windowMetrics.getBounds().width() - insets.left - insets.right; - } else { - DisplayMetrics displayMetrics = new DisplayMetrics(); - activity.getWindowManager().getDefaultDisplay().getMetrics(displayMetrics); - return displayMetrics.widthPixels; - } - } - - @Override - protected void onNewIntent(Intent intent) { - super.onNewIntent(intent); - if (getIntent().getBooleanExtra(EXTRA_FROM_QS_TILE, false)) { - mWindowSwitch.setChecked(true); - } - } - - @Override - protected void onStart() { - super.onStart(); - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU && !mNotificationSwitch.isChecked()) { - if (checkSelfPermission(Manifest.permission.POST_NOTIFICATIONS) != PackageManager.PERMISSION_GRANTED) { - requestPermissions(new String[]{Manifest.permission.POST_NOTIFICATIONS}, REQUEST_CODE_NOTIFICATION); - } - } - } - - @Override - public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { - super.onRequestPermissionsResult(requestCode, permissions, grantResults); - if (requestCode == REQUEST_CODE_NOTIFICATION) { - if (grantResults[0] == PackageManager.PERMISSION_DENIED) { - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU - && shouldShowRequestPermissionRationale(Manifest.permission.POST_NOTIFICATIONS)) { - requestPermissions(new String[]{Manifest.permission.POST_NOTIFICATIONS}, REQUEST_CODE_NOTIFICATION); - } else { - showToast("POST_NOTIFICATIONS Permission Denied", Toast.LENGTH_SHORT); - } - } else { - showToast("POST_NOTIFICATIONS Permission Granted", Toast.LENGTH_SHORT); - } - } - } - - @Override - protected void onResume() { - super.onResume(); - refreshWindowSwitch(); - refreshNotificationSwitch(); - refreshAccessibilitySwitch(); - NotificationMonitor.cancelNotification(this); - } - - @Override - protected void onPause() { - super.onPause(); - if (DatabaseUtil.isShowWindow()) { - NotificationMonitor.showNotification(this, false); - } - } - - private void refreshWindowSwitch() { - mWindowSwitch.setChecked(DatabaseUtil.isShowWindow()); - if (DatabaseUtil.hasAccess() && AccessibilityMonitoringService.getInstance() == null) { - mWindowSwitch.setChecked(false); - } - } - - private void refreshAccessibilitySwitch() { - mAccessibilitySwitch.setChecked(DatabaseUtil.hasAccess()); - } - - private void refreshNotificationSwitch() { - mNotificationSwitch.setChecked(!DatabaseUtil.isNotificationToggleEnabled()); - } - - public void showToast(String str, int length) { - Toast.makeText(this, str, length).show(); - } - - @Override - public boolean onCreateOptionsMenu(Menu menu) { - menu.add("GitHub Repo").setIcon(R.drawable.ic_github).setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM); - SpannableString span = new SpannableString("About App"); - span.setSpan(new TypefaceSpan(this, "fonts/google_sans_regular.ttf"), 0, span.length(), - Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); - menu.add(span); - span = new SpannableString("Crash Log"); - span.setSpan(new TypefaceSpan(this, "fonts/google_sans_regular.ttf"), 0, span.length(), - Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); - menu.add(span); - span = new SpannableString("Bug Report"); - span.setSpan(new TypefaceSpan(this, "fonts/google_sans_regular.ttf"), 0, span.length(), - Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); - menu.add(span); - return super.onCreateOptionsMenu(menu); - } - - public String readFile(File file) { - StringBuilder text = new StringBuilder(); - try { - BufferedReader br = new BufferedReader(new FileReader(file)); - String line = br.readLine(); - while (line != null) { - text.append(line); - text.append("\n"); - line = br.readLine(); - } - - new FileOutputStream(file).write(text.toString().getBytes()); - } catch (Exception e) { - e.printStackTrace(); - } - return text.toString(); - } - - @Override - public boolean onOptionsItemSelected(MenuItem item) { - String title = item.getTitle().toString(); - if (title.equals("About App")) { - fancy.setTitle("About App").setMessage( - "An useful open source tool for Android Developers, which shows the package name and class name of current activity\n\nHere are the main features of this app!\n● It provides a freely moveable popup window to view current activity info\n● It supports text copying from popup window\n● It supports quick settings and app shortcut for easy access to the popup window. Meaning you can get the popup window in your screen from anywhere") - .show(); - } else if (title.equals("Crash Log")) { - String errorLog = readFile(new File(App.getCrashLogDir(), "crash.txt")); - if (errorLog.isEmpty()) - showToast("No log was found", 0); - else { - Intent intent = new Intent(this, CrashActivity.class); - intent.putExtra(CrashActivity.EXTRA_CRASH_INFO, errorLog); - intent.putExtra("Restart", false); - startActivity(intent); - } - } else if (title.equals("GitHub Repo")) { - fancy.setTitle("GitHub Repo").setMessage( - "It is an open source project. Would you like to visit the official github repo of this app") - .setPositiveButton("Yes", new DialogInterface.OnClickListener() { - @Override - public void onClick(DialogInterface di, int btn) { - di.dismiss(); - startActivity(new Intent().setAction(Intent.ACTION_VIEW) - .setData(Uri.parse("https://github.com/ratulhasanrahat/Current-Activity"))); - } - }).show(); - } else if (title.equals("Bug Report")) { - fancy.setTitle("Bug Report").setMessage( - "If you found a bug while using this app, please take a screenshot of it if possible. If it's a crash then you can find the crash log in this directory: " - + new File(App.getCrashLogDir(), "crash.txt").getAbsolutePath() - + "\n\nAfter you get all necessary things related to the bug, open an issue in github repo of this app with your bug report details") - .setPositiveButton("Create", new DialogInterface.OnClickListener() { - @Override - public void onClick(DialogInterface di, int btn) { - di.dismiss(); - startActivity(new Intent().setAction(Intent.ACTION_VIEW).setData( - Uri.parse("https://github.com/ratulhasanrahat/Current-Activity/issues/new"))); - } - }).show(); - } - return super.onOptionsItemSelected(item); - } - - @Override - protected void onDestroy() { - super.onDestroy(); - unregisterReceiver(mReceiver); - } - - class UpdateSwitchReceiver extends BroadcastReceiver { - @Override - public void onReceive(Context context, Intent intent) { - refreshWindowSwitch(); - refreshNotificationSwitch(); - refreshAccessibilitySwitch(); - } - } - - public static boolean usageStats(Context context) { - boolean granted = false; - AppOpsManager appOps = (AppOpsManager) context.getSystemService(Context.APP_OPS_SERVICE); - int mode = appOps.checkOpNoThrow(AppOpsManager.OPSTR_GET_USAGE_STATS, android.os.Process.myUid(), - context.getPackageName()); - - if (mode == AppOpsManager.MODE_DEFAULT) { - granted = (context.checkCallingOrSelfPermission( - android.Manifest.permission.PACKAGE_USAGE_STATS) == PackageManager.PERMISSION_GRANTED); - } else { - granted = (mode == AppOpsManager.MODE_ALLOWED); - } - return granted; - } - - public void setupBattery() { - fancy.setTitle("Battery Optimizations").setMessage( - "Please remove battery optimization/restriction from this app in order to run in background with full functionality") - .setPositiveButton("Ok", new DialogInterface.OnClickListener() { - @Override - public void onClick(DialogInterface di, int btn) { - di.dismiss(); - Intent intent = new Intent(); - intent.setAction("android.settings.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS"); - intent.setData(Uri.parse("package:" + getPackageName())); - startActivity(intent); - } - }).show(); - - } + public static final String ACTION_STATE_CHANGED = "io.github.ratul.topactivity.ACTION_STATE_CHANGED"; + public static final String EXTRA_FROM_QS_TILE = "from_qs_tile"; + private ActivityResultLauncher notificationPermissionLauncher; + private BroadcastReceiver updateReceiver; + private SwitchCompat showWindow, showNotification, useAccessibility; + private PackageMonitoringService monitoringService; + private boolean isServiceBound = false; + + private final ServiceConnection serviceConnection = new ServiceConnection() { + @Override + public void onServiceConnected(ComponentName name, IBinder service) { + PackageMonitoringService.LocalBinder binder = + (PackageMonitoringService.LocalBinder) service; + monitoringService = binder.getService(); + isServiceBound = true; + } + + @Override + public void onServiceDisconnected(ComponentName name) { + isServiceBound = false; + monitoringService = null; + } + }; + + class UpdateSwitchReceiver extends BroadcastReceiver { + @Override + public void onReceive(Context context, Intent intent) { + refreshWindowSwitch(); + refreshNotificationSwitch(); + refreshAccessibilitySwitch(); + } + } + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_main); + startAccessibilityService(); + DatabaseUtil.setDisplayWidth(getScreenWidth()); + + boolean isWindowActuallyShowing = WindowUtil.isViewVisible(); + if (DatabaseUtil.isShowingWindow() != isWindowActuallyShowing) { + DatabaseUtil.setShowingWindow(isWindowActuallyShowing); + } + + showWindow = findViewById(R.id.show_window); + showNotification = findViewById(R.id.show_notification); + useAccessibility = findViewById(R.id.use_accessibility); + Button downloadAccessibility = findViewById(R.id.download_accessibility); + Button configureWidth = findViewById(R.id.configure_width); + + updateReceiver = new UpdateSwitchReceiver(); + ContextCompat.registerReceiver(this, updateReceiver, + new IntentFilter(ACTION_STATE_CHANGED), ContextCompat.RECEIVER_EXPORTED); + + notificationPermissionLauncher = registerForActivityResult( + new ActivityResultContracts.RequestPermission(), + isGranted -> { + DatabaseUtil.setShowNotification(isGranted); + showNotification.setChecked(isGranted); + }); + + useAccessibility.setOnCheckedChangeListener((button, isChecked) -> { + DatabaseUtil.setUseAccessibility(isChecked); + startAccessibilityService(); + }); + + showNotification.setOnCheckedChangeListener((button, isChecked) -> { + DatabaseUtil.setShowNotification(isChecked); + + if (isChecked && !isNotificationGranted()) { + requestNotificationPermission(); + } + }); + + showWindow.setOnClickListener(v -> { + boolean isChecked = showWindow.isChecked(); + + if (!isChecked) { + DatabaseUtil.setShowingWindow(false); + NotificationReceiver.cancelNotification(); + WindowUtil.dismiss(this); + } + + if (isSystemOverlayGranted() && isCommonPermissionsGranted()) { + DatabaseUtil.setShowingWindow(true); + WindowUtil.show(this, getPackageName(), getClass().getName()); + startAccessibilityService(); + startPackageMonitoringService(); + } else { + showWindow.setChecked(false); + requestSystemOverlayPermission(); + requestCommonPermissions(); + } + }); + + downloadAccessibility.setOnClickListener(v -> { + Intent intent = new Intent(Intent.ACTION_VIEW) + .setData(Uri.parse( + "https://github.com/codehasan/Current-Activity/releases/tag/v" + + BuildConfig.VERSION_NAME)); + startActivity(intent); + }); + + configureWidth.setOnClickListener(v -> configureWidth()); + + if (handleQsTileIntent(getIntent())) { + moveTaskToBack(true); + } + } + + @Override + protected void onNewIntent(Intent intent) { + super.onNewIntent(intent); + if (handleQsTileIntent(intent)) { + moveTaskToBack(true); + } + } + + @Override + protected void onResume() { + super.onResume(); + startAccessibilityService(); + refreshWindowSwitch(); + refreshNotificationSwitch(); + refreshAccessibilitySwitch(); + } + + @Override + public boolean onCreateOptionsMenu(Menu menu) { + menu.add("GitHub Repo") + .setIcon(R.drawable.ic_github) + .setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM); + menu.add("Check for Update"); + return super.onCreateOptionsMenu(menu); + } + + @Override + public boolean onOptionsItemSelected(MenuItem item) { + CharSequence title = item.getTitle(); + if (isNullOrEmpty(title)) return true; + + Intent intent = new Intent(Intent.ACTION_VIEW); + switch (title.toString()) { + case "GitHub Repo": + intent.setData(Uri.parse("https://github.com/codehasan/Current-Activity")); + startActivity(intent); + break; + case "Check for Update": + intent.setData(Uri.parse("https://github.com/codehasan/Current-Activity/releases")); + startActivity(intent); + break; + } + return true; + } + + @Override + protected void onDestroy() { + unregisterReceiver(updateReceiver); + super.onDestroy(); + } + + private int getScreenWidth() { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) { + WindowMetrics windowMetrics = getWindowManager().getCurrentWindowMetrics(); + Insets insets = windowMetrics.getWindowInsets().getInsetsIgnoringVisibility(WindowInsets.Type.systemBars()); + return windowMetrics.getBounds().width() - insets.left - insets.right; + } else { + DisplayMetrics displayMetrics = new DisplayMetrics(); + getWindowManager().getDefaultDisplay().getMetrics(displayMetrics); + return displayMetrics.widthPixels; + } + } + + private boolean handleQsTileIntent(Intent intent) { + if (intent.getBooleanExtra(EXTRA_FROM_QS_TILE, false)) { + showWindow.setChecked(true); + showWindow.callOnClick(); + return DatabaseUtil.isShowingWindow(); + } + return false; + } + + private boolean isCommonPermissionsGranted() { + return !isAccessibilityNotStarted() && isUsageStatsGranted(); + } + + private boolean isSystemOverlayGranted() { + return Settings.canDrawOverlays(this); + } + + private boolean isNotificationGranted() { + if (Build.VERSION.SDK_INT < Build.VERSION_CODES.TIRAMISU) { + return true; + } + return checkSelfPermission(POST_NOTIFICATIONS) == PERMISSION_GRANTED; + } + + private boolean isUsageStatsGranted() { + AppOpsManager appOps = (AppOpsManager) getSystemService(Context.APP_OPS_SERVICE); + int mode = appOps.checkOpNoThrow(AppOpsManager.OPSTR_GET_USAGE_STATS, + Process.myUid(), getPackageName()); + + if (mode == AppOpsManager.MODE_DEFAULT) { + return checkCallingOrSelfPermission(PACKAGE_USAGE_STATS) == PERMISSION_GRANTED; + } + return mode == AppOpsManager.MODE_ALLOWED; + } + + @SuppressWarnings("ConstantConditions") + private boolean isAccessibilityNotStarted() { + return BuildConfig.FLAVOR.equals("global") && + DatabaseUtil.useAccessibility() && + AccessibilityMonitoringService.getInstance() == null; + } + + private void configureWidth() { + View dialogView = getLayoutInflater().inflate(R.layout.content_configure_width, null); + EditText widthInput = dialogView.findViewById(R.id.width); + TextView helperText = dialogView.findViewById(R.id.helper); + + int screenWidth = getScreenWidth(); + int userWidth = DatabaseUtil.getUserWidth(); + + if (userWidth != -1) { + widthInput.setText(String.valueOf(userWidth)); + } + helperText.append("enter a width between 500 and " + screenWidth + "."); + + AlertDialog alertDialog = new AlertDialog.Builder(this) + .setTitle("Configure Width") + .setView(dialogView) + .setNeutralButton("Cancel", (dialog, which) -> dialog.dismiss()) + .setPositiveButton("Save", null) + .create(); + + alertDialog.setOnShowListener(dialog -> { + Button saveButton = alertDialog.getButton(AlertDialog.BUTTON_POSITIVE); + saveButton.setOnClickListener(v -> { + String input = widthInput.getText().toString(); + + if (input.trim().isEmpty()) { + DatabaseUtil.setUserWidth(-1); + dialog.dismiss(); + App.showToast(this, "Saved"); + return; + } + + int width = Integer.parseInt(input); + if (width < 500) { + widthInput.setError("Width should be greater than 500"); + return; + } else if (width > screenWidth) { + widthInput.setError("Width should be less than screen width (" + screenWidth + ")"); + return; + } + + DatabaseUtil.setUserWidth(width); + dialog.dismiss(); + App.showToast(this, "Saved"); + }); + }); + + alertDialog.show(); + } + + private void startAccessibilityService() { + // Start Accessibility Monitoring Service if accessibility is enabled + if (isAccessibilityNotStarted()) { + Intent intent = new Intent( + this, AccessibilityMonitoringService.class); + getApplicationContext().startService(intent); + } + } + + private void startPackageMonitoringService() { + Intent intent = new Intent(this, PackageMonitoringService.class); + getApplicationContext().startService(intent); + getApplicationContext().bindService( + intent, serviceConnection, Context.BIND_AUTO_CREATE); + } + + private void refreshWindowSwitch() { + showWindow.setChecked(DatabaseUtil.isShowingWindow()); + } + + private void refreshNotificationSwitch() { + if (!isNotificationGranted()) { + DatabaseUtil.setShowNotification(false); + showNotification.setChecked(false); + return; + } + showNotification.setChecked(DatabaseUtil.isShowNotification()); + } + + private void refreshAccessibilitySwitch() { + useAccessibility.setChecked(DatabaseUtil.useAccessibility()); + } + + private void requestNotificationPermission() { + if (Build.VERSION.SDK_INT < Build.VERSION_CODES.TIRAMISU) { + return; + } + if (checkSelfPermission(POST_NOTIFICATIONS) != PERMISSION_GRANTED) { + notificationPermissionLauncher.launch(POST_NOTIFICATIONS); + } + } + + private void requestSystemOverlayPermission() { + if (!Settings.canDrawOverlays(this)) { + new AlertDialog.Builder(this) + .setTitle("System Overlay") + .setMessage("Please allow draw over other apps permission for 'Current Activity'") + .setPositiveButton("Settings", (dialog, which) -> { + Intent intent = new Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION) + .setData(Uri.parse("package:" + getPackageName())); + startActivity(intent); + dialog.dismiss(); + }) + .show(); + } + } + + private void requestCommonPermissions() { + if (isAccessibilityNotStarted()) { + new AlertDialog.Builder(this) + .setTitle("Accessibility Permission") + .setMessage("Please enable Accessibility Service for 'Current Activity'") + .setPositiveButton("Settings", (dialog, button) -> { + startActivity(new Intent(Settings.ACTION_ACCESSIBILITY_SETTINGS)); + dialog.dismiss(); + }) + .show(); + } + + if (!isUsageStatsGranted()) { + new AlertDialog.Builder(this) + .setTitle("Usage Access") + .setMessage("Please allow Usage Access permission for 'Current Activity'") + .setPositiveButton("Settings", (di, btn) -> { + startActivity(new Intent(Settings.ACTION_USAGE_ACCESS_SETTINGS)); + di.dismiss(); + }) + .show(); + } + } } diff --git a/app/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_main.xml index 9629aa1..f222959 100644 --- a/app/src/main/res/layout/activity_main.xml +++ b/app/src/main/res/layout/activity_main.xml @@ -1,93 +1,160 @@ - + android:gravity="center_horizontal" + android:orientation="vertical"> - + android:text="Show Floating Window" + android:textColor="?editTextColor" + android:textSize="16sp" /> - + android:layout_height="wrap_content" /> - + android:background="?actionBarDivider" /> - + android:orientation="vertical"> - + + + + + + android:layout_height="wrap_content" /> - + android:background="?actionBarDivider" /> + - + android:orientation="vertical"> + + - + + + + android:layout_height="wrap_content" + android:visibility="@integer/use_accessibility" /> + +