shutting down android functionality like qs tiles, volume panel and navigation's

97 Views Asked by At

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

  • Access QS tiles
  • Access Volume panel
  • Navigate out of the Activity

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?

1

There are 1 best solutions below

2
On BEST ANSWER

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:

  1. Use FLAG_SHOW_WHEN_LOCKED flag to the window to bypass the lock screen.

  2. Inside of onResume add FLAG_FULLSCREEN flags to hide the status bar.

  3. 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>
    
  4. 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()
      }
    }
    
  5. 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)
    }
    
  6. 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.