1

我有一个 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

4 回答 4

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。然后你可以提取你需要的任何资源我猜..让我知道。

于 2012-05-02T09:15:46.663 回答
1

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

这不是一个想法解决方案,有点违背了拥有图书馆的意义,但至少我可以分享我的大部分代码。

于 2012-05-02T01:41:34.757 回答
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 代码只有三个短文件。我正在编写一个与您的库类似的库,并且可能会自己提取功能。

于 2012-05-06T05:06:01.177 回答
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 { ...
于 2012-04-25T23:08:28.867 回答