0

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?

James Read
  • 419
  • 2
  • 7
  • 13
  • @CommonsWare Thanks for answering. Point taken. So, is there a way to stop an app from another app? I am seeing no evidence that the activity associated with the second app is being finished. – James Read Oct 28 '22 at 00:25

2 Answers2

1

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's 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) {
        this@SecondActivity.finish()
    } 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 ) {
        this@SecondActivity.finish()
    }
}

}

  • You will need to beware the activity life cycle unless you are making a system or privileged app which can pass by the restriction easily – Android Newbie A Oct 28 '22 at 07:50
0

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

user496854
  • 6,461
  • 10
  • 47
  • 84