13

Our app has different notifications that can open different Activities. So we created the URI scheme to do so. The Notifications are received and open the correct activities. I create the stack for proper navigation with the following code:

Intent intent = new Intent(Intent.ACTION_DEFAULT, Uri.parse(uri));

TaskStackBuilder stackBuilder = TaskStackBuilder.create(context);
stackBuilder.addNextIntentWithParentStack(intent);

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

NotificationManager mNotifM = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
Notification.Builder mBuilder = new Notification.Builder(context);
mNotifM.notify(NotificationId.getID(), mBuilder.setStyle(new    Notification.BigTextStyle(mBuilder)
            .bigText(bigText)
            .setBigContentTitle(title)
            .setSummaryText(summaryText))
            .setContentTitle(title)
            .setSmallIcon(R.drawable.udechile_launcher)
            .setContentText(summaryText)
            .setAutoCancel(true)
            .setContentIntent(contentIntent)
            .setTicker(bigText)
            .build());

The problem is that in Android 4.1.1 that code to recreate the stack does not work properly. The only way I made it work is referecing the class instead of the uri when creating the intent:

intent = new Intent(context, MatchDetail.class);

The problem with this is that I will have to do a Switch-Case for every uri to be able to create the intent with each class. This defeats the purpose of the URI in the first place. Also if in the future I need to add a new Push Target is not just adding the URI in the AndroidManifest.xml I have to add a new case in the switch of the Push Notification Receiver.

Does somebody knows how to make this work in Android 4.1.1 with URIs?

Extract of Manifest:

<activity
        android:name=".controller.MatchDetail"
        android:label="@string/title_activity_match_detail"
        android:parentActivityName=".controller.MainActivity" >
        <meta-data
            android:name="android.support.PARENT_ACTIVITY"
            android:value=".controller.MainActivity" />
        <intent-filter>
            <action android:name="android.intent.action.VIEW" />
            <category android:name="android.intent.category.DEFAULT" />
            <category android:name="android.intent.category.BROWSABLE"/>
            <data android:scheme="scheme" android:host="base" android:path="/name" />
        </intent-filter>
    </activity>
Franklin
  • 881
  • 1
  • 8
  • 28
  • What is stopping you from using the code on previous APIs? Are you saying the `new Intent(Intent.ACTION_DEFAULT, Uri.parse(uri));` isn't working or you're having a problem with the rest of the code? – ianhanniballake May 01 '15 at 17:46
  • The uri worked but when I hit back the app closes with 4.1.1 and it works with android > 4.2.2. Same code – Franklin May 01 '15 at 18:16
  • Assuming you are using the Support Library version of [TaskStackBuilder](http://developer.android.com/reference/android/support/v4/app/TaskStackBuilder.html), there's nothing different from Android 3.0+ on how the parent stack is being built that would cause 4.1.1 to work differently from 4.2.2. Can you include the Activity manifest entry for one of the activities that isn't working? – ianhanniballake May 01 '15 at 18:26
  • Edited my response to include the Android Manifest – Franklin May 01 '15 at 19:03

1 Answers1

1

I haven't tried this yet, but this could possibly fix your problem:

TaskStackBuilder stackBuilder = TaskStackBuilder.create(context);
stackBuilder.addParentStack(Class.forName(intent.getComponent().getClassName()));
stackBuilder.addNextIntent(intent);

If that doesn't work, try this:

TaskStackBuilder stackBuilder = TaskStackBuilder.create(context);
stackBuilder.addNextIntent(context, Class.forName(intent.getComponent().getClassName()));
stackBuilder.addNextIntent(intent);

Also one more to try:

TaskStackBuilder stackBuilder = TaskStackBuilder.create(context);
stackBuilder.addNextIntentWithParentStack(new Intent(context, Class.forName(intent.getComponent().getClassName())));

Edit

Found a new way that might work, hopefully

TaskStackBuilder stackBuilder = TaskStackBuilder.create(context);
stackBuilder.addParentStack(new ComponentName(context, Class.forName(intent.getComponent().getClassName())));
stackBuilder.addNextIntent(intent);
Kevin van Mierlo
  • 9,554
  • 5
  • 44
  • 76
  • Neither of the three solutions worked. It makes sense because we are never setting the component. The documentation says: "Retrieve the concrete component associated with the intent. When receiving an intent, this is the component that was found to best handle it (that is, yourself) and will always be non-null; *in all other cases it will be null unless explicitly set.*" – Franklin May 13 '15 at 15:51
  • @Franklin I don't know if this will work, but I added another answer that will hopefully work. I'm just trying to find another way to get the parent from an `Intent`. – Kevin van Mierlo May 14 '15 at 18:57
  • The problem is when we do: intent.getComponent. That is null because we do not create this component. – Franklin May 14 '15 at 18:59
  • @Franklin Hmm, I don't really know if I have another answer. But I'll keep looking! – Kevin van Mierlo May 14 '15 at 19:02
  • @Franklin one more question, what kind of information do you get from the uri? – Kevin van Mierlo May 14 '15 at 19:03
  • The URI tells which activity the app has to open for that Push – Franklin May 14 '15 at 19:36
  • @Franklin is there anything else like package name : `com.test.test.MainActivity` or can you send that with the notification? Cause then you can create a `ComponentName` and perhaps retrieve the parent using that – Kevin van Mierlo May 14 '15 at 20:01