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

时间:2016-12-20 04:55:15

标签: android push-notification

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

我使用了以下方法:

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

7 个答案:

答案 0 :(得分:5)

要将应用程序提升到前台而不启动任何新活动,请启动其启动器意图。

这种方法来自我的旧项目。

/**
 * 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);

答案 1 :(得分:1)

这适用于以下三个条件:

1.如果应用已经打开并点击通知,通知应从状态栏中删除。

2.如果应用程序处于打开状态且处于后台状态,那么app应该恢复之前已打开的任何屏幕。

3.如果应用已关闭,请点击状态栏中的通知,然后应该打开应用。

private final static int NORMAL = 0x00;
private final static int BIG_TEXT_STYLE = 0x01;
private static NotificationManager mNotificationManager;
在onMessage调用中

mNotificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
new CreateNotification(BIG_TEXT_STYLE, team, message).execute();

然后在GCMIntentService中声明以下类。   公共类CreateNotification扩展了AsyncTask {

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

答案 2 :(得分:0)

Web app

答案 3 :(得分:0)

制作新活动

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

添加到manifest.xml

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

检查应用是否正在运行

public static boolean isMainActivityRunning() {
  ActivityManager activityManager = (ActivityManager) MyApp.getContext().getSystemService(Context.ACTIVITY_SERVICE);
  List<ActivityManager.RunningTaskInfo> tasksInfo = activityManager.getRunningTasks(Integer.MAX_VALUE);

  for (int i = 0; i < tasksInfo.size(); i++) {
    if (tasksInfo.get(i).baseActivity.getPackageName().equals(MyApp.getContext().getPackageName())) {
      return true;
    }
  }
  return false;
}

然后在通知意图中调用该活动。

Intent resultIntent = new Intent(this, isMainActivityRunning() ? FinishImmediateActivity.class : HomeActivity.class);

答案 4 :(得分:0)

如果您想恢复应用状态,那么我建议您只保留单个活动,并将片段用于不同的屏幕,而不是多个活动。

在通知单击中,您需要在通知有效负载中定义应用的入口点,并且入口点将决定下一个导航的内容。

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

或者第二个选项如果您使用的是firebase,那么将所有通知作为后台通知和onMessageReceive方法推送,您可以从活动堆栈中获取热门活动,并将该活动设置为通知的入口点。但是仍然存在问题,因为用户可能在从再次出现问题的设置入口点活动导航之后点击通知。所以我更喜欢采用第一种方法。

答案 5 :(得分:0)

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

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

答案 6 :(得分:0)

Application类中应该有类似的东西来存储当前活动。

private BaseActivity mCurrentActivity = null;

public BaseActivity getCurrentActivity() {
    return mCurrentActivity;
}

public void setCurrentActivity(BaseActivity currentActivity) {
    this.mCurrentActivity = currentActivity;
}

然后,在您的句柄通知Service类中。

@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,从推送通知导航到特定屏幕更容易。