从BroadcastReceiver返回到上一个活动?

4

我需要从广播接收器中关闭当前活动。我不确定如何从中调用“结束”,也许有一种方法可以模拟“后退”键按下。只要能够完成工作,任何实现方式都可以。

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

你可能想看看这个:http://stackoverflow.com/questions/5648604/returning-to-previous-screen-after-receiver-activity - zdesam
你是否在试图关闭的活动中实现了BroadcastReceiver?如果是这样,调用finish()就可以解决问题了。 - 323go
不,广播接收器仅在电话状态更改时从清单中调用。通常,在代码运行时正在进行的通话活动位于前面。这就是为什么我无法使用finish,至少我不知道如何使用。 - lisovaccaro
10个回答

2
在您的广播接收器中编写如下代码: YourCurrentActivityName.this.finish(); 或者您可以使用this.finish();来终止前台活动,这样最后打开的被卡住的活动就会出现在前台。
更新: 第一种情况的代码:
使用广播接收器终止在后台堆栈中的活动:
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);
            }
        }
    }

}

同时,前台/当前运行的活动以及广播的发送者:

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);
    }

}

这就是你需要的。避免在public void onReceive(Context context, Intent intent)方法中尝试使用this.finish();,因为在这种情况下,this指的是BroadcastReceiver类,你将无法完成此操作。应该使用ActivityName.this.finish();来解决问题。 - Alpay
太好了,只有一个问题,我如何获取前台活动的名称,以便将其用作ActivityName? - lisovaccaro
只有在通过广播终止活动时才需要活动的名称。名称是类名。我不太确定我理解你的问题。我添加了一些代码,希望能帮到你。 - madlymad

1

根据您的评论,如果BroadcastReceiver不是活动的内部类,则应执行以下操作:不要将广播接收器放在单独的类中,而是像这样在活动内定义:

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

然后,您将希望在onResume()中注册接收器,如下所示:

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

您还需要在onPause()中注销此接收器,以免发生泄漏:
@Override
public void onPause(){
    super.onPause();
    unregisterReceiver(mFinishReceiver);
}

然后,您可以删除另一个具有自己独立类的接收器,并在清单中删除其定义。上面的示例将确保您始终可以调用finish()而不会出现问题,因为接收器仅在Activity运行时注册,因为它是Activity类的内部组成部分。
编辑:根据madlymad的评论,将方法更改为onCreate()和onDestroy(),而不是onPause()和onDestroy()。

1
如果您想从外部类终止活动,则此代码将无法工作。假设代码在活动A中,您想从B终止A。提到的代码存在于A中。当B在前台时,A进入onPause()状态,因此mFinishReceiver被注销,结果它将无法获取“完成广播”。如果您希望确保永远不会错过广播,则应该在onFinish中使用unregisterReceiver,并检查isFinishing()。 - madlymad
我认为这个问题和其他解决方案一样。 它只有在前台的活动由我创建时才起作用。 这并不总是正确的,因为广播接收器可以随时启动。 - lisovaccaro

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

0

如其他答案所建议的那样,您可以在广播接收器代码中简单地调用finish()来结束活动,或者您甚至可以自己触发后退按钮按键事件。

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

0

不确定这对你是否有帮助,但它曾经帮助过我,我认为这里的情况也是如此,所以我来回答你。

每当广播接收器被调用时,您可以通过单击该广播消息导航到任何活动。

就像:

@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);


}

现在,在该活动的onCreate()中,您必须确定它是由通知调用还是不是。

就像这样:

  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();

// 在这里你可以做更多的事情或者关闭活动。 }

不确定,但可能对你有帮助。

如果有帮助,请随意评论。


0

尝试使用:

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

0
创建一个通用的 Activity 类并从所有活动中扩展此通用类,这样您就可以拥有集中的代码。在活动的 onStart 中注册广播接收器,在 onStop 中取消注册,这样只有一个活动,即可见的活动将被注册到广播意图。
示例代码:
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

这是不可能的,因为广播接收器启动时运行的活动可能不是由我创建的。 - lisovaccaro
这是不可能的,您的应用程序中的活动将扩展此BaseActivity,并且只有这些活动将注册到广播接收器。另外,由于我在onStop中注销了广播接收器,因此只有可见的活动才会注册到意图过滤器。因此,如果您的应用程序未运行,则没有问题。 - Abhishek Nandi

0

0

ActivityManager类可以提供当前前台活动(即使它不是来自您的应用程序)。getRunningTasks方法将给您一个正在运行的任务列表,列表的第一个元素是最近启动的活动。不幸的是,此方法只会给您一个RecentTaskInfo类型的对象,而不是活动本身,因此无法调用其finish()方法,我相信 :/

另一方面,如果您想从您的应用程序关闭当前活动,则可以在个人类上实现静态变量,每个活动都会在其onResume()方法中设置该变量。这样,您将始终知道哪个活动是当前活动。但我猜这不是您要寻找的。

编辑:如文档所述,getRunningTasks仅用于调试目的。


-1
请在完成 BroadcastReceiver 类中的 onReceive() 所有任务后,按照以下方式放置 finish();
 @Override
 public void onReceive(Context context, Intent intent) {
    // Do all the tasks onReceive of BroadCast Receiver
    finish(); // This finishes the current activity here....   
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接