Android,如何在C2DMReceiver构造函数中获取上下文?

时间:2012-04-23 09:54:50

标签: android android-c2dm android-context

我有一个C2DM接收器类,它在构造函数中初始化C2DM发送者电子邮件。 问题是,我需要从资源字符串中获取发件人电子邮件,因此我需要在接收器的构造函数中获取上下文

接收器看起来像这样

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 { ...

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;
    }
...

这与问题无关,但出于背景目的,需要这个的原因是代码在一个库项目中,该项目在许多android项目中使用,每个项目都有自己的发件人在资源文件中定义的电子邮件地址。 AppConstants类的工作是阅读各种资源字符串,然后从我接受的上一个问题的答案继续Android, Best way to provide app specific constants in a library project?

最后,为了完整性,AppConstants.getC2DMSender方法看起来像这样

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

用户此库的特定应用程序负责在xml资源中设置c2dm_sender变量。所以为了得到这个变量我需要上下文

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

因为这是在资源字符串中设置的,所以特定应用可以设置此值,模板将自动使用它。

4 个答案:

答案 0 :(得分:2)

将单件类添加到库中。让一个成员持有senderid和相应的getter和setter方法......

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;
   }

}

在您应用的活动中ClassicSingleton.getInstance().setSender("SENDER_ID")

在您的C2DM课程中

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

尝试将应用的上下文作为成员而不是senderId。然后你可以拉出你需要的任何资源我猜..让我知道。

答案 1 :(得分:1)

我得出的结论是,这不能按照我的尝试方式完成。 我暂时通过在每个应用程序中创建一个新类来解决我的问题,该类来自库项目中的类,并且只是覆盖每个应用程序中的构造函数。

这不是一个想法的解决方案,有点挫败了拥有一个库,但至少我可以分享我的大部分代码。

答案 2 :(得分:1)

C2DMBaseReceiver实际上并不使用senderId,除非它需要重试注册请求。 C2DMBaseReceiver是一个对象(IntentService),它为每个操作创建和销毁(注册响应,来自服务器的消息,并重新注册)。只要你在注册前设置senderId,你应该没事。

这似乎有效:

public class C2DMReceiver extends C2DMBaseReceiver {
    private static String gSenderId = "dummy";

    public C2DMReceiver() {
        super(gSenderId);
    }

    public static void register(Context context, String senderId) {
        gSenderId = senderId;
        C2DMessaging.register(context, senderId);
    }

    ...
}

由于您正在创建一个提供C2DM服务的库,您应该考虑@fargath所说的内容并将c2dm.jar函数直接合并到您的库中。然后,您可以根据需要自定义界面。此外,c2dm.jar提供了库代码的间接,然后您的库代码提供了与应用程序等效的间接。这有点浪费。

c2dm.jar代码只有三个短文件。我正在编写一个类似于你的库,可能会自行提取功能。

答案 3 :(得分:0)

//As C2DMReceiver receiver extends Intent service, rather than passing this , call getApplicationConext 

public class C2DMReceiver extends C2DMBaseReceiver {

public C2DMReceiver() {
    Context context = getApplicationContext();
    super(AppConstants.getC2DMSender(context); // This way you can pass context.
}

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