Home > Enterprise >  How to stop a previously launched activity on Android in Kotlin
How to stop a previously launched activity on Android in Kotlin

Time:10-28

I have two apps. The first app launches the second app and should stop the second app after a time interval (currently 10 seconds) and then relaunch the app. Here is the code I have so far:

package com.example.launch

import android.content.ActivityNotFoundException
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.util.Log

class MainActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
    }

    override fun onResume() {
        super.onResume()
        val launchIntent = packageManager.getLaunchIntentForPackage("com.example.secondapp")
        while (true) {
            if (launchIntent != null) {
                try {
                    startActivityForResult(launchIntent, 1)
                    Log.d("", "Launching com.example.secondapp")
                } catch (e: ActivityNotFoundException) {
                    Log.d("", "Failed to launch com.example.secondapp")
                }
            } else {
                Log.d("", "Intent is null value.")
            }
            Thread.sleep(10000)
            finishActivity(1)
        }
    }
}

On my android phone (Galaxy A12) the first app launches the second app but doesn't stop it. Here is some typical output from the first app.

2022-10-28 00:17:58.127 21240-21240/com.example.launch D/: Launching com.example.secondapp
2022-10-28 00:18:08.140 21240-21240/com.example.launch D/: Launching com.example.secondapp
2022-10-28 00:18:18.150 21240-21240/com.example.launch D/: Launching com.example.secondapp

So it seems from the output that the first app believes it is successfully launching the second app every 10 seconds. This doesn't correspond with what I am seeing on the phone or in the log for the second app which is continuing to run without being stopped or relaunched.

Where am I going wrong? How can I fix this?

CodePudding user response:

An app can't stop have any knowledge or influence over other apps for security reasons. But since you're writing both apps, you can create an exported BroadcastReceiver in App#2, which has a specific intent filter (something like com.my.app.SHUT_DOWN). When it receives that intent, have it close all of its activities. Then in your App#1, send that intent whenever you want to kill App#2

Here's a similar question, but it's pretty old, and you may have to update the code appropriately for the latest API levels

CodePudding user response:

You shall make 2nd APP to decide when it shall end.

Since if 1st APP is staled due to various reason, 2nd APP will not be ended when time up.

IMO, I will pass the time to 2nd APP and let it decide when it shall be ended. Further, we shall aware the activity life cycle. Pause the timer when APP is going to background, restart the timer when APP is going back to foreground.

In 1st APP,

class FirstActivity: AppCompatActivity() {
override fun onResume() {
    super.onResume()
    val launchIntent: Intent? = packageManager.getLaunchIntentForPackage("com.example.secondapp")
    
    // added
    val timeout = 10 *1000
    launchIntent?.putExtra("timeout", timeout);

    if (launchIntent != null) {
        startActivity(launchIntent)
    }
}

In 2nd APP,

class SecondActivity: AppCompatActivity() {
private val TAG = "SecondActivity"
private val activityLaunchTime = SystemClock.elapsedRealtime() // Time since last reboot
private var timeout = -1L // -1 -> null -> indicates it shall not apply timeout
private var timer: CountDownTimer? = null

override fun onCreate(savedInstanceState: Bundle?, persistentState: PersistableBundle?) {
    super.onCreate(savedInstanceState, persistentState)
    timeout = intent.getLongExtra("timeout", -1);
    Log.d(TAG, "onCreate: timeout(from intent extras)=$timeout")
}

override fun onResume() {
    super.onResume()
    // Pseudo code for explanation
    // e.g.1, 00:00:15 > 00:00:00   00:00:10 -> true, finish now
    // e.g.2, 00:00:08 > 00:00:00   00:00:10 -> false, set timer again
    if (timeout != -1L && SystemClock.elapsedRealtime() > activityLaunchTime   timeout) {
        [email protected]()
    } else {
        setTimer(activityLaunchTime   timeout - SystemClock.elapsedRealtime())
    }
}

override fun onPause() {
    super.onPause()
    timer?.cancel()
}

private fun setTimer(t: Long) {
    if (t == -1L) { return }

    timer = object: CountDownTimer(t, 1000) {
        override fun onTick(millisUntilFinished: Long) {}

        override fun onFinish() {
            checkTimeout()
        }
    }

    timer?.start()
}

private fun checkTimeout() {
    if (timeout == -1L) { return }

    if (SystemClock.elapsedRealtime() > activityLaunchTime   timeout ) {
        [email protected]()
    }
}

}

  • Related