简体   繁体   中英

Make a service close an external activity (created through implicit intent)

What I want to do is quite simple: my application offers the user to watch a maximum of 10 min of video, then it stops the video and gets back to my application (previous activity). The video is shown in an external player with that code:

Intent intentVideo = new Intent();
intentVideo.setAction(Intent.ACTION_VIEW);
intentVideo.setData(Uri.parse(url)));
startActivity(intentVideo); 

Then a background Service check periodically if time is elapsed or not.

How can my service kill the video activity ( where I can't add code or listeners, or whatever, because it is provided by an external app ) and make my app go back to its previous activity when time is elapsed?

Thanks

One way to solve this problem is to define a BroadcastReceiver inside the Activity . When the Service needs to notify the Activity that the time is up, send a broadcast and receive it in the BroadcastReceiver . Then, inside the onReceive() call finish() on the Activity to kill it. Hope this helps.

Okay here's my final code if it can help, thanks to Egor.

Note: Two solution are possible to force stopping the player activity:

  1. using startActivityForResult(intent, rq) / finishActivity(rq)
  2. using FLAG_ACTIVITY_CLEAR_TOP

Be careful using finishActivity() , some external apps won't close because of their behavior. For me it worked well when I open videos using VLC player, but not working when I open videos with Dailymotion app.

ActivityThatLaunchesPlayer.java

public class ActivityThatLaunchesPlayer extends Activity 
{

    private BroadcastReceiver brdreceiver = new BroadcastReceiver() 
    {
        @Override
        public void onReceive(Context context, Intent intent) 
        {
            System.out.println("broadcast signal received");

             //either
             finishActivity(57); //57 is my arbitrary requestcode

             //or either :
            Intent intentback = new Intent(getApplicationContext(),  ActivityThatLaunchesPlayer.class);
            intentback.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
            startActivity(intentback); 
        }
    };

    @Override
    protected void onCreate(Bundle savedInstanceState) 
    {
    super.onCreate(savedInstanceState);

            //set the brdcstreceiver to listen to the slot
    getApplicationContext().registerReceiver(brdreceiver, new IntentFilter("com.example.portail10.timeElapsed"));

            //here we launch the player (android opens a new appropriate activity)
    Intent intent = new Intent();

    intent.setAction(android.content.Intent.ACTION_VIEW);
    intent.setData(Uri.parse(uri));
        startActivityForResult(intent, 57); //again arbitrary rqstcode

            //here we start the service that watch the time elapsed watching the video
            intentServ = new Intent(this, TimeWatcher.class);
            startService(intentServ);
     }
}

TimeWatcher.java

public class TimeWatcher extends Service 
{

    //... some code is missing, but the main idea is here

@Override
public int onStartCommand(Intent intent, int flags, int startId) 
{
    super.onStartCommand(intent, flags, startId);

    timer.scheduleAtFixedRate(new TimerTask() 
    {
        public void run() 
        {
            //send the broadcast when time's up
            Intent intentbrd = new Intent();
            intentbrd.setAction("com.example.portail10.timeElapsed");
            sendBroadcast(intentbrd); 

            System.out.println("Brdcast sent");

            stopSelf();

        }
    }, 0, 600000); //in ms = 10min

    return START_NOT_STICKY;
} 

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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