如何在从通知(活动2)启动的活动后启动MainActivity(活动1)在后台销毁

Posted

技术标签:

【中文标题】如何在从通知(活动2)启动的活动后启动MainActivity(活动1)在后台销毁【英文标题】:How to launch MainActivity(activity1) after the activity launched from notification(activity2) in destoryed on backpress 【发布时间】:2020-02-23 01:18:50 【问题描述】:

从通知启动 Activity 后,可以说当用户使用 backpress 时,activity2(result) 完成或销毁,它会进入主屏幕而不是 Main Activity。如何防止这种情况并打开 mainactivity。

到目前为止,方法实现是检查 activity2 是直接从 mainactivity(使用 extras)启动还是从通知启动,以便根据 bundle 值控制 onDestory,但这是一个明显的时间差是纠正这个或启动通知时创建堆栈历史记录

当前代码

notificationservice.java

Intent resultIntent = new Intent(this, videonotifications.class);
       Intent parentIntent=new Intent(this, MainActivity.class);
       TaskStackBuilder stackBuilder = TaskStackBuilder.create(this);
        //stackBuilder.addNextIntentWithParentStack(resultIntent);
        stackBuilder.addParentStack(videonotifications.class);
// Adds the Intent to the top of the stack
        stackBuilder.addNextIntent(resultIntent);
        PendingIntent resultPendingIntent =stackBuilder.getPendingIntent(0, PendingIntent.FLAG_UPDATE_CURRENT);
        mNotificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
        createNotificationChannel(mNotificationManager);
        Notification notification = new NotificationCompat.Builder(this,DEFAULT_CHANNEL_ID)
                .setContentTitle("Fall Detected")
                .setStyle(new NotificationCompat.BigTextStyle()
                        .bigText("A Fall Has Been Detected By Smart Video Surveillance At Old Age Home's Common Room"))//Set the title of Notification
                .setSmallIcon(R.drawable.ic_home_black_24dp)
                .setAutoCancel(true)
                .setContentIntent(resultPendingIntent)
                .build();
        mNotificationManager.notify(1, notification);
        final Intent i=new Intent(this,notificationsservice.class);
        //stopService(i);

videonotification.java

public void onDestroy() 
      //to be optimized as the roundabout procedure
        super.onDestroy();
        Bundle extras;
        extras=getIntent().getExtras();
        if(extras==null)
        Intent i=new Intent(this,MainActivity.class);
        i.putExtra("activity","notification is already called");
        startActivity(i);
        
    

MainActivity.java

Bundle extras=null;
       extras=getIntent().getExtras();
       if(extras==null)
           final Intent i=new Intent(this, notificationsservice.class);
        new Timer().schedule(new TimerTask() 
            @Override
            public void run() 
                startService(i);
            
        ,5000);

androidManifest.xml

<activity
            android:name=".videonotifications"
            android:parentActivityName=".MainActivity">
            <meta-data
                android:name="android.support.PARENT_ACTIVITY"
                android:value=".MainActivity"/>
        </activity>

【问题讨论】:

参考this 【参考方案1】:

TL;DR - 覆盖 onBackPressed() [当用户按下后退按钮时调用的方法],如果用户从通知中进入活动,则使用 Intent 启动 MainActivity。

我的理解是,只有在通过单击通知启动 FromNotificationActivity 时,您才希望从活动 2(我们称之为 FromNotificationActivity)移动到活动 1(我们称之为 MainActivity),即:

用户点击通知 ---> FromNotificationActivity 被启动 ---> 返回按钮被按下并且 FromNotificationActivity 被销毁 ---> 你不想返回主屏幕,而是想启动 MainActivity。

我相信最快的方法是重写 onBackPressed() 并仅在 FromNotificationActivity 从通知启动时直接转到 MainActivity。

所以,当你创建通知时,添加这一行 -

intent.putExtra("origin_from_notification", true);

所以您的通知生成器将如下所示 -

Intent intent = new Intent(context, FromNotificationActivity.class);
intent.putExtra("origin_from_notification", true);
PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, intent, 0);

// TODO: Replace with .Build() for api >= 16
Notification notification = new Notification.Builder(context)
    .setContentTitle("Notification Title"
    .setContentText("Notification text")
    .setSmallIcon(R.drawable.icon)
    .setContentIntent(pendingIntent)
    .// Whatever more you want to add

然后,在您的 FromNotificationActivity 中,在 onCreate() 之后,添加以下行 -

@Override
public void onBackPressed() 
    // Check if the user came here from a notification
    if (getIntent().getBooleanExtra("origin_from_notification", true)) 
        Intent intent = new Intent(this, MainActivity.class);
        startActivity(intent);
     else 
        // Do whatever you want, the user came here from another screen
    

如果您的活动在标题栏中有一个后退按钮,请使用此按钮 -

@Override
public boolean onOptionsItemSelected(MenuItem item) 
    switch (item.getItemId()) 
        case android.R.id.home:
            onBackPressed();
            break;
    

希望这会有所帮助!

【讨论】:

【参考方案2】:

首先在Manifest处添加activity2android:parentActivityName属性

<activity
    android:name=".Activity2"
    android:parentActivityName=".MainActivity" />

然后要启动一个包含活动回栈的活动,您需要创建一个TaskStackBuilder 的实例并调用addNextIntentWithParentStack(),将Intent 传递给您要启动的活动。 您可以调用getPendingIntent() 来接收包含整个后台堆栈的PendingIntent

// Create an Intent for the activity you want to start
Intent resultIntent = new Intent(this, Activity2.class);
// Create the TaskStackBuilder and add the intent, which inflates the back stack
TaskStackBuilder stackBuilder = TaskStackBuilder.create(this);
stackBuilder.addNextIntentWithParentStack(resultIntent);
// Get the PendingIntent containing the entire back stack
PendingIntent resultPendingIntent =
        stackBuilder.getPendingIntent(0, PendingIntent.FLAG_UPDATE_CURRENT);

然后您可以照常将PendingIntent 传递给通知:

NotificationCompat.Builder builder = new NotificationCompat.Builder(this, CHANNEL_ID);
builder.setContentIntent(resultPendingIntent);
...
NotificationManagerCompat notificationManager = NotificationManagerCompat.from(this);
notificationManager.notify(NOTIFICATION_ID, builder.build());

【讨论】:

以上是关于如何在从通知(活动2)启动的活动后启动MainActivity(活动1)在后台销毁的主要内容,如果未能解决你的问题,请参考以下文章

如何在从 AppWidgetProvider android 启动新活动之前关闭所有活动

如何在新的意图活动完成后启动其余方法

如何在通知单击时重新启动/刷新活动内容

未找到启动器活动!在安卓中

从服务启动活动

推送通知以打开特定活动