前台服务内容意图不是恢复应用程序而是重新启动它

Posted

技术标签:

【中文标题】前台服务内容意图不是恢复应用程序而是重新启动它【英文标题】:Foreground service content intent not resuming the app but relaunching it 【发布时间】:2020-04-26 03:41:32 【问题描述】:

我一直在浏览许多关于从前台服务恢复活动的主题,但没有找到任何具体的问题答案。

我正在尝试在我的应用程序中放置一个前台服务,并且我希望在单击服务通知而不是重新启动它时恢复应用程序。我已经尝试使用来自PackageManagergetLaunchIntentForPackage() 方法,这是最接近我想要做的。

但是,当通过点击通知恢复应用时,Activity 的onCreate 仍然被调用。

所以这是我的问题,如何从通知的内容意图恢复应用程序?

我在活动的onStop 中启动我的 ForegroundService,所以当应用程序被杀死或发送到后台时它会被调用。

override fun onStop() 
    super.onStop()
    Log.v(TAG, "onStop")
    ForegroundService.startService(this, "Hellooooooo, here is the background")

前台服务

class ForegroundService: Service() 

    companion object 
        private const val CHANNEL_ID = "ForegroundServiceChannel"

        fun startService(context: Context, message: String) 
            val startIntent = Intent(context, ForegroundService::class.java)
            startIntent.putExtra("inputExtra", message)
            ContextCompat.startForegroundService(context, startIntent)
        
        fun stopService(context: Context) 
            val stopIntent = Intent(context, ForegroundService::class.java)
            context.stopService(stopIntent)
        
    

    override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int 
        val input = intent!!.getStringExtra("inputExtra")

        val launchIntent = packageManager.getLaunchIntentForPackage(APP_PACKAGE)
        val contentIntent = PendingIntent.getActivity(applicationContext, 0,
            launchIntent, 0)

        val notification: Notification = NotificationCompat.Builder(this, CHANNEL_ID)
            .setContentTitle("Foreground Service")
            .setContentText(input)
            .setContentIntent(contentIntent)
            .setSmallIcon(R.drawable.ic_call_to_action)
            .setOngoing(true)
            .build()

        startForeground(1, notification)
        createNotificationChannel()

        return START_NOT_STICKY
    

    override fun onBind(p0: Intent?): IBinder? 
        return null
    

    private fun createNotificationChannel() 
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) 
            val serviceChannel = NotificationChannel(
                CHANNEL_ID,
                "Foreground Service Channel",
                NotificationManager.IMPORTANCE_DEFAULT
            )
            val manager = getSystemService(
                NotificationManager::class.java
            )
            manager?.createNotificationChannel(serviceChannel)
        

    


【问题讨论】:

我认为您对Activity 生命周期有一些误解。只要Activity 不在屏幕上,操作系统就可以随意销毁它。事实上,你应该预料到它会在onStop() 之后不久被销毁。不要试图“解决”这个生命周期;使用它。我认为也许对您来说更重要的是您的 app 没有被破坏,因为您拥有前台服务。尝试将您的 Activity.onCreate() 逻辑(您不希望执行两次的内容)移动到应用程序/服务 onCreate() 【参考方案1】:
    尝试在活动清单中设置 android:launchMode="singleInstance"。 不要忘记为您的活动意图设置一些操作: activityIntent.setAction(ACTION_STARTED_FROM_NOTIFICATION); 覆盖 Activity 中的 onNewIntent。 在 onCreate 和 onNewIntent 中检查 if(ACTION_STARTED_FROM_NOTIFICATION.equalsIgnoreCase(intent.getAction())) 做你需要的

【讨论】:

以上是关于前台服务内容意图不是恢复应用程序而是重新启动它的主要内容,如果未能解决你的问题,请参考以下文章

重新创建的活动是不是记得启动它的原始意图?

应用程序强制退出和应用程序重新启动后如何恢复 NSURLSession 下载过程?

在活动处于前台时接收明确的意图

活动重新创建意图附加内容为空

前台服务已终止且未重新启动

防止我的 Cocoa 应用程序“恢复”?