tags:

views:

274

answers:

3

I would like to show a notification that displays the progress of an ongoing operation. That works well for me. But at the same time the remote view should contain cancel button to stop the ongoing operation. The usual content intent should still do something else, i.e. not cancel the ongoing operation. It seems though that I can only have one intent.

I have to specify a contentIntent that is launched when clicking on the notification: If I don't specify that I get something along those lines:

E/ActivityManager(   62): Activity Manager Crash
E/ActivityManager(   62): java.lang.IllegalArgumentException: contentIntent required ...

For the "cancel" button I set another intent:

Intent cancelSyncIntent = new Intent("com.xyz.CANCEL_SYNC");
contentView.setOnClickPendingIntent(R.id.cancel_sync,
                                    PendingIntent.getBroadcast(context, 0,
                                    cancelSyncIntent, 0));

But this never works. I always get the content intent when the button is clicked. It looks like I cannot use buttons in remote views of notifications?!

I could probably display a text: "<< Press to cancel operation >>", but that seems rather heavy handed.

Update: Afer J.'s recommendations:

    final Notification n = new Notification(R.drawable.gen_auto_notification_icon, context.getResources()
            .getString(
                    fastSyncOnly ? R.string.fast_synchronization_running_notification_title
                            : R.string.synchronization_running_notification_title), new Date().getTime());

    n.flags = Notification.FLAG_ONGOING_EVENT;

    final RemoteViews contentView = new RemoteViews(context.getPackageName(), R.layout.in_progress_notification);
    n.contentView = contentView;

    // Intent cancelSyncIntent = new Intent("com.newsrob.CANCEL_SYNC");
    Intent cancelSyncIntent = new Intent();
    cancelSyncIntent.setClass(context, FireReceiver.class);
    PendingIntent pendingCancelSyncIntent = PendingIntent.getActivity(context, 0, cancelSyncIntent, 0);
    contentView.setOnClickPendingIntent(R.id.cancel_sync, pendingCancelSyncIntent);

    Intent showDashboardIntent = new Intent(context, DashboardListActivity.class);
    PendingIntent showDashboardPendingIntent = PendingIntent.getActivity(context, 0, showDashboardIntent, 0);
    n.contentIntent = showDashboardPendingIntent;
A: 

Hi Mariano try this...

    Intent cancelSyncIntent = new Intent();
    cancelSyncIntent .setClassName("com.xyz","com.xyz.CANCEL_SYNC");

PendingIntent pendingIntent = PendingIntent.getActivity(context,
    0 /* no requestCode */, cancelSyncIntent , 0 /* no flags */);
contentView.setOnClickPendingIntent(R.id.cancel_sync, pendingIntent);
Jorgesys
Thanks J.Are you sure it works that way? I tries, see above, but still when tapping on "Cancel" I only get the showDashboardIntent.
Mariano Kamp
A: 

Hi Mariano, I posted a similar question and am waiting for answers... I've been fiddling with J's answer and your sample code with no luck.

HTC's sense has managed a during-call notification which has a functioning button to end the call and pressing anywhere outside the button does not "highlight" the notification but an intent to return to the call screen is executed.

I need this functionality and I hope someone finds the answer soon... :(

sisedi
+1  A: 

Short answer: You cannot have clickable child views in a notification view.

Longer answer...

I spent a day trying to get this to work as well and eventually gave up and looked at the Android source. It looks like everything happens in makeNotificationView() within StatusBarService.java. In there, the code inflates a layout named "status_bar_latest_event" for each row in the notification pull down shade. It grabs a ViewGroup from that view it just inflated named "content", calls setDescendantFocusability(ViewGroup.FOCUS_BLOCK_DESCENDANTS) on it, and then adds your notification view as a child of that. So, assuming I understand how FOCUS_BLOCK_DESCENDANTS works, it appears there is no hope of your view or any of its children getting focus or click events.

I also followed the logic of how the main PendingEvent that you associate with your Notification works. The same ViewGroup that hosts your Notification view gets a setOnClickListener() call on it to register a listener class named "Launcher". When that class gets an onClick() event, it simply calls the send() method on the PendingIntent you associated with the Notification. I was hoping maybe the coordinate of the click might get passed along so I could at least attempt to compute which button was clicked on, but no such luck.

Anyway, if anyone knows of a way to work around this, I'd love to hear it. For now, I'm just pulling my buttons out and moving on.

Steve