Android 如何打开在单击通知时打开的当前活动

Android 如何打开在单击通知时打开的当前活动,android,push-notification,Android,Push Notification,我已经尝试了所有的方法,但对我不起作用。我想在点击通知时打开或恢复任何屏幕的应用程序 我使用了以下方法: NotificationCompat.BigTextStyle notiStyle = new NotificationCompat.BigTextStyle(); notiStyle.setBigContentTitle(team); notiStyle.bigText(message); Intent resultIntent = new

我已经尝试了所有的方法,但对我不起作用。我想在点击通知时打开或恢复任何屏幕的应用程序

我使用了以下方法:

NotificationCompat.BigTextStyle notiStyle = new NotificationCompat.BigTextStyle();
        notiStyle.setBigContentTitle(team);
        notiStyle.bigText(message);

        Intent resultIntent = new Intent(this, MainDrawerActivity.class);
        resultIntent.putExtra("fromNotification", "notification");

        resultIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP
                | Intent.FLAG_ACTIVITY_SINGLE_TOP);


        TaskStackBuilder stackBuilder = TaskStackBuilder.create(this);



        stackBuilder.addNextIntent(resultIntent);


        PendingIntent resultPendingIntent = stackBuilder.getPendingIntent(0,
                PendingIntent.FLAG_UPDATE_CURRENT);

        int icon = R.mipmap.ic_launcher;


        return new NotificationCompat.Builder(this).setSmallIcon(icon)
                .setAutoCancel(true)

                .setContentIntent(resultPendingIntent).setContentTitle(team)
                .setContentText(message).setStyle(notiStyle).build(); 
开展新的活动

public class FinishImmediateActivity extends AppCompatActivity {
  @Override protected void onCreate(@Nullable Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    finish();
  }
}
添加到manifest.xml

<activity android:name=".FinishImmediateActivity"/>

要在不启动任何新活动的情况下将应用程序提升到前台,请启动它的启动程序

这种方法来自我的一个老项目

/**
 * Creates a new launcher intent, equivalent to the intent generated by
 * clicking the icon on the home screen.
 *
 * @return the launcher intent
 */
public static Intent newLauncherIntent(final Context context) {
    final Intent intent = new Intent(context, MainActivity.class);
    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
    intent.setAction(Intent.ACTION_MAIN);
    intent.addCategory(Intent.CATEGORY_LAUNCHER);
    return intent;
}
如果应用程序正在运行,则此方法创建的意图不会启动新任务,即使它具有该标志

这是获得启动器意图的另一种方法。然而,我发现这个意图总是会启动一个新任务,如果应用程序正在运行,这不是你想要的

final Intent intent = context.getPackageManager()
        .getLaunchIntentForPackage(BuildConfig.APPLICATION_ID);

如果你只想恢复应用程序状态,那么我建议你只保留单个活动,并为不同的屏幕使用片段,而不是多个活动

在通知中单击,您需要在通知负载中定义应用程序的入口点,该入口点决定下一次导航的内容

如果您只有一个活动,那么您可以将该活动定义为入口点,并在该活动上决定是否必须推送新片段


或者第二个选项,如果您正在使用firebase,则将所有通知推送到后台通知和
onMessageReceive
方法,您可以从活动堆栈中获取顶级活动,并将该活动设置为通知的入口点。但仍然存在问题,因为用户可能会在从设置入口点活动导航后单击通知,从而再次出现问题。因此,我更倾向于使用第一种方法。

这在以下三种情况下运行良好:

1.若应用程序已经打开并点击通知,则通知应从状态栏中删除

2.如果应用程序处于打开状态且处于后台,则应用程序应在之前已打开的任何屏幕上恢复

3.如果应用程序已关闭,并单击状态栏中的通知,则应用程序应打开

private final static int NORMAL = 0x00;
private final static int BIG_TEXT_STYLE = 0x01;
private static NotificationManager mNotificationManager;
在线留言电话

mNotificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
new CreateNotification(BIG_TEXT_STYLE, team, message).execute();
然后在gcminentservice中声明以下类。 公共类CreateNotification扩展了异步任务{

    int style = NORMAL;
    String team, message;

    public CreateNotification(int style, String team, String message) {
        this.style = style;
        this.team = team;
        this.message = message;

    }

    @Override
    protected Void doInBackground(Void... params) {
        Notification noti = new Notification();

        switch (style) {
        case BIG_TEXT_STYLE:
            noti = setBigTextStyleNotification(team, message);
            break;

        }

        noti.sound = (null);
        noti.defaults = 0;
        noti.sound = Uri.parse("android.resource://" + getPackageName() + "/" + R.raw.beep);
        noti.flags |= Notification.FLAG_AUTO_CANCEL;

        mNotificationManager.notify(0, noti);

        return null;

    }
}
最后

private Notification setBigTextStyleNotification(String team, String message) {

    // Create the style object with BigTextStyle subclass.
    NotificationCompat.BigTextStyle notiStyle = new NotificationCompat.BigTextStyle();
    notiStyle.setBigContentTitle(team);
    notiStyle.bigText(message);


    Intent      resultIntent = getPackageManager()
            .getLaunchIntentForPackage(getPackageName());

    TaskStackBuilder stackBuilder = TaskStackBuilder.create(this);

        // Adds the Intent that starts the Activity to the top of the stack.
    stackBuilder.addNextIntent(resultIntent);


    PendingIntent resultPendingIntent = stackBuilder.getPendingIntent(0,
            PendingIntent.FLAG_UPDATE_CURRENT);
    int icon = R.mipmap.ic_launcher;


    return new NotificationCompat.Builder(this).setSmallIcon(icon)
            .setAutoCancel(true)

            .setContentIntent(resultPendingIntent).setContentTitle(team)
            .setContentText(message).setStyle(notiStyle).build();
}

通过这种方式,我们还可以实现上述结果:

            try {
            int icon;

                icon = R.mipmap.ic_launcher;


        int mNotificationId = 001;


            Intent intent = new Intent(this, MainDrawerActivity.class);
            intent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);

            //FLAG_UPDATE_CURRENT is important
            PendingIntent pendingIntent = PendingIntent.getActivity(this, 
 (int)System.currentTimeMillis(), intent, 
PendingIntent.FLAG_UPDATE_CURRENT);


            NotificationCompat.Builder mBuilder = new 
 NotificationCompat.Builder(
                this);
        Notification notification = 
  mBuilder.setSmallIcon(icon).setTicker(json.getString("team")).setWhen(0)
                .setAutoCancel(true)
                .setContentTitle(json.getString("team"))
                .setStyle(new 
 NotificationCompat.BigTextStyle().bigText(json.getString("message")))
                .setContentIntent(pendingIntent)
                .setSound(Uri.parse("android.resource://" + getPackageName() + "/" + R.raw.beep))


        NotificationManager notificationManager = (NotificationManager) 
  this.getSystemService(Context.NOTIFICATION_SERVICE);
        notificationManager.notify(mNotificationId, notification);




        } catch (Exception e) {
            e.printStackTrace();
        }

Application
类中应该有类似的内容来存储当前活动

private BaseActivity mCurrentActivity = null;

public BaseActivity getCurrentActivity() {
    return mCurrentActivity;
}

public void setCurrentActivity(BaseActivity currentActivity) {
    this.mCurrentActivity = currentActivity;
}
然后,在句柄通知服务类中

@Override
    public void onMessageReceived(RemoteMessage remoteMessage) {
        super.onMessageReceived(remoteMessage);

    BaseActivity currentActivity = ((App) this.getApplicationContext())
                               .getCurrentActivity();
        Intent intent;
        if (currentActivity instanceof ActivityA) {
            intent = new Intent(this, ActivityA.class);
        } else if (currentActivity instanceof ActivityB) {
            intent = new Intent(this, ActivityB.class);
        } else {
            intent = new Intent(this, MainActivity.class);
        }

        intent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
        PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, intent,
                PendingIntent.FLAG_UPDATE_CURRENT);

    // your code...
}
如果您的应用程序被终止,将调用默认活动,如MainActivity

否则,当应用程序位于前台或后台时,当您收到并单击推送通知消息时。当前活动将作为默认活动(如ActivityA和ActivityB)保留在此处。然后,您可以导航到其他活动或片段所在的位置



我的建议是,最好使用Fragment,它更容易从推送通知导航到特定屏幕。

你是说当你在后台时吗?如果你在前台打开同一个活动,你会得到onNewIntent方法。是的,每次我单击通知时,它都会从一开始打开。这取决于你当前的ac活动状态并基于启动模式恢复或创建新的启动模式我没有设置anthing。在哪个类中我必须在主抽屉或GCM意向通知中使用它。Intent resultIntent=新意向(此,FinishImpediateActivity.class);Rate,现在应用程序仍保持在同一页面上,但单击通知时其未打开。但当我单击应用程序图标并打开时,应用程序将与上一屏幕一起打开。如果我想打开应用程序,我需要做什么?请帮我解决问题。当应用程序打开时,您的方法工作正常,单击通知,通知将被取消。在应用程序打开时,我只需要做一件事在后台,单击通知,应用程序应该恢复。我正在elicpse中使用GCM。非常感谢,您保存了我的一天。它工作正常。当应用程序在后台时,只有应用程序打开并保持在屏幕上。但当应用程序在前台时,应用程序将再次重新启动。但我不想重新启动。只需将该通知从状态中删除即可bar.我需要做什么?@sunil我没有遇到这个问题,但我也不能100%确定我测试了那个场景。我会调查一下。我正在使用这个(它正在通过run按钮运行应用程序)我认为这是可行的,但不知何故,当我试图运行/安装我从build>build apk菜单中构建的apk时,我得到了一种不同的结果。哦,我的糟糕,这是可行的。我有一个不同的问题,为什么我有一个印象不起作用。这与相关。但我仍然打算开始一项新任务,我对我遇到的问题进行修复,效果很好ted.props to kevin..+1..是的,我也这么做了…使用一个活动,所有其他屏幕都是片段。如果您有单个活动,您应该在清单中将活动定义为singleTask,因此单击通知,如果您的活动位于后台,它将使用新数据调用onNewIntent。Thanx,通过这种方式,它已解决了Intent Intent=new Intent的问题(this,maindureractivity.class);intent.addFlags(intent.FLAG_ACTIVITY_SINGLE_TOP);pendingent pendingent=pendingent.getActivity(this,(int)System.currentTimeMillis(),intent,pendingent.FLAG_UPDATE_CURRENT);希望您也喜欢这个答案。如果“是”,那么@Kevin Krumwiede方法与您的代码的工作方式是一样的您喜欢哪种方法,您的方法还是他的方法?我正在使用我的方法,Intent Intent=new Intent(this,maindureractivity.class);Intent.addFlags(Intent.FLAG\u ACTIVITY\u SINGLE\u TOP);这个标志我正在使用pendingent pendingent=pendingent.getActivity(this,(int)System.currentTimeMillis(),intent,pendingent.FLAG_UPDATE_CURRENT);我还使用intent resultent=getPackageManager().getLaunchIntentForPackage(getPackageName());尝试了上述解决方案(它正在通过运行按钮运行应用程序)我认为这是可行的,但不知怎的,当我试图运行/安装我从build>BuildAPK菜单构建的apk时,我得到了一种不同的结果。
            try {
            int icon;

                icon = R.mipmap.ic_launcher;


        int mNotificationId = 001;


            Intent intent = new Intent(this, MainDrawerActivity.class);
            intent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);

            //FLAG_UPDATE_CURRENT is important
            PendingIntent pendingIntent = PendingIntent.getActivity(this, 
 (int)System.currentTimeMillis(), intent, 
PendingIntent.FLAG_UPDATE_CURRENT);


            NotificationCompat.Builder mBuilder = new 
 NotificationCompat.Builder(
                this);
        Notification notification = 
  mBuilder.setSmallIcon(icon).setTicker(json.getString("team")).setWhen(0)
                .setAutoCancel(true)
                .setContentTitle(json.getString("team"))
                .setStyle(new 
 NotificationCompat.BigTextStyle().bigText(json.getString("message")))
                .setContentIntent(pendingIntent)
                .setSound(Uri.parse("android.resource://" + getPackageName() + "/" + R.raw.beep))


        NotificationManager notificationManager = (NotificationManager) 
  this.getSystemService(Context.NOTIFICATION_SERVICE);
        notificationManager.notify(mNotificationId, notification);




        } catch (Exception e) {
            e.printStackTrace();
        }
private BaseActivity mCurrentActivity = null;

public BaseActivity getCurrentActivity() {
    return mCurrentActivity;
}

public void setCurrentActivity(BaseActivity currentActivity) {
    this.mCurrentActivity = currentActivity;
}
@Override
    public void onMessageReceived(RemoteMessage remoteMessage) {
        super.onMessageReceived(remoteMessage);

    BaseActivity currentActivity = ((App) this.getApplicationContext())
                               .getCurrentActivity();
        Intent intent;
        if (currentActivity instanceof ActivityA) {
            intent = new Intent(this, ActivityA.class);
        } else if (currentActivity instanceof ActivityB) {
            intent = new Intent(this, ActivityB.class);
        } else {
            intent = new Intent(this, MainActivity.class);
        }

        intent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
        PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, intent,
                PendingIntent.FLAG_UPDATE_CURRENT);

    // your code...
}