0

我正在开发一个健康应用程序,它可以让你的手机在给定的一段时间内(例如 30 分钟、1 小时、1.5 小时)关闭

在这种状态下,用户只能看到一个有剩余时间的屏幕,而不能

  • 访问 QS 瓷砖
  • 访问音量面板
  • 退出活动

类似于 Oneplus Zen 模式的东西

我为这样做而想到的事情

  • 杀死 SystemUI 进程。(这样做很可能会处理 QS 和音量面板,可能需​​要 root 用户?SystemUI 也会自动重启,非常顽固)

  • 使应用程序成为动态启动器?(从技术上讲,您无法离开启动器并在重新启动时返回它)

我怎样才能解决这个问题?有任何想法吗?

4

1 回答 1

1

使应用程序成为手机的默认启动器是您想要实现的更实用的解决方案。我之前在 Flutter 应用程序中完成了此操作,该应用程序将安装在 kiosk 设备上以获取客户的订单,并且运行良好。让它工作有点棘手,还有很多事情要做。这是我当时做的事情的清单:

  1. 使用FLAG_SHOW_WHEN_LOCKED窗口标志绕过锁定屏幕。

  2. 在里面onResume添加FLAG_FULLSCREEN标志来隐藏状态栏。

  3. 通过将类别添加到 in 来制作您的MainActivity启动器。您还可以添加我使用的其他属性(如果您不知道它们应该做什么,请搜索它们)。LAUNCHERAndroidManifest.xml

    <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. 监听你的窗口焦点变化,MainActivity如果它失去焦点,把你的应用程序放在前面。

    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. 我还在检查我的应用程序是否是默认启动器。

    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. 您需要在 Flutter 和平台之间进行通信,MethodChannel以启用和禁用强制模式并获取应用程序的状态。

于 2021-10-10T10:02:04.130 回答