I am working on an well-being app that shuts your phone up for a given period of time (eg. 30min, 1hr, 1.5hr)
In this state user can only see a screen with remaining time on it and cannot
something similar to Oneplus Zen mode
things i have thought of for doing this
Killing the SystemUI process.(by doing so the QS and volume panel would be dealt with most probably, maybe need root for that tho? also SystemUI automatically restarts itself, quite stubborn)
Making app a launcher Dynamically?(technically you can't navigate out of a launcher and on reboot you come back to it)
how can I get around accomplishing this? any ideas?
Making application the default launcher of the phone is more practical solution to what you're trying to achieve. I've done this previously in a Flutter application which was going to be installed on kiosk devices to get orders from customers and it worked perfectly. It's a bit tricky to make it work and there's lots of things to do. Here is a list of things I did back then:
Use FLAG_SHOW_WHEN_LOCKED
flag to the window to bypass the lock screen.
Inside of onResume
add FLAG_FULLSCREEN
flags to hide the status bar.
Make your MainActivity
launcher by adding LAUNCHER
category to in AndroidManifest.xml
. Also you can add other attributes I used (Search for them if you don't know what are they supposed to do).
<activity
android:name=".MainActivity"
android:configChanges="orientation|keyboardHidden|keyboard|screenSize|smallestScreenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode"
android:excludeFromRecents="true"
android:hardwareAccelerated="true"
android:launchMode="singleInstance"
android:showOnLockScreen="true"
android:showWhenLocked="true"
android:theme="@style/LaunchTheme"
android:turnScreenOn="true"
android:windowSoftInputMode="adjustResize">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
<category android:name="android.intent.category.HOME" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>
Listen for window focus changes in your MainActivity
and bring your application to front if it lost the focus.
private fun moveToFront() {
val closeDialog = Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS)
sendBroadcast(closeDialog)
(activity.applicationContext.getSystemService(Context.ACTIVITY_SERVICE) as ActivityManager)
.moveTaskToFront(activity.taskId, ActivityManager.MOVE_TASK_WITH_HOME)
window.setFlags(
WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN);
}
override fun onWindowFocusChanged(hasFocus: Boolean) {
super.onWindowFocusChanged(hasFocus)
if (!hasFocus) {
moveToFront()
}
}
I was also checking if my application is the default launcher.
private fun isAppDefault(): Boolean {
val intent = Intent(Intent.ACTION_MAIN)
intent.addCategory(Intent.CATEGORY_HOME)
val res: ResolveInfo = packageManager.resolveActivity(intent, 0)
return res.activityInfo != null && (packageName
== res.activityInfo.packageName)
}
And you're gonna need to communicate between Flutter and the platform using MethodChannel
to enable and disable force mode and get the state of the application.