Skip to content
This repository was archived by the owner on Feb 13, 2024. It is now read-only.
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 16 additions & 0 deletions app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,9 @@ You should have received a copy of the GNU General Public License along with Sim
<uses-permission android:name="com.android.launcher.permission.INSTALL_SHORTCUT" />
<uses-permission android:name="android.permission.READ_CALENDAR" />
<uses-permission android:name="android.permission.WRITE_CALENDAR" />
<uses-permission android:name="android.permission.RECEIVE_USER_PRESENT" />
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
<supports-screens
android:anyDensity="true"
android:largeScreens="true"
Expand Down Expand Up @@ -195,6 +198,19 @@ You should have received a copy of the GNU General Public License along with Sim
/>
</receiver>

<!-- In support of 'habit mode' that launches SimpleTask when the device is unlocked-->
<receiver android:name=".AppLauncherReceiver" android:exported="true">
<intent-filter>
<action android:name="android.intent.action.USER_PRESENT" />
</intent-filter>
</receiver>

<!-- Service to improve reliability of 'habit mode' -->
<service
android:name=".AppLauncherService"
android:enabled="true"
android:exported="false" />

<service
android:name=".AppWidgetService"
android:exported="false"
Expand Down
16 changes: 16 additions & 0 deletions app/src/main/java/nl/mpcjanssen/simpletask/AppLauncherReceiver.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package nl.mpcjanssen.simpletask

import android.content.BroadcastReceiver
import android.content.Context
import android.content.Intent

class AppLauncherReceiver : BroadcastReceiver() {

override fun onReceive(context: Context, intent: Intent) {
if (intent.action == Intent.ACTION_USER_PRESENT) {
val simpleTaskActivity = Intent(context, Simpletask::class.java)
simpleTaskActivity.flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_REORDER_TO_FRONT
context.startActivity(simpleTaskActivity)
}
}
}
55 changes: 55 additions & 0 deletions app/src/main/java/nl/mpcjanssen/simpletask/AppLauncherService.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
package nl.mpcjanssen.simpletask

import android.app.NotificationChannel
import android.app.NotificationManager
import android.app.Service
import android.content.Intent
import android.content.IntentFilter
import android.os.Build
import android.os.IBinder
import androidx.core.app.NotificationCompat

class AppLauncherService : Service() {

private val appLauncherReceiver = AppLauncherReceiver()

override fun onBind(intent: Intent): IBinder? {
return null
}

override fun onCreate() {
super.onCreate()

// Create a notification channel for the foreground service
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
val channel = NotificationChannel(
"simpletask_launcher_service",
"SimpleTask Launcher Service",
NotificationManager.IMPORTANCE_LOW
)
val notificationManager = getSystemService(NotificationManager::class.java)
notificationManager.createNotificationChannel(channel)
}

// Create a notification for the foreground service using NotificationCompat.Builder()
val notification = NotificationCompat.Builder(this, "simpletask_launcher_service")
.setContentTitle("SimpleTask Habit Mode")
.setContentText("Waiting for Screen Unlock")
.setSmallIcon(R.drawable.ic_done_white_24dp)
.build()

// Start the foreground service with the notification
startForeground(1, notification)

// Register the BroadcastReceiver for the ACTION_USER_PRESENT broadcast
val intentFilter = IntentFilter(Intent.ACTION_USER_PRESENT)
registerReceiver(appLauncherReceiver, intentFilter)
}

override fun onDestroy() {
// Unregister the BroadcastReceiver when the service is destroyed
unregisterReceiver(appLauncherReceiver)

super.onDestroy()
}
}
21 changes: 21 additions & 0 deletions app/src/main/java/nl/mpcjanssen/simpletask/Preferences.kt
Original file line number Diff line number Diff line change
Expand Up @@ -30,9 +30,11 @@ package nl.mpcjanssen.simpletask
import android.Manifest
import android.content.*
import android.content.pm.PackageManager
import android.net.Uri
import android.os.Build
import android.os.Bundle
import android.preference.*
import android.provider.Settings
import android.text.TextUtils
import androidx.core.app.ActivityCompat
import androidx.core.content.ContextCompat
Expand Down Expand Up @@ -89,6 +91,7 @@ class Preferences : ThemedPreferenceActivity(), SharedPreferences.OnSharedPrefer
val broadcastIntent = Intent(Constants.BROADCAST_MAIN_FONTSIZE_CHANGED)
localBroadcastManager.sendBroadcast(broadcastIntent)
}
getString(R.string.habit_mode_pref_key) -> requestDrawOverlaysPermissionAndStartService()
}
}

Expand All @@ -111,6 +114,24 @@ class Preferences : ThemedPreferenceActivity(), SharedPreferences.OnSharedPrefer
}
}

private fun requestDrawOverlaysPermissionAndStartService() {
Log.i(TAG, "requestDrawOverlaysPermissionAndStartService")
if (TodoApplication.config.enableHabitMode) {
// test to see if we already have permission
val canDrawOverlays = Settings.canDrawOverlays(this)
if (!canDrawOverlays) {

val intent = Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION)
intent.data = Uri.parse("package:${packageName}")
startActivityForResult(intent, 0)
}

startService(Intent(this, AppLauncherService::class.java))
} else {
stopService(Intent(this, AppLauncherService::class.java))
}
}

override fun onResume() {
super.onResume()
// Set up a listener whenever a key changes
Expand Down
12 changes: 11 additions & 1 deletion app/src/main/java/nl/mpcjanssen/simpletask/Simpletask.kt
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@

package nl.mpcjanssen.simpletask

import android.annotation.SuppressLint
import android.annotation.SuppressLint
import android.app.DatePickerDialog
import android.app.PendingIntent
import android.app.SearchManager
Expand Down Expand Up @@ -42,6 +42,7 @@ import androidx.annotation.RequiresApi
import androidx.core.content.FileProvider
import androidx.core.app.NotificationCompat
import androidx.core.app.NotificationManagerCompat
import android.provider.Settings

import hirondelle.date4j.DateTime
import nl.mpcjanssen.simpletask.adapters.DrawerAdapter
Expand Down Expand Up @@ -80,9 +81,18 @@ class Simpletask : ThemedNoActionBarActivity() {

private val uiHandler = UiHandler()



public override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
Log.i(TAG, "onCreate")

// If Habit Mode is enabled, we start the foreground service that
// catches the screen unlock events reliably.
if(TodoApplication.config.enableHabitMode) {
startService(Intent(this, AppLauncherService::class.java))
}

m_savedInstanceState = savedInstanceState
val intentFilter = IntentFilter()
intentFilter.addAction(Constants.BROADCAST_ACTION_LOGOUT)
Expand Down
2 changes: 2 additions & 0 deletions app/src/main/java/nl/mpcjanssen/simpletask/util/Config.kt
Original file line number Diff line number Diff line change
Expand Up @@ -177,6 +177,8 @@ class Config(app: TodoApplication) : Preferences(app) {

val showConfirmationDialogs by BooleanPreference(R.string.ui_show_confirmation_dialogs, true)

val enableHabitMode by BooleanPreference(R.string.habit_mode_pref_key, false)

val defaultSorts: Array<String>
get() = TodoApplication.app.resources.getStringArray(R.array.sortKeys)

Expand Down
1 change: 1 addition & 0 deletions app/src/main/res/values/donottranslate.xml
Original file line number Diff line number Diff line change
Expand Up @@ -184,4 +184,5 @@ You should have received a copy of the GNU General Public License along with Tod
<string name="query_store" translatable="false">query_store</string>
<string name="force_english" translatable="false">force_english</string>
<string name="idle_before_save" translatable="false">idle_before_save</string>
<string name="habit_mode_pref_key" translatable="false">habit_mode_enable</string>
</resources>
2 changes: 2 additions & 0 deletions app/src/main/res/values/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -405,6 +405,8 @@ You should have received a copy of the GNU General Public License along with Tod
<string name="lua_config_share">Share</string>
<string name="lua_open_config">Lua config</string>
<string name="use_uuid_title">Assign a UUID to each task</string>
<string name="habit_mode_pref_title">Enable Habit Mode (BETA)</string>
<string name="habit_mode_pref_summary">Habit Mode brings this app to the foreground every time the device is unlocked.</string>
<string name="task_drag_title">Drag tasks to reorder (BETA)</string>
<string name="nav_drawer_hint">Save the current filter\n
using the save button</string>
Expand Down
6 changes: 6 additions & 0 deletions app/src/main/res/xml/interface_preferences.xml
Original file line number Diff line number Diff line change
Expand Up @@ -63,4 +63,10 @@
android:key="@string/task_drag"
android:title="@string/task_drag_title"
/>
<CheckBoxPreference
android:defaultValue="false"
android:key="@string/habit_mode_pref_key"
android:summary="@string/habit_mode_pref_summary"
android:title="@string/habit_mode_pref_title"
/>
</PreferenceScreen>