Search code examples
androidandroid-c2dmandroid-context

Android, How to get context in C2DMReceiver constructor?


I have a C2DM receiver class that initialises the C2DM sender email in the constructor. The thing is, I need to get the senders email from a resource string and therefore I need to get the context in the constructor for the receiver

The receiver looks like this

public class C2DMReceiver extends C2DMBaseReceiver {

    public C2DMReceiver() {
        super(AppConstants.getC2DMSender(this)); // How do I get the context here?
    }

    @Override
    public void onRegistered(Context context, String registrationId)
            throws java.io.IOException { ...

The relevant code on the C2DMBaseReceiver

public abstract class C2DMBaseReceiver extends IntentService {
...
    private final String senderId;

    /**
     * The C2DMReceiver class must create a no-arg constructor and pass the 
     * sender id to be used for registration.
     */
    public C2DMBaseReceiver(String senderId) {
        // senderId is used as base name for threads, etc.
        super(senderId);
        this.senderId = senderId;
    }
...

It's not really relevant to the question but for background purposes the reason for needing this is that the code is in a library project that is used in many android projects each of which has it's own sender's email address defined in a resource file. The AppConstants class has the job of reading the various resource strings and follows on from my accepted answer for a previous question here Android, Best way to provide app specific constants in a library project?

Finally for completeness the AppConstants.getC2DMSender method looks like this

public static String getC2DMSender(Context c){
    return c.getResources().getString(uk.co.the_prize_quiz.quiz_template.R.string.c2dm_sender);
}

The specific app that users this library has the responsibility of setting the c2dm_sender variable in an xml resource. So in order to get this variable I need the context

<item type="string" name="c2dm_sender" format="string">app_specific_registered_c2dm@email_address</item>

Because this is set in a resource string the specific app can set this value and the template will use it automatically.


Solution

  • Add a singleton class to your library. Have a member to hold the senderid and corresponding getter and setter methods...

    public class ClassicSingleton {
       private static ClassicSingleton instance = null;
       private String mSenderId = nulll; // Your data holder
    
       protected ClassicSingleton() {
          // Exists only to defeat instantiation.
       }
    
       public static ClassicSingleton getInstance() {
          if(instance == null) {
             instance = new ClassicSingleton();
          }
          return instance;
       }
    
       /* Setter and Getter for the mAppContext member here */
       public void setSender(String sender) {
           mSenderId = sender;
       }
    
    }
    

    In your app's activity ClassicSingleton.getInstance().setSender("SENDER_ID")

    In your C2DM class

    public C2DMReceiver() {
        super(ClassicSingleton.getInstance().getSender());
    }
    

    Try to have the app's context as the member instead of senderId. Then you can pull any resource you need I guess.. Let me know.