简体   繁体   中英

Go to previous activity from BroadcastReceiver?

I need to close the current activity from a broadcast receiver. I'm not sure how to call finish from it, maybe there is a way to simulate a "Back" key keypress. Any implementation will be fine as long as it does the job.

@Override
public void onReceive(Context context, Intent intent) {
// How can I finish the current activity here?
}

At your broadcast receiver write: YourCurrentActivityName.this.finish();

Or you can terminate the front activity with this.finish(); so the last open in stuck comes to front.


Update: Code for first case:

Use of broadcast receiver to terminate activity at back stack:

public class ActivityFirstName extends Activity {

    private BroadcastReceiver mFinishReceiver;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        // other code

        if (mFinishReceiver == null) {
            IntentFilter intentFilter = new IntentFilter();
            intentFilter.addAction("com.example.ACTION_TERMINATE");// a string to identify your action
            mFinishReceiver = new BroadcastReceiver() {
                @Override
                public void onReceive(Context context, Intent intent) {
                    // How can I finish the current activity here?
                    if ("com.example.ACTION_TERMINATE".equals(intent.getAction())) {
                        ActivityFirstName.this.finish();
                    }
                }
            };
            registerReceiver(mFinishReceiver, intentFilter);
        }

        // other code

    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        if (isFinishing()) {
            if (mFinishReceiver != null) {
                unregisterReceiver(mFinishReceiver);
            }
        }
    }

}

And the front/current running activity, the sender of the broadcast:

public class ActivitySecondName extends Activity {

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.second);

        // code code code

        final Button button = (Button) findViewById(R.id.button_id);
        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                // Perform action on click
                terminateBackActivities();
            }
        });
    }

    private void terminateBackActivities() {
        Intent i = new Intent("com.example.ACTION_TERMINATE"); // the two action strings MUST be same
        // i.putExtra(...); // to send extra data
        sendBroadcast(i);
    }

}

你可以简单地调用this.finish();

Assuming from your comment that the BroadcastReceiver is not an internal class of the activity, here is what you should do: Rather than having the broadcast receiver in a separate class, define it inside your activity like so:

private BroadcastReceiver mFinishReceiver = new BroadcastReceiver(){
@Override
    public void onReceive(Context context, Intent intent){
        YourActivity.this.finish();
    }
};

Then, you will want to register the receiver in onResume() as such:

@Override
public void onResume(){
    super.onResume();
    registerReceiver(mFinishReceiver, new IntentFilter(yourIntentAction));
}

You will also want to unregister this receiver in onPause() so you don't leak it:

@Override
public void onPause(){
    super.onPause();
    unregisterReceiver(mFinishReceiver);
}

Then you can remove the other receiver that had its own separate class and also remove its definition in the manifest. The above example will ensure that you can always call finish() with no issues because the receiver is only registered when the activity is running, as it is internal to the activity's class.

EDIT: Change the methods to onCreate() and onDestroy() rather than onPause() and onDestroy(), according to madlymad's comment.

The ActivityManager class can give you the current foreground activity (even if it's not from your app). The getRunningTasks methods will give you a list of the running tasks, the first element of the list being the most recent launched activity.Unfortunately,this method will just give you an object of type RecentTaskInfo , not the activity itself, so there is no way to call its finish() method,I believe :/

On the other hand, if you want to close the current activity from your app, you can implement a static variable on a personal class that each activiy would set in their onResume() method. This way you will always know what activity is the current one. But I guess it's not what you are looking for.

Edit: The getRunningTasks is just intended for debug purposes, as says the doc..

如其他答案所示,您只需在广播接收器代码中调用活动上的finish(),或者您甚至可以自己触发后退按键按键事件。

this.dispatchKeyEvent(new Keyevent(ACTION_DOWN, KEYCODE_BACK)); 

Not sure about whether this is helpfull to you or not but its help me once and i think thats a same case here so i am answering for you.

Whenever the broadcast receiver get call, you can navigate to any activity by clicking on that broadcast message.

Just like:

@Override
public void onReceive(Context context, Intent intent) {
    // My Notification Code
    notificationManager = (NotificationManager)context.getSystemService(Context.NOTIFICATION_SERVICE);
    int icon = R.drawable.app_icon;
    //System.out.println("The ID Number is: "+Long.parseLong(intent.getData().getSchemeSpecificPart()) );
    contentText = intent.getStringExtra("MyMessage");
    System.out.println("The Message is: "+intent.getStringExtra("MyMessage"));
    CharSequence text = "Your tax amount due period";
    CharSequence contentTitle = "Tax Toolbox";

    long when = System.currentTimeMillis();

    intent = new Intent(context, MenuPageActivity.class); // here i am calling activity
    intent.putExtra("sixMonth", "sixMonth");
    intent.putExtra("messageSixMonth", contentText);
    PendingIntent contentIntent = PendingIntent.getActivity(context, 1, intent, PendingIntent.FLAG_UPDATE_CURRENT);

    notification = new Notification(icon,text,when);

    long[] vibrate = {0,100,200,300};
    notification.vibrate = vibrate;  // To vibrate the Device

    notification.ledARGB = Color.RED;
    notification.ledOffMS = 300;
    notification.ledOnMS = 300;

    notification.defaults |= Notification.DEFAULT_LIGHTS;
    //notification.flags |= Notification.FLAG_SHOW_LIGHTS;

    notification.setLatestEventInfo(context, contentTitle, contentText, contentIntent);
    notificationManager.notify(com.project.TaxToolbox.NotificationConstants.NOTIFICATION_ID_SIX_MONTH, notification);


}

Now, on the onCreate() of that activity you have to identify whether it is call by Notification or not.

As like:

  NotificationManager notificationManager = (NotificationManager)getSystemService(Context.NOTIFICATION_SERVICE);

    System.out.println("The Extra for twoMonth is:  "+getIntent().hasExtra("twoMonth"));
    System.out.println("The Extra for sixMonth is:  "+getIntent().hasExtra("sixMonth"));
    System.out.println("The Extra for EveryMonth is:  "+getIntent().hasExtra("everyMonth"));



    if(getIntent().hasExtra("sixMonth")){
        notificationManager.cancel(NotificationConstants.NOTIFICATION_ID_SIX_MONTH);
        final AlertDialog alert3 = new AlertDialog.Builder(MenuPageActivity.this).create();
        alert3.setTitle("Tax Toolbox");
        alert3.setMessage(getIntent().getExtras().getString("messageSixMonth"));
        alert3.setButton("OK", new DialogInterface.OnClickListener() {
            public void onClick(DialogInterface dialog, int which) {
                return;
            }
        });
        alert3.setIcon(R.drawable.app_icon);
        alert3.show();

// here you can do anything more or close the activity. }

Not sure but might be helpfull to you.

Feel free to comments if it help you.

尝试使用:

Intent i = new Intent(context,intent.getClass());

Create a common Activity class and extend this common class from all activities, that way you can have a centralized code. Have a register the broadcast receiver in onStart of the activity and unregister in onStop that way only one activity, the one which is visible will be registered for the broadcast intent.

Sample code:

public class BaseActivity extends Activity {

    /*
     * (non-Javadoc)
     * 
     * @see android.app.Activity#onCreate(android.os.Bundle)
     */
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        registerReceiver(receiver, new IntentFilter(YOUR_INTENT_FILTER)); 
    }
    /*
     * (non-Javadoc)
     * 
     * @see android.app.Activity#onStop()
     */
    protected void onStop(){
        unregisterReceiver(receiver);
    }

    /*
     * (non-Javadoc)
     * 
     * @see android.app.Activity#onStart()
     */
    protected void onStart(){
        super.onStart();
        registerReceiver(receiver, new IntentFilter(YOUR_INTENT_FILTER)); 
    }

    private BroadcastReceiver receiver = new BroadcastReceiver() {

        /*
         * (non-Javadoc)
         * 
         * @see
         * android.content.BroadcastReceiver#onReceive(android.content.Context,
         * android.content.Intent)
         */
        @Override
        public void onReceive(Context context, Intent intent) {
            onBackPressed();//on back pressed simply calls finish()
        }
    };
} // End of BaseActivity 
// End of File

Place finish(); after u completed all the tasks in onReceive() of BroadcastReceiver class as below:

 @Override
 public void onReceive(Context context, Intent intent) {
    // Do all the tasks onReceive of BroadCast Receiver
    finish(); // This finishes the current activity here....   
}

Follow the instructions from gezdy on How to get current foreground activity context in android? to ensure you can get a reference to the current activity from anywhere in your application.

From there you can call .finish() to close the current activity.

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