1

Let me start by saying I know this is a very similar question to others that have been answered, but they aren't helping me to solve my problem.

The question Resume application and stack from notification is exactly the same problem as mine, but the selected answer doesn't work for me and I don't quite understand why it even would?

Simply enough, I want to be able to resume my app from a notification click and regardless of what activity was open I want it to return to the last activity open. So if I'm in activity F, then press the home button and a couple minutes later I press the notification.. I want to return back to activity F. I cannot go back to the MainActivity as the user is sometimes forced to stay on a certain activity.

This answer - https://stackoverflow.com/a/5502950/4662037 is shown below:

final Intent notificationIntent = new Intent(context, YourActivity.class);
notificationIntent.setAction(Intent.ACTION_MAIN);
notificationIntent.addCategory(Intent.CATEGORY_LAUNCHER);

It seems to be correct as so many people have accepted it but what exactly is "YourActivity" in this case?.. I don't want to set it to a specific activity!

EDIT: Updated code for notification

private void setForegroundService(){
    CharSequence text = getString(R.string.app_name);

    PackageManager pm = getPackageManager();

    Intent notificationIntent = pm.getLaunchIntentForPackage("com.example.xxxx.xxxxx");
    notificationIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
    PendingIntent contentIntent = PendingIntent.getActivity(getApplicationContext(), 0,
            notificationIntent, 0);

    // Create the notification
    Notification notification = new NotificationCompat.Builder(this)
            .setContentText(text)
            .setSmallIcon(R.drawable.nurse_call_app_icon)
            .setContentTitle(text)
            .setContentIntent(contentIntent).build();

    notification.flags = Notification.FLAG_AUTO_CANCEL | Notification.FLAG_ONGOING_EVENT;

    //  Start the actual service
    startForeground(Integer.MAX_VALUE, notification);
}

Manifest code:

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.xxxxx.xxxxxx"
    android:versionCode="1"
    android:versionName="0.0.1" >

<uses-sdk android:minSdkVersion="14" />

<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission android:name="android.permission.PROCESS_OUTGOING_CALLS" />
<uses-permission android:name="android.permission.VIBRATE" />
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.FLASHLIGHT" />
<uses-permission android:name="android.permission.CALL_PHONE" />
<uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<uses-permission android:name="android.permission.RECORD_AUDIO" />
<uses-permission android:name="android.permission.BLUETOOTH" />
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />

<uses-feature android:name="android.hardware.Camera" />
<uses-feature
    android:name="android.hardware.bluetooth_le"
    android:required="false" />

<application
    android:name=".xxxxxxx"
    android:allowBackup="true"
    android:icon="@drawable/xxxxxx"
    android:label="@string/app_name"
    android:theme="@style/AppTheme" >

    <service android:name=".xxxxxxService" />

    <activity
        android:name=".activities.LoginActivity"
        android:label="@string/app_name"
        android:screenOrientation="portrait" >
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />
            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
    </activity>

    <activity
        android:name=".activities.MainActivity"
        android:label="@string/app_name"
        android:launchMode="singleTop"
        android:screenOrientation="portrait" >
    </activity>
    <activity
        android:name=".activities.AlarmActivity"
        android:icon="@drawable/ic_action_alarms"
        android:label="@string/alarm_details"
        android:parentActivityName=".activities.MainActivity"
        android:screenOrientation="portrait" >
        <meta-data
            android:name="android.support.PARENT_ACTIVITY"
            android:value=".activities.MainActivity" />
    </activity>
    <activity
        android:name=".activities.SettingsActivity"
        android:icon="@drawable/ic_action_settings"
        android:label="@string/settings"
        android:parentActivityName=".activities.MainActivity"
        android:screenOrientation="portrait" >
        <meta-data
            android:name="android.support.PARENT_ACTIVITY"
            android:value=".activities.MainActivity" />
    </activity>
    <activity
        android:name=".activities.MessageListActivity"
        android:icon="@drawable/ic_action_email"
        android:label="@string/title_activity_text"
        android:launchMode="singleTask"
        android:parentActivityName=".activities.MainActivity"
        android:screenOrientation="portrait" >
        <meta-data
            android:name="android.support.PARENT_ACTIVITY"
            android:value=".activities.MainActivity" />
    </activity>
    <activity
        android:name=".activities.MessageActivity"
        android:icon="@drawable/ic_action_read"
        android:label="@string/message"
        android:parentActivityName=".activities.MessageListActivity"
        android:screenOrientation="portrait" >
        <meta-data
            android:name="android.support.PARENT_ACTIVITY"
            android:value=".activities.MessageListActivity" />
    </activity>
    <activity
        android:name=".activities.BreakActivity"
        android:icon="@drawable/ic_action_person"
        android:label="@string/title_activity_break"
        android:screenOrientation="portrait" >
    </activity>
    <activity
        android:name=".activities.ContactsActivity"
        android:icon="@drawable/ic_action_group"
        android:label="@string/title_activity_contacts"
        android:parentActivityName=".activities.MainActivity"
        android:screenOrientation="portrait" >
        <meta-data
            android:name="android.support.PARENT_ACTIVITY"
            android:value=".activities.MainActivity" />
    </activity>
    <activity
        android:name=".activities.CallActivity"
        android:icon="@drawable/ic_action_call"
        android:label="@string/title_activity_call"
        android:screenOrientation="portrait" >
    </activity>

    <receiver
        android:name=".BootUpReceiver"
        android:enabled="true"
        android:exported="true" >
        <intent-filter>
            <action android:name="android.intent.action.BOOT_COMPLETED" />
            <action android:name="android.intent.action.QUICKBOOT_POWERON" />
            <category android:name="android.intent.category.DEFAULT" />
        </intent-filter>
    </receiver>
    <receiver
        android:name=".PhoneCallReceiver"
        android:enabled="true"
        android:exported="true" >
        <intent-filter>
            <action android:name="android.intent.action.NEW_OUTGOING_CALL" />
            <action android:name="android.intent.action.PHONE_STATE" />
        </intent-filter>
    </receiver>
</application>

So a quick overview of what it does:

It starts with the LoginActivity, after you login it will destroy that and the MainActivity will then become the root of everything. You can navigate up and down between stacks but never below the MainActivity unless you call a logout.

Community
  • 1
  • 1
Murphybro2
  • 2,207
  • 1
  • 22
  • 36

3 Answers3

4

Look at my question here.

This is how you are supposed to do it:

Intent notificationIntent = new Intent(getApplicationContext(), MainActivity.class);
notificationIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP);

PendingIntent pendingIntent = PendingIntent.getActivity(getApplicationContext(), 0, notificationIntent, 0);

Notification notification = new Notification(R.drawable.floating2, "Click to start launcher",System.currentTimeMillis());
notification.setLatestEventInfo(getApplicationContext(), "Start launcher" ,  "Click to start launcher", pendingIntent);
notification.flags = Notification.FLAG_AUTO_CANCEL | Notification.FLAG_ONGOING_EVENT;

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

notificationManager.notify(ID_NOTIFICATION,notification);
Community
  • 1
  • 1
Fish
  • 1,689
  • 1
  • 18
  • 28
  • It doesn't appear to work, opens up the MainActivity every time.. I will post my full code into the question. Can you spot anything? – Murphybro2 May 19 '15 at 10:30
  • After looking at the question you posted, you want to show the MainActivity every time. Sorry but that is the opposite of what I want. – Murphybro2 May 19 '15 at 10:36
  • @Murphybro2 Firstly, you could change the MainActivity to whatever activity you want. Secondly I am aware that you want to resume your activity. So I found an article that might help you. Check out [this article about how to intent resume](http://stackoverflow.com/questions/3305088/how-to-make-notification-intent-resume-rather-than-making-a-new-intent) – Fish May 19 '15 at 11:54
  • 1
    How did this get 4 upvotes? This is wrong. OP doesn't want to clear the task back to the root activty. He just wants to bring the existing task stack to the foreground. – David Wasser May 19 '15 at 12:37
0

YourActivity is the root activity. That's the one that is defined with ACTION=MAIN and CATEGORY=DEFAULT in your manifest.

You will also need to set FLAG_ACTIVITY_NEW_TASK as well:

notificationIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);

This doesn't actually start any Activity (if your app is already running). It just brings the task containing your app to the foreground in the same state it was in when it went to the background, which is what you want.


UPDATE:

Since you seem to be having problems with this, please try this alternative suggestion:

PackageManager pm = getPackageManager();
// NOTE: replace com.example.xxx.xxx with the package name from your manifest!
Intent notificationIntent = pm.getLaunchIntentForPackage("com.example.xxx.xxx");
PendingIntent contentIntent = PendingIntent.getActivity(getApplicationContext(), 0,
                                   notificationIntent, 0);
David Wasser
  • 93,459
  • 16
  • 209
  • 274
  • Okay so my MainActivity already has ACTION=MAIN and CATEGORY=DEFAULT in my manifest. Check. I have added the new flag. Check. When I open up my app, navigate to ActivityB for example, press the home button and then click the notification.... it still takes me back to my MainActivity.. Hmm.. Il put updated code into the question! – Murphybro2 May 19 '15 at 12:48
  • What I'm struggling to understand is how it can show any other activity other than the MainActivity if that's what's set in the Intent. Feel like it's never going to work if that's set like that.. – Murphybro2 May 19 '15 at 12:52
  • Wait. You may be seeing something else. Please do the following: Install your app. do NOT start your app. Go to the settings -> apps -> choose your app and force stop. Now return to HOME screen and start your app. Now navigate to ActivityB. Now return to HOME screen and click notification. This should take you to ActivityB. If not, please post your manifest. – David Wasser May 19 '15 at 13:24
  • No luck I'm afraid. Did it all exactly as you stated but still showed me MainActivity. It's so frustrating as pressing HOME then clicking the app icon does exactly what I want the notification to do.. wish I could see what Intent it was creating. I'll post manifest now. Thanks for all this help by the way. – Murphybro2 May 19 '15 at 13:42
  • Are you still setting `FLAG_ACTIVTY_CLEAR_TOP` and `FLAG_ACTIVITY_SINGLE_TOP`? If so, you need to get rid of those. That's what is causing your problem. – David Wasser May 19 '15 at 13:46
  • so I just looked in my manifest and realised my LoginActivity has ACTION=MAIN and CATEGORY=DEFAULT *doh!*.. I'll explain the structure a bit better in the edit – Murphybro2 May 19 '15 at 13:48
  • Added the manifest, and yes I had removed the two flags :) When I realised the LoginActivity was the MAIN I tried that instead, but it just creates a new one and overlays my MainActivity (as expected as it will have been destroyed) – Murphybro2 May 19 '15 at 14:00
  • You need to use `LoginActivity`, not `MainActivity`. I will add an alternative suggestion to my answer. – David Wasser May 19 '15 at 14:48
  • Ach, I also found the problem. I knew there was some strange bug here that I'd already investigated. See http://stackoverflow.com/a/16901603/769265 You need to add ACTION=MAIN and CATEGORY=LAUNCHER to make this work. However, if you use my alternative suggestion, the ACTION and CATEGORY are correctly set when you call `PackageManager.getLaunchIntentForPackage()` – David Wasser May 19 '15 at 15:00
  • Please see my updated code. Is that right? Getting confused now over which flags are necessary and which aren't! And what about the manifest, do i add the action and category to my MainActivity? Or have I misunderstood you.. – Murphybro2 May 19 '15 at 15:13
  • You don't need any additional flags. And you don't need to change the manifest at all. – David Wasser May 19 '15 at 15:58
0

I resolve this issue by saving top activity intent in onResume method of BaseActivity like below:

Intent currentActivityIntent = new Intent(this, getClass());
currentActivityIntent.addFlags(FLAG_ACTIVITY_NEW_TASK);
currentActivityIntent.addFlags(FLAG_ACTIVITY_SINGLE_TOP);
App.setCurrentActivityIntent(currentActivityIntent);

I get top activity intent after clicking on push.

All you need is to get intent of last top activity with the two flags FLAG_ACTIVITY_NEW_TASK and FLAG_ACTIVITY_SINGLE_TOP.

Birju Vachhani
  • 6,072
  • 4
  • 21
  • 43
Andrew
  • 1
  • 1