diff --git a/app/build.gradle b/app/build.gradle
index 18c9c58..e2223c4 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -10,8 +10,8 @@ android {
applicationId "com.flx_apps.digitaldetox"
minSdkVersion 21
targetSdkVersion 29
- versionCode 10000
- versionName "1.0.0"
+ versionCode 10001
+ versionName "1.0.1"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
@@ -62,6 +62,10 @@ dependencies {
annotationProcessor "org.androidannotations:androidannotations:4.7.0"
implementation "org.androidannotations:androidannotations-api:4.7.0"
kapt "org.androidannotations:androidannotations:4.7.0"
+
+ // About Info Screen
+ implementation 'com.github.ditacristianionut:AppInfoBadge:1.3'
+
// implementation 'androidx.room:room-runtime:2.3.0-alpha03'
// kapt 'androidx.room:room-compiler:2.3.0-alpha03'
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index 92b9a75..e423d0c 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -14,13 +14,15 @@
+ android:theme="@style/AppTheme"
+ tools:replace="android:label">
+
@@ -31,8 +33,8 @@
@@ -46,24 +48,11 @@
android:name=".QuickSettingsTileService"
android:icon="@drawable/ic_quick_settings_tile"
android:label="@string/app.quickSettingsTile"
- android:permission="android.permission.BIND_QUICK_SETTINGS_TILE"
- >
+ android:permission="android.permission.BIND_QUICK_SETTINGS_TILE">
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/app/src/main/java/com/flx_apps/digitaldetox/AboutFragment.kt b/app/src/main/java/com/flx_apps/digitaldetox/AboutFragment.kt
new file mode 100644
index 0000000..b397115
--- /dev/null
+++ b/app/src/main/java/com/flx_apps/digitaldetox/AboutFragment.kt
@@ -0,0 +1,47 @@
+package com.flx_apps.digitaldetox
+
+import android.net.Uri
+import android.os.Bundle
+import androidx.core.content.ContextCompat
+import androidx.fragment.app.Fragment
+import com.dci.dev.appinfobadge.AppInfoBadge
+import com.dci.dev.appinfobadge.BaseInfoItem
+import com.dci.dev.appinfobadge.InfoItemWithLink
+
+class AboutFragment : Fragment() {
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+ val appInfoBadgeFragment = AppInfoBadge
+ .headerColor { ContextCompat.getColor(context!!, R.color.colorPrimaryDark) }
+ .withAppIcon { true }
+ .withCustomItems { listOf(
+ InfoItemWithLink(
+ iconId = R.drawable.ic_coffee,
+ title = getString(R.string.about_coffee),
+ link = Uri.parse(getString(R.string.about_coffee_link))
+ ),
+ InfoItemWithLink(
+ iconId = R.drawable.ic_patron,
+ title = getString(R.string.about_patron),
+ link = Uri.parse(getString(R.string.about_patron_link))
+ ),
+ InfoItemWithLink(
+ iconId = R.drawable.ic_contact_mail_3,
+ title = getString(R.string.about_contact),
+ link = Uri.parse(getString(R.string.about_contact_link))
+ ),
+ InfoItemWithLink(
+ iconId = R.drawable.ic_contact_site_github,
+ title = getString(R.string.about_github),
+ link = Uri.parse(getString(R.string.about_github_link))
+ )
+ )}
+ .withPermissions { false }
+ .withRater { false }
+ .withChangelog { false }
+ .withLibraries { false }
+ .withLicenses { false }
+ .show()
+ fragmentManager!!.beginTransaction().replace(R.id.nav_host_fragment, appInfoBadgeFragment).commit()
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/flx_apps/digitaldetox/AppExceptionsListAdapter.kt b/app/src/main/java/com/flx_apps/digitaldetox/AppExceptionsListAdapter.kt
index 5aae047..d77da73 100644
--- a/app/src/main/java/com/flx_apps/digitaldetox/AppExceptionsListAdapter.kt
+++ b/app/src/main/java/com/flx_apps/digitaldetox/AppExceptionsListAdapter.kt
@@ -4,34 +4,34 @@ import android.content.Context
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
-import android.widget.CheckBox
import android.widget.ImageView
import android.widget.TextView
+import androidx.appcompat.widget.SwitchCompat
import androidx.recyclerview.widget.RecyclerView
import org.androidannotations.annotations.EBean
@EBean
open class AppExceptionsListAdapter(context: Context) : RecyclerView.Adapter() {
- lateinit var values: List
+ lateinit var values: List
var prefs: Prefs_ = Prefs_(context)
- data class AppWhitelistItem(val title: String, val pckg: String) {
+ data class AppExceptionListItem(val title: String, val pckg: String) {
var isException = false
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
val view = LayoutInflater.from(parent.context)
- .inflate(R.layout.fragment_app_whitelist_list_item, parent, false)
+ .inflate(R.layout.fragment_app_exceptions_list_item, parent, false)
return ViewHolder(view)
}
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
val item = values[position]
- val context = holder.appIcon.context
holder.appTitle.text = item.title
+ holder.appPackage.text = item.pckg
holder.appIcon.setImageDrawable(holder.appIcon.context.packageManager.getApplicationIcon(item.pckg))
- holder.btnSetWhitelisted.setOnCheckedChangeListener { button, b ->
+ holder.btnToggleExceptionState.setOnCheckedChangeListener { _, b ->
item.isException = b
prefs.edit().grayscaleExceptions().put(
prefs.grayscaleExceptions().get().let {
@@ -39,14 +39,15 @@ open class AppExceptionsListAdapter(context: Context) : RecyclerView.Adapter = ArrayList()
+ val appList: MutableList = ArrayList()
apps?.iterator()?.forEach {
appList.add(
- AppExceptionsListAdapter.AppWhitelistItem(
+ AppExceptionsListAdapter.AppExceptionListItem(
it.loadLabel(pm) as String,
it.packageName
)
@@ -43,7 +43,7 @@ open class AppExceptionsListFragment : Fragment() {
}
@UiThread
- open fun initAdapter(appList: List) {
+ open fun initAdapter(appList: List) {
if (!this::list.isInitialized) return
with(list) {
diff --git a/app/src/main/java/com/flx_apps/digitaldetox/DetoxAccessibilityService.kt b/app/src/main/java/com/flx_apps/digitaldetox/DetoxAccessibilityService.kt
index 4405121..4e0b35a 100644
--- a/app/src/main/java/com/flx_apps/digitaldetox/DetoxAccessibilityService.kt
+++ b/app/src/main/java/com/flx_apps/digitaldetox/DetoxAccessibilityService.kt
@@ -2,8 +2,11 @@ package com.flx_apps.digitaldetox
import android.accessibilityservice.AccessibilityService
import android.app.NotificationManager
+import android.content.Context
import android.view.KeyEvent
+import android.view.WindowManager
import android.view.accessibility.AccessibilityEvent
+import android.view.inputmethod.InputMethodManager
import org.androidannotations.annotations.EService
import org.androidannotations.annotations.SystemService
import org.androidannotations.annotations.sharedpreferences.Pref
@@ -22,36 +25,58 @@ open class DetoxAccessibilityService : AccessibilityService() {
@SystemService
lateinit var notificationManager: NotificationManager
-
private var isGrayscale = false
private var lastPackage = ""
private var isPausing = false
+ private var ignoredEventClasses = mutableSetOf(
+ "android.inputmethodservice.SoftInputWindow",
+ "com.android.systemui.volume"
+ )
+ private var ignoredPackages = mutableSetOf()
+
+ override fun onCreate() {
+ super.onCreate()
+
+ // add all known keyboard packages to list of apps where we will not interfere with grayscale / color settings
+ (getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager).enabledInputMethodList.forEach {
+ log(it.packageName)
+ ignoredPackages.add(it.packageName)
+ }
+ }
override fun onAccessibilityEvent(accessibilityEvent: AccessibilityEvent) {
+// log("event=$accessibilityEvent")
+ log("package=${accessibilityEvent.packageName}, class=${accessibilityEvent.className}, event=${accessibilityEvent.eventType}")
+
val now = System.currentTimeMillis()
isPausing = now < prefs.pauseUntil().get()
+ // TYPE_ASSIST_READING_CONTEXT happens when the home button is long-pressed
if (accessibilityEvent.eventType == AccessibilityEvent.TYPE_ASSIST_READING_CONTEXT) {
isPausing = DetoxUtil.togglePause(baseContext)
isGrayscale = !isPausing
}
- val exceptions = setOf(
- "android.inputmethodservice.SoftInputWindow",
- "com.android.systemui.volume.VolumeDialogImpl\$CustomDialog"
- )
- if (isPausing || accessibilityEvent.packageName == lastPackage || accessibilityEvent.text.isNullOrEmpty() || accessibilityEvent.contentChangeTypes != AccessibilityEvent.CONTENT_CHANGE_TYPE_UNDEFINED || exceptions.contains(
- accessibilityEvent.className
- )) return
+ // decide whether we want to handle this event or not
+ var skipEvent = isPausing
+ || ignoredPackages.contains(accessibilityEvent.packageName)
+ || accessibilityEvent.packageName == lastPackage
+ || accessibilityEvent.text.isNullOrEmpty()
+ || accessibilityEvent.contentChangeTypes != AccessibilityEvent.CONTENT_CHANGE_TYPE_UNDEFINED
+ ignoredEventClasses.forEach {
+ skipEvent = skipEvent || accessibilityEvent.className.contains(it)
+ }
+ if (skipEvent) { log("skip..."); return }
+
lastPackage = accessibilityEvent.packageName.toString()
- log(accessibilityEvent.toString())
+ // forcefully enable DoNotDisturb
DetoxUtil.setZenMode(applicationContext, true)
- val grayscale = prefs.grayscaleEnabled().get() && !prefs.grayscaleExceptions().get().contains(
- accessibilityEvent.packageName
- )
- if (grayscale != isGrayscale) {
+ // decide whether we want to grayscale or color the screen
+ val grayscale = prefs.grayscaleEnabled().get()
+ && !prefs.grayscaleExceptions().get().contains(accessibilityEvent.packageName)
+ if (grayscale != isGrayscale) { // wantedState != currentState
DetoxUtil.setGrayscale(applicationContext, grayscale)
isGrayscale = grayscale
}
@@ -59,6 +84,7 @@ open class DetoxAccessibilityService : AccessibilityService() {
override fun onKeyEvent(event: KeyEvent?): Boolean {
// TODO: implement pause feature here?
+ log("onKeyEvent=$event")
return super.onKeyEvent(event)
}
diff --git a/app/src/main/java/com/flx_apps/digitaldetox/DetoxUtil.kt b/app/src/main/java/com/flx_apps/digitaldetox/DetoxUtil.kt
index 4769f57..72670cf 100644
--- a/app/src/main/java/com/flx_apps/digitaldetox/DetoxUtil.kt
+++ b/app/src/main/java/com/flx_apps/digitaldetox/DetoxUtil.kt
@@ -57,7 +57,7 @@ object DetoxUtil {
DISPLAY_DALTONIZER,
if (grayscale) 0 else -1
)
- return result1 && result2;
+ return result1 && result2
}
@JvmStatic
@@ -106,12 +106,42 @@ object DetoxUtil {
): Boolean {
val now = System.currentTimeMillis()
val prefs = Prefs_(context)
- val isPausing = !(now < prefs.pauseUntil().get()) // new pause state: inversion of "are we currently pausing?"
+ var isPausing = (now < prefs.pauseUntil().get())
+ if (!isPausing && now < prefs.nextPauseAllowedAt().get()) {
+ // we are currently not in a pause, and a pause is not allowed right now either
+ Toast.makeText(
+ context,
+ context.getString(
+ R.string.app_quickSettingsTile_noPause,
+ TimeUnit.MILLISECONDS.toMinutes(prefs.nextPauseAllowedAt().get() - now) + 1
+ ),
+ Toast.LENGTH_SHORT
+ ).show()
+ return false
+ }
+
+ isPausing = !isPausing // new pause state: inversion of "are we currently pausing?"
prefs.edit().pauseUntil().put(if (isPausing) now + TimeUnit.MINUTES.toMillis(prefs.pauseDuration().get().toLong()) else -1).apply()
setGrayscale(context, !isPausing)
setZenMode(context, !isPausing)
if (isPausing) {
- Toast.makeText(context, context.getString(R.string.app_quickSettingsTile_paused, prefs.pauseDuration().get()), Toast.LENGTH_SHORT).show()
+ // a pause was made, let's show a hint to the user
+ Toast.makeText(
+ context,
+ context.getString(
+ R.string.app_quickSettingsTile_paused,
+ prefs.pauseDuration().get()
+ ),
+ Toast.LENGTH_SHORT
+ ).show()
+ prefs.edit().nextPauseAllowedAt()
+ .put(prefs.pauseUntil().get() + TimeUnit.MINUTES.toMillis(prefs.timeBetweenPauses().get().toLong()))
+ .apply()
+ } else {
+ // a pause was interrupted
+ prefs.edit().nextPauseAllowedAt()
+ .put(now + TimeUnit.MINUTES.toMillis(prefs.timeBetweenPauses().get().toLong()))
+ .apply()
}
return isPausing
}
diff --git a/app/src/main/java/com/flx_apps/digitaldetox/HomeFragment.kt b/app/src/main/java/com/flx_apps/digitaldetox/HomeFragment.kt
index 9f2aa6c..635f074 100644
--- a/app/src/main/java/com/flx_apps/digitaldetox/HomeFragment.kt
+++ b/app/src/main/java/com/flx_apps/digitaldetox/HomeFragment.kt
@@ -6,6 +6,7 @@ import android.content.Intent
import android.content.pm.PackageManager
import android.os.Build
import android.provider.Settings
+import android.widget.Button
import android.widget.NumberPicker
import androidx.core.content.ContextCompat
import androidx.fragment.app.Fragment
@@ -43,7 +44,7 @@ open class HomeFragment : Fragment() {
return
}
- setDetoxIsActive(prefs.isRunning().get())
+ setDetoxIsActive(prefs.isRunning.get())
}
@AfterViews
@@ -88,7 +89,7 @@ open class HomeFragment : Fragment() {
}
btnToggleGrayscale.isChecked = prefs.grayscaleEnabled().get()
if (prefs.isRunning.get()) {
- DetoxUtil.setGrayscale(context!!, btnToggleGrayscale.isChecked)
+ DetoxUtil.setGrayscale(context!!, btnToggleGrayscale.isChecked && !prefs.grayscaleExceptions().get().contains(context!!.packageName))
}
}
@@ -99,18 +100,22 @@ open class HomeFragment : Fragment() {
?.addToBackStack(javaClass.name)?.commit()
}
- @Click
- fun btnSetPauseDurationClicked() {
+ @Click(R.id.btnSetPauseDuration, R.id.btnSetTimeBetweenPauses)
+ fun btnConfigurePauseClicked(btn: Button) {
val numberPicker = NumberPicker(context).apply {
- minValue = 1
+ minValue = if (btn.id == R.id.btnSetPauseDuration) 1 else 0
maxValue = 60
- value = prefs.pauseDuration().get()
+ value = if (btn.id == R.id.btnSetPauseDuration) prefs.pauseDuration().get() else prefs.timeBetweenPauses().get()
}
MaterialAlertDialogBuilder(context!!).apply {
- setTitle(R.string.home_pauseButton_setDuration)
+ setTitle(btn.text)
setView(numberPicker)
setPositiveButton(R.string.action_save) { _, _ ->
- prefs.edit().pauseDuration().put(numberPicker.value).apply()
+ val editorField = when (btn.id) {
+ R.id.btnSetPauseDuration -> prefs.edit().pauseDuration()
+ else -> prefs.edit().timeBetweenPauses()
+ }
+ editorField.put(numberPicker.value).apply()
}
setNegativeButton(R.string.action_cancel, null)
}.show()
diff --git a/app/src/main/java/com/flx_apps/digitaldetox/MainActivity.kt b/app/src/main/java/com/flx_apps/digitaldetox/MainActivity.kt
index 7500d2b..5e0ac89 100644
--- a/app/src/main/java/com/flx_apps/digitaldetox/MainActivity.kt
+++ b/app/src/main/java/com/flx_apps/digitaldetox/MainActivity.kt
@@ -2,10 +2,14 @@ package com.flx_apps.digitaldetox
import android.os.Bundle
import android.view.Menu
+import android.view.MenuItem
import androidx.appcompat.app.AppCompatActivity
import androidx.appcompat.widget.Toolbar
import androidx.drawerlayout.widget.DrawerLayout
-import androidx.navigation.findNavController
+import androidx.fragment.app.Fragment
+import androidx.navigation.*
+import androidx.navigation.fragment.FragmentNavigator
+import androidx.navigation.fragment.FragmentNavigatorDestinationBuilder
import androidx.navigation.ui.AppBarConfiguration
import androidx.navigation.ui.navigateUp
import androidx.navigation.ui.setupActionBarWithNavController
@@ -31,9 +35,11 @@ class MainActivity : AppCompatActivity() {
// menu should be considered as top level destinations.
appBarConfiguration = AppBarConfiguration(
setOf(
- R.id.nav_home
+ R.id.nav_home,
+ R.id.nav_about
), drawerLayout
)
+
setupActionBarWithNavController(navController, appBarConfiguration)
navView.setupWithNavController(navController)
}
diff --git a/app/src/main/java/com/flx_apps/digitaldetox/Prefs.kt b/app/src/main/java/com/flx_apps/digitaldetox/Prefs.kt
index 0b33ef3..4c0b8d1 100644
--- a/app/src/main/java/com/flx_apps/digitaldetox/Prefs.kt
+++ b/app/src/main/java/com/flx_apps/digitaldetox/Prefs.kt
@@ -25,4 +25,10 @@ interface Prefs {
@DefaultInt(1)
fun pauseDuration(): Int
+
+ @DefaultLong(-1)
+ fun nextPauseAllowedAt(): Long
+
+ @DefaultInt(5)
+ fun timeBetweenPauses(): Int
}
\ No newline at end of file
diff --git a/app/src/main/res/drawable/ic_coffee.xml b/app/src/main/res/drawable/ic_coffee.xml
new file mode 100644
index 0000000..1e7fe77
--- /dev/null
+++ b/app/src/main/res/drawable/ic_coffee.xml
@@ -0,0 +1,9 @@
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/drawable/ic_info.xml b/app/src/main/res/drawable/ic_info.xml
new file mode 100644
index 0000000..17255b7
--- /dev/null
+++ b/app/src/main/res/drawable/ic_info.xml
@@ -0,0 +1,10 @@
+
+
+
diff --git a/app/src/main/res/drawable/ic_patron.xml b/app/src/main/res/drawable/ic_patron.xml
new file mode 100644
index 0000000..903bae8
--- /dev/null
+++ b/app/src/main/res/drawable/ic_patron.xml
@@ -0,0 +1,10 @@
+
+
+
diff --git a/app/src/main/res/layout/fragment_app_exceptions.xml b/app/src/main/res/layout/fragment_app_exceptions.xml
index b65d83d..924f52d 100644
--- a/app/src/main/res/layout/fragment_app_exceptions.xml
+++ b/app/src/main/res/layout/fragment_app_exceptions.xml
@@ -10,11 +10,11 @@
android:name="com.flx_apps.digitaldetox.AppItemFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
- android:layout_marginLeft="16dp"
- android:layout_marginRight="16dp"
+ android:paddingLeft="16dp"
+ android:paddingRight="16dp"
app:layoutManager="LinearLayoutManager"
tools:context=".AppExceptionsListFragment"
- tools:listitem="@layout/fragment_app_whitelist_list_item" />
+ tools:listitem="@layout/fragment_app_exceptions_list_item" />
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/fragment_app_whitelist_list_item.xml b/app/src/main/res/layout/fragment_app_whitelist_list_item.xml
deleted file mode 100644
index 25959d2..0000000
--- a/app/src/main/res/layout/fragment_app_whitelist_list_item.xml
+++ /dev/null
@@ -1,29 +0,0 @@
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/app/src/main/res/layout/fragment_home.xml b/app/src/main/res/layout/fragment_home.xml
index 303bab2..f9a55e4 100644
--- a/app/src/main/res/layout/fragment_home.xml
+++ b/app/src/main/res/layout/fragment_home.xml
@@ -100,6 +100,13 @@
android:layout_height="wrap_content"
android:text="@string/home.pauseButton.setDuration" />
+
+
diff --git a/app/src/main/res/layout/fragment_home_card.xml b/app/src/main/res/layout/fragment_home_card.xml
index 654b719..2429074 100644
--- a/app/src/main/res/layout/fragment_home_card.xml
+++ b/app/src/main/res/layout/fragment_home_card.xml
@@ -42,7 +42,7 @@
android:id="@+id/content"
android:layout_width="match_parent"
android:layout_height="wrap_content"
- android:orientation="horizontal">
+ android:orientation="vertical">
\ No newline at end of file
diff --git a/app/src/main/res/layout/fragment_no_permissions.xml b/app/src/main/res/layout/fragment_no_permissions.xml
index f2cadb0..b5699e6 100644
--- a/app/src/main/res/layout/fragment_no_permissions.xml
+++ b/app/src/main/res/layout/fragment_no_permissions.xml
@@ -1,17 +1,36 @@
-
+
+
+ android:text="@string/noPermissions.text"
+ android:textAppearance="@style/TextAppearance.AppCompat.Medium"
+ app:layout_constraintBottom_toBottomOf="parent"
+ app:layout_constraintEnd_toEndOf="parent"
+ app:layout_constraintStart_toStartOf="parent"
+ app:layout_constraintTop_toBottomOf="@+id/appCompatImageView" />
-
\ No newline at end of file
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/nav_header_main.xml b/app/src/main/res/layout/nav_header_main.xml
index 44cb0d3..6b40df8 100644
--- a/app/src/main/res/layout/nav_header_main.xml
+++ b/app/src/main/res/layout/nav_header_main.xml
@@ -23,12 +23,12 @@
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingTop="@dimen/nav_header_vertical_spacing"
- android:text="@string/app.name"
+ android:text="@string/app.name_"
android:textAppearance="@style/TextAppearance.AppCompat.Body1" />
+ android:text="@string/app.subtitle" />
\ No newline at end of file
diff --git a/app/src/main/res/menu/activity_main_drawer.xml b/app/src/main/res/menu/activity_main_drawer.xml
index 9f9d9f1..d584d3c 100644
--- a/app/src/main/res/menu/activity_main_drawer.xml
+++ b/app/src/main/res/menu/activity_main_drawer.xml
@@ -7,5 +7,8 @@
+
\ No newline at end of file
diff --git a/app/src/main/res/navigation/mobile_navigation.xml b/app/src/main/res/navigation/mobile_navigation.xml
index 8128060..edb84a9 100644
--- a/app/src/main/res/navigation/mobile_navigation.xml
+++ b/app/src/main/res/navigation/mobile_navigation.xml
@@ -10,4 +10,9 @@
android:name="com.flx_apps.digitaldetox.HomeFragment_"
android:label="@string/navigation.home"
tools:layout="@layout/fragment_home" />
+
+
\ No newline at end of file
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index caeeaa7..4108c0f 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -1,9 +1,10 @@
- DetoxDroid
- detoxdroid.flx-apps.com
+ DetoxDroid
+ detoxdroid.flx-apps.com
Pause DetoxDroid
DetoxDroid has been paused for %d minutes.
+ Take another pause in %d minutes.
DetoxDroid Accessibility Service
This services disables and enables grayscale mode depending on which app is currently open. It also reacts to long-pressing the home button and manages detoxing mode pauses.
@@ -18,6 +19,7 @@
Click to (de-)activate
Home
+ About
Donate
Welcome to DetoxDroid!
@@ -31,20 +33,32 @@
Automatic Grayscale
Color up by coloring down your phone
Strip away all the neuron-stimulating colors (hint: you can add your camera and gallery app to the exceptions).
+ Gray
+ Colors
+ Ignored
Pause Button
Take a break from taking a break
- DetoxDroid can be paused for a defined period of time, for example if you want to take a quick look on a photo somebody sent you. It will automatically come back into life, once the pause is over. A pause can be made by pressing the quick settings tile or by long-pressing the home button.
+ DetoxDroid can be paused for a defined period of time, for example if you want to take a quick look on a photo somebody sent you. It will automatically come back into life, once the pause is over. A pause can be made by pressing the quick settings tile or by long-pressing the home button. You can also set a minimum time between the pauses to prevent yourself from tricking yourself by pausing all the time.
Set Pause Duration
+ Set Time Between Pauses
- Donate
- DetoxDroid is open-source and without ads. If you find the app useful, please consider leaving a donation to support the development of the app.
+ Buy me a coffee
+ https://ko-fi.com/flxapps
+ Become a patron
+ https://liberapay.com/DetoxDroid/donate
+ Contact me
+ mailto:detoxdroid@flx-apps.com
+ Contribute on GitHub
+ https://github.com/flxapps/DetoxDroid
- You need to grant this app elevated privileges from your computer.\n\n
- Please visit https://detoxdroid.flx-apps.com/ to find out how.
+ You need to grant this app elevated privileges from your computer.
+ \n\nDon\'t worry, it takes you only a couple of minutes: Please visit https://detoxdroid.flx-apps.com/ to find out how.
+
+ Hello blank fragment
\ No newline at end of file
diff --git a/build.gradle b/build.gradle
index bbbf0e6..3a2c356 100644
--- a/build.gradle
+++ b/build.gradle
@@ -18,6 +18,7 @@ allprojects {
repositories {
google()
jcenter()
+ maven { url "https://jitpack.io" }
}
}
diff --git a/fastlane/metadata/android/en-US/changelogs/10000.txt b/fastlane/metadata/android/en-US/changelogs/10000.txt
new file mode 100644
index 0000000..03081f0
--- /dev/null
+++ b/fastlane/metadata/android/en-US/changelogs/10000.txt
@@ -0,0 +1 @@
+Initial release
\ No newline at end of file
diff --git a/fastlane/metadata/android/en-US/changelogs/10001.txt b/fastlane/metadata/android/en-US/changelogs/10001.txt
new file mode 100644
index 0000000..1ba7c7b
--- /dev/null
+++ b/fastlane/metadata/android/en-US/changelogs/10001.txt
@@ -0,0 +1 @@
+Implemented "minimum time between pauses" feature
\ No newline at end of file
diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar
new file mode 100644
index 0000000..f6b961f
Binary files /dev/null and b/gradle/wrapper/gradle-wrapper.jar differ
diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties
new file mode 100644
index 0000000..b2137c0
--- /dev/null
+++ b/gradle/wrapper/gradle-wrapper.properties
@@ -0,0 +1,6 @@
+#Sun Nov 15 11:19:38 CET 2020
+distributionBase=GRADLE_USER_HOME
+distributionPath=wrapper/dists
+zipStoreBase=GRADLE_USER_HOME
+zipStorePath=wrapper/dists
+distributionUrl=https\://services.gradle.org/distributions/gradle-6.5-all.zip
diff --git a/gradlew b/gradlew
new file mode 100755
index 0000000..cccdd3d
--- /dev/null
+++ b/gradlew
@@ -0,0 +1,172 @@
+#!/usr/bin/env sh
+
+##############################################################################
+##
+## Gradle start up script for UN*X
+##
+##############################################################################
+
+# Attempt to set APP_HOME
+# Resolve links: $0 may be a link
+PRG="$0"
+# Need this for relative symlinks.
+while [ -h "$PRG" ] ; do
+ ls=`ls -ld "$PRG"`
+ link=`expr "$ls" : '.*-> \(.*\)$'`
+ if expr "$link" : '/.*' > /dev/null; then
+ PRG="$link"
+ else
+ PRG=`dirname "$PRG"`"/$link"
+ fi
+done
+SAVED="`pwd`"
+cd "`dirname \"$PRG\"`/" >/dev/null
+APP_HOME="`pwd -P`"
+cd "$SAVED" >/dev/null
+
+APP_NAME="Gradle"
+APP_BASE_NAME=`basename "$0"`
+
+# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+DEFAULT_JVM_OPTS=""
+
+# Use the maximum available, or set MAX_FD != -1 to use that value.
+MAX_FD="maximum"
+
+warn () {
+ echo "$*"
+}
+
+die () {
+ echo
+ echo "$*"
+ echo
+ exit 1
+}
+
+# OS specific support (must be 'true' or 'false').
+cygwin=false
+msys=false
+darwin=false
+nonstop=false
+case "`uname`" in
+ CYGWIN* )
+ cygwin=true
+ ;;
+ Darwin* )
+ darwin=true
+ ;;
+ MINGW* )
+ msys=true
+ ;;
+ NONSTOP* )
+ nonstop=true
+ ;;
+esac
+
+CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
+
+# Determine the Java command to use to start the JVM.
+if [ -n "$JAVA_HOME" ] ; then
+ if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
+ # IBM's JDK on AIX uses strange locations for the executables
+ JAVACMD="$JAVA_HOME/jre/sh/java"
+ else
+ JAVACMD="$JAVA_HOME/bin/java"
+ fi
+ if [ ! -x "$JAVACMD" ] ; then
+ die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+ fi
+else
+ JAVACMD="java"
+ which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+fi
+
+# Increase the maximum file descriptors if we can.
+if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
+ MAX_FD_LIMIT=`ulimit -H -n`
+ if [ $? -eq 0 ] ; then
+ if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
+ MAX_FD="$MAX_FD_LIMIT"
+ fi
+ ulimit -n $MAX_FD
+ if [ $? -ne 0 ] ; then
+ warn "Could not set maximum file descriptor limit: $MAX_FD"
+ fi
+ else
+ warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
+ fi
+fi
+
+# For Darwin, add options to specify how the application appears in the dock
+if $darwin; then
+ GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
+fi
+
+# For Cygwin, switch paths to Windows format before running java
+if $cygwin ; then
+ APP_HOME=`cygpath --path --mixed "$APP_HOME"`
+ CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
+ JAVACMD=`cygpath --unix "$JAVACMD"`
+
+ # We build the pattern for arguments to be converted via cygpath
+ ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
+ SEP=""
+ for dir in $ROOTDIRSRAW ; do
+ ROOTDIRS="$ROOTDIRS$SEP$dir"
+ SEP="|"
+ done
+ OURCYGPATTERN="(^($ROOTDIRS))"
+ # Add a user-defined pattern to the cygpath arguments
+ if [ "$GRADLE_CYGPATTERN" != "" ] ; then
+ OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
+ fi
+ # Now convert the arguments - kludge to limit ourselves to /bin/sh
+ i=0
+ for arg in "$@" ; do
+ CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
+ CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
+
+ if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
+ eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
+ else
+ eval `echo args$i`="\"$arg\""
+ fi
+ i=$((i+1))
+ done
+ case $i in
+ (0) set -- ;;
+ (1) set -- "$args0" ;;
+ (2) set -- "$args0" "$args1" ;;
+ (3) set -- "$args0" "$args1" "$args2" ;;
+ (4) set -- "$args0" "$args1" "$args2" "$args3" ;;
+ (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
+ (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
+ (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
+ (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
+ (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
+ esac
+fi
+
+# Escape application args
+save () {
+ for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
+ echo " "
+}
+APP_ARGS=$(save "$@")
+
+# Collect all arguments for the java command, following the shell quoting and substitution rules
+eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
+
+# by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong
+if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then
+ cd "$(dirname "$0")"
+fi
+
+exec "$JAVACMD" "$@"
diff --git a/gradlew.bat b/gradlew.bat
new file mode 100644
index 0000000..e95643d
--- /dev/null
+++ b/gradlew.bat
@@ -0,0 +1,84 @@
+@if "%DEBUG%" == "" @echo off
+@rem ##########################################################################
+@rem
+@rem Gradle startup script for Windows
+@rem
+@rem ##########################################################################
+
+@rem Set local scope for the variables with windows NT shell
+if "%OS%"=="Windows_NT" setlocal
+
+set DIRNAME=%~dp0
+if "%DIRNAME%" == "" set DIRNAME=.
+set APP_BASE_NAME=%~n0
+set APP_HOME=%DIRNAME%
+
+@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+set DEFAULT_JVM_OPTS=
+
+@rem Find java.exe
+if defined JAVA_HOME goto findJavaFromJavaHome
+
+set JAVA_EXE=java.exe
+%JAVA_EXE% -version >NUL 2>&1
+if "%ERRORLEVEL%" == "0" goto init
+
+echo.
+echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:findJavaFromJavaHome
+set JAVA_HOME=%JAVA_HOME:"=%
+set JAVA_EXE=%JAVA_HOME%/bin/java.exe
+
+if exist "%JAVA_EXE%" goto init
+
+echo.
+echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:init
+@rem Get command-line arguments, handling Windows variants
+
+if not "%OS%" == "Windows_NT" goto win9xME_args
+
+:win9xME_args
+@rem Slurp the command line arguments.
+set CMD_LINE_ARGS=
+set _SKIP=2
+
+:win9xME_args_slurp
+if "x%~1" == "x" goto execute
+
+set CMD_LINE_ARGS=%*
+
+:execute
+@rem Setup the command line
+
+set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
+
+@rem Execute Gradle
+"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
+
+:end
+@rem End local scope for the variables with windows NT shell
+if "%ERRORLEVEL%"=="0" goto mainEnd
+
+:fail
+rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
+rem the _cmd.exe /c_ return code!
+if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
+exit /b 1
+
+:mainEnd
+if "%OS%"=="Windows_NT" endlocal
+
+:omega
diff --git a/install/README.txt b/install/README.txt
new file mode 100644
index 0000000..913a353
--- /dev/null
+++ b/install/README.txt
@@ -0,0 +1,42 @@
+===========================================================
+
+ DETOXDROID INSTALLATION INSTRUCTIONS
+
+===========================================================
+
+BEFORE RUNNING THE INSTALLATION SCRIPT:
+
+If you haven't already, you need to enable USB debugging on
+your phone. In order to do this, follow these steps:
+
+1. Go to Android Settings → System → About Phone
+
+2. Look for the build number option and touch it
+ multiple times. A message should appear saying that
+ developer mode has been enabled.
+
+3. Go to Android Settings → System → Developer Options.
+ Look for USB debugging and enable it.
+
+4. Connect your device with your computer.
+
+The following video will also show you these steps:
+https://www.youtube.com/watch?v=0usgePpr8_Y
+
+===========================================================
+
+RUNNING THE INSTALLATION SCRIPT:
+
+ * If you are on Windows, you should be able to run
+ "install_windows.bat" by simply double-clicking the file.
+
+ * If you are on Mac/Linux, you should be able to run the
+ installation script from the console using
+ "bash install_.sh"
+
+===========================================================
+
+If you do not trust the installation scripts, you can
+always follow the manual installation steps on:
+
+https://github.com/flxapps/DetoxDroid/wiki/Manual-Installation
diff --git a/releases/1.0.0/release/app-release.apk b/releases/1.0.0/release/app-release.apk
new file mode 100644
index 0000000..3771b20
Binary files /dev/null and b/releases/1.0.0/release/app-release.apk differ
diff --git a/releases/1.0.0/release/output-metadata.json b/releases/1.0.0/release/output-metadata.json
new file mode 100644
index 0000000..0818e2f
--- /dev/null
+++ b/releases/1.0.0/release/output-metadata.json
@@ -0,0 +1,18 @@
+{
+ "version": 2,
+ "artifactType": {
+ "type": "APK",
+ "kind": "Directory"
+ },
+ "applicationId": "com.flx_apps.digitaldetox",
+ "variantName": "processReleaseResources",
+ "elements": [
+ {
+ "type": "SINGLE",
+ "filters": [],
+ "versionCode": 10000,
+ "versionName": "1.0.0",
+ "outputFile": "app-release.apk"
+ }
+ ]
+}
\ No newline at end of file
diff --git a/releases/1.0.1/release/app-release.apk b/releases/1.0.1/release/app-release.apk
new file mode 100644
index 0000000..fea389a
Binary files /dev/null and b/releases/1.0.1/release/app-release.apk differ
diff --git a/releases/1.0.1/release/output-metadata.json b/releases/1.0.1/release/output-metadata.json
new file mode 100644
index 0000000..cf51aab
--- /dev/null
+++ b/releases/1.0.1/release/output-metadata.json
@@ -0,0 +1,18 @@
+{
+ "version": 2,
+ "artifactType": {
+ "type": "APK",
+ "kind": "Directory"
+ },
+ "applicationId": "com.flx_apps.digitaldetox",
+ "variantName": "processReleaseResources",
+ "elements": [
+ {
+ "type": "SINGLE",
+ "filters": [],
+ "versionCode": 10001,
+ "versionName": "1.0.1",
+ "outputFile": "app-release.apk"
+ }
+ ]
+}
\ No newline at end of file