繁体   English   中英

使应用服务在后台不可见

[英]Making app service work invisible in background

我有一个无限运行后台服务的应用程序,同时还隐藏了应用程序图标并将其隐藏在后台堆栈中,因此在运行时用户不会看到它:

       val componentName = ComponentName(this, FullscreenActivity::class.java)
       p.setComponentEnabledSetting(
           componentName,
           PackageManager.COMPONENT_ENABLED_STATE_DISABLED,
           PackageManager.DONT_KILL_APP
       )

这就是我从片段启动服务的方式:

parentFragment?.activity?.startService(
                    Intent(
                        requireParentFragment().requireActivity().applicationContext,
                        RescueService::class.java
                    ).addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
                )

它成功地从后台隐藏图标和应用程序并且服务继续运行,当我按下手机上的方形按钮以显示后台应用程序正在运行时,我没有看到我想要的应用程序,但是如果我点击“ X”按钮清除所有后台应用程序它也会杀死我的应用程序并且我的服务会死掉,即使应用程序没有像我提到的那样出现在那里。

任何想法是什么让服务在完成后死亡? 因为几天前我对我的应用程序进行了一些更改之前并没有发生这种情况..

我所做的更改之一是将我的Service变成LifecycleService因为我需要我的服务来观察需要LifecycleOwner的 livedata。这可能是我的服务在清除后台堆栈时死亡的原因吗?

欢迎所有建议!

EDIT1 - 这是我使用WorkManager执行语音录制的TestService 。我调用hideApp()从手机中隐藏图标并使应用程序在后台不可见:

class RecordingWork(
    context: Context,
    params: WorkerParameters
) : CoroutineWorker(context, params) {

    override val coroutineContext = Dispatchers.Main
    override suspend fun doWork(): Result {

        mSpeechRecognizer.startListening(mSpeechRecognizerIntent)
        return Result.success()
    }
}

private lateinit var mSpeechRecognizer: SpeechRecognizer
private val mSpeechRecognizerIntent = Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH)

class TestService : Service() {

    private lateinit var workManager: WorkManager

    override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
        Log.d("TestService", "onStartCommand called")
        hideApp()
        prepareVoiceRecording()
        workManager = WorkManager.getInstance(applicationContext)
        workManager.enqueue(OneTimeWorkRequestBuilder<RecordingWork>().build())

        return START_REDELIVER_INTENT
    }

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

    fun prepareVoiceRecording() {
        mSpeechRecognizer = SpeechRecognizer.createSpeechRecognizer(applicationContext)
        mSpeechRecognizerIntent.putExtra(
            RecognizerIntent.EXTRA_LANGUAGE_MODEL,
            RecognizerIntent.LANGUAGE_MODEL_FREE_FORM
        )
        mSpeechRecognizerIntent.putExtra(
            RecognizerIntent.EXTRA_LANGUAGE,
            Locale.getDefault()
        )
        mSpeechRecognizer.setRecognitionListener(
            object : RecognitionListener {

                @RequiresApi(Build.VERSION_CODES.M)
                override fun onError(i: Int) {
                    Log.d(TAG, "onErrorCalled error is $i")
                    if (i == SpeechRecognizer.ERROR_NETWORK || i == SpeechRecognizer.ERROR_SPEECH_TIMEOUT || i == SpeechRecognizer.ERROR_NO_MATCH) {
                        Log.d(TAG, "error triggered")
                        mSpeechRecognizer.destroy()
                        prepareVoiceRecording()
                        workManager.enqueue(OneTimeWorkRequestBuilder<RecordingWork>().build())

                    }
                }

                @RequiresApi(Build.VERSION_CODES.M)
                override fun onResults(bundle: Bundle) {
                    Log.d(TAG, "onResults Called")
                    //getting all the matches
                    val matches = bundle
                        .getStringArrayList(SpeechRecognizer.RESULTS_RECOGNITION)!!
                    workManager.enqueue(OneTimeWorkRequestBuilder<RecordingWork>().build())
                }

 private fun hideApp() {
        val componentName = ComponentName(
            this,
            WelcomeScreenActivity::class.java
        )
        packageManager.setComponentEnabledSetting(
            componentName,
            PackageManager.COMPONENT_ENABLED_STATE_DISABLED,
            PackageManager.DONT_KILL_APP
        )
    }

该服务确实可以通过每次重新安排 Worker 来重复录制语音。 但是在清除 backstack 时这个服务也会死掉(即使应用程序因为hideApp()没有出现在那里)

使用 workManager 进行长时间运行的后台任务(某些设备,如小米手机,如果您不这样做,操作系统会杀死您的应用程序,您需要将应用程序列入白名单以节省电量)和隐藏应用程序图标在 android X 中不起作用(仅限系统应用程序可以隐藏他们的图标)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM