0

I have a BroadcastReceiver inside a service:

public class NotificationClickService extends Service {

    private static final String DEBUG_TAG = "NotificationClickService";

    @Override
    public IBinder onBind(Intent intent) {
        // TODO Auto-generated method stub
        return null;
    }

    @Override
    public void onCreate() {
        registerReceiver(NotificationClickReceiver, new IntentFilter(DownloadManager.ACTION_NOTIFICATION_CLICKED));
    }

    @Override
      public void onDestroy() {
        unregisterReceiver(NotificationClickReceiver);
    }

    BroadcastReceiver NotificationClickReceiver = new BroadcastReceiver() {

        @Override
        public void onReceive(Context context, Intent intent) {
            Log.d(DEBUG_TAG, "NotificationClickReceiver: onReceive CALLED");

                Intent i = new Intent(android.app.DownloadManager.ACTION_VIEW_DOWNLOADS);
                i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | 
                        Intent.FLAG_ACTIVITY_SINGLE_TOP | 
                        Intent.FLAG_ACTIVITY_CLEAR_TOP | 
                        Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
                context.startActivity(i);
        }
    };
}

This brings the system Download Manager to the front.

On my phone I'm running CyanogenMod 10.1 based on JellyBean.

But...

As soon as the system app CMupdater starts:

  • if CMupdater is currently running, it is called from my service's BroadcastReceiver, instead of the DownloadManager;
  • if CMupdater is not running, but has ran at least once, my receiver is not called at all.

It works again if I reboot and don't run the updater. All tested also on my tablet with the corresponding CyanogenMod 10.1 version.

This is from the CM's receiver:

package com.cyanogenmod.updater.receiver;

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;

import com.cyanogenmod.updater.UpdatesSettings;

public class NotificationClickReceiver extends BroadcastReceiver{
     private static String TAG = "NotificationClickReceiver";

     @Override
     public void onReceive(Context context, Intent intent) {

         // Bring the main app to the foreground
         Intent i = new Intent(context, UpdatesSettings.class);
         i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_SINGLE_TOP |
                 Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
         context.startActivity(i);
     }
 }

and from its manifest:

    <receiver android:name="com.cyanogenmod.updater.receiver.NotificationClickReceiver">
        <intent-filter>
            <action android:name="android.intent.action.DOWNLOAD_NOTIFICATION_CLICKED"/>
            <category android:name="android.intent.category.HOME"/>
        </intent-filter>
    </receiver>

android.intent.action.DOWNLOAD_NOTIFICATION_CLICKED is the constant value for the DownloadManager.ACTION_NOTIFICATION_CLICKED intent I used.

dentex
  • 3,223
  • 4
  • 28
  • 47
  • "if it's currently running, it's called from my service's BroadcastReceiver, instead of the DownloadManager" What's running? What's called? – Mister Smith Feb 25 '13 at 14:04
  • question edited. I hope it's clearer now. – dentex Feb 25 '13 at 14:10
  • Ok, thanks for the clarification. So you are registering a receiver with the action `ACTION_NOTIFICATION_CLICKED`. When the user clicks on a download, every receiver will be notified. This means yours and also every other one. Have you checked the receiver is actually not being called? Perhaps the problem has to do with the new activity launch flags other than the receiver itself. – Mister Smith Feb 25 '13 at 14:32
  • thanks to you for the comment: yes, the receiver is called (I removed the Log.d() calls from the code above). it is called but not "executed". `FLAG_ACTIVITY_NEW_TASK` is mandatory due to an exception otherwise thrown. – dentex Feb 25 '13 at 14:41
  • emendament: my receiver is not called at all (if CMupdater has ran before). editing the question. – dentex Feb 25 '13 at 14:47
  • Try commenting the `setFlags` line. – Mister Smith Feb 25 '13 at 14:52
  • FLAG_ACTIVITY_NEW_TASK is mandatory due to an exception otherwise thrown. After reboot, when my receiver is actually called: `RuntimeException: Error receiving broadcast Intent... Caused by: android.util.AndroidRuntimeException: Calling startActivity() from outside of an Activity context requires the FLAG_ACTIVITY_NEW_TASK flag. Is this really what you want?` I tried removing the other flags except this one. Then I started CMupdater. No effect. Receiver not called again. – dentex Feb 25 '13 at 15:29
  • Is CMUpdater somehow replacing the default download manager in that ROM? I mean, is the normal download manager still installed or there's only CMUpdater? – Mister Smith Feb 25 '13 at 15:35
  • BTW, CMUpdater seems it is no longer maintained, and I can't find that receiver in [the manifest](http://code.google.com/p/cyanogen-updater/source/browse/trunk/AndroidManifest.xml) (I know, this does not solve the problem, just saying) – Mister Smith Feb 25 '13 at 15:43
  • yes the standard DownloadManager is present. About maintenance, I don't know. It's included in nightlies updates, and it seems that a commit occurred 9 days from now... – dentex Feb 25 '13 at 16:10

2 Answers2

0

While I'm still having trouble deciphering your question, I can't see how your receiver would have ever been called. You are missing the category registration in your intent filter.

Try:

IntentFilter filter = new IntentFilter(DownloadManager.ACTION_NOTIFICATION_CLICKED); 
filter.addCategory(Intent.CATEGORY_HOME);
registerReceiver(NotificationClickReceiver, filter);

That should ensure that you always receive the same broadcasts as the manifest registered receiver.

Justin Breitfeller
  • 13,737
  • 4
  • 39
  • 47
  • What's not clear? I'll edit the question; anyway, this is all about a receiver that works only if a system updater has never ran before. And yes, I see `Intent.CATEGORY_HOME` in the CMupdater... in the emulator works without `Intent.CATEGORY_HOME`. I'm going to try adding this, and see if it works on the phone. – dentex Feb 25 '13 at 14:25
  • Are you sure your receiver is actually registered? IF you put logs into your onCreate and onDestroy you should see whether or not your service is actually running. – Justin Breitfeller Feb 25 '13 at 14:52
  • `Log.d(DEBUG_TAG, "service created")` yes I see this Log from `onCreate()` – dentex Feb 25 '13 at 15:04
  • 1
    These problems would imply a missing permission / package filtered intent, but that would have prevented this from ever working (which you say it does work before the updater is open). The symptoms point to an ordered broadcast that is aborted by a receiver with higher priority, but the posted code doesn't show that either. There is nothing else to prevent broadcasts from reaching you. – Justin Breitfeller Feb 26 '13 at 18:07
0

All matching BroadcastRecievers will be notified, with their appropriate Context. Note that this can happen in two ways:

  1. If a Receiver is locally created in code and registered, inside some object, it will be called only if that object is around.

  2. If an Reciever is declared in manifest, that object will be created and onReceive() method will be called.

So, you can have Service class implement BroadCastReciever, declare it in Manifest file, and start your service form its onRecieve();

S.D.
  • 29,290
  • 3
  • 79
  • 130