2012-04-23 42 views
1

我有一個C2DM接收器類,它在構造函數中初始化C2DM發送者電子郵件。 的事情是,我需要從資源字符串獲得發件人的電子郵件,因此我需要在構造背景下的接收器Android,如何在C2DMReceiver構造函數中獲取上下文?

接收器看起來像這樣

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">[email protected]_address</item> 

因爲這是在資源字符串設定具體的應用程序可以設置這個值和模板會自動使用它。

+1

如果您在圖書館項目中發現任何複雜情況以獲取上下文,可以將這些文件或包複製到您的項目中並根據需要進行更改。 – fargath 2012-04-23 11:54:05

+0

沒有意識到可以完成,我可能只需要這樣做,但我真的不想,除非沒有其他選擇。感謝您的信息 – jamesc 2012-04-23 11:59:37

+0

您打算如何處理不同發件人電子郵件的不同包裹?註冊C2DM時,您需要指定一個請求的發件人電子郵件以及您的應用程序包。該包由C2DM用於調用您的C2DMReceiver類(在清單中定義),您確定在您能夠在構造函數中正確設置電子郵件時正確調用此類嗎? – marmor 2012-04-30 07:55:35

回答

2

將單例類添加到您的庫中。有一個部件保持Sender ID和相應的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。那麼你可以拉我需要的任何資源,我想..讓我知道。

+0

我已經接受了答案,但我沒有時間去嘗試,我會回到你後來感謝你的毅力 – jamesc 2012-05-02 15:20:28

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

這不起作用,我得到2錯誤,說隱式超級構造函數C2DMBaseReceiver()是未定義的。必須顯式調用另一個構造函數AND構造函數調用必須是構造函數中的第一個語句,謝謝回覆,儘管 – jamesc 2012-04-26 06:21:00

+0

@jamesw試試這個'super(AppConstants.getC2DMSender(getApplicationContext()));' – Ronnie 2012-05-01 16:39:01

+0

@ userSeven7s謝謝你的建議,給我一個錯誤「不能在明確調用構造函數時引用實例方法」 – jamesc 2012-05-02 01:14:51

1

我得出的結論是,這不能以我嘗試的方式完成。 我暫時通過在每個應用程序中創建一個新類來解決我的問題,這個應用程序從庫項目中的類繼承而來,並且僅覆蓋每個應用程序中的構造函數。

這不是一個想法的解決方案,有點像一個庫,但至少我可以分享我的大部分代碼。

+0

我也認爲它不能按照你想要的方式完成。但您仍然可以嘗試 - 在庫中擁有一個包含註冊到C2DM所需數據的類。在註冊之前將這些數據設置在您的活動中。你將不得不做靜態引用。 – Ronnie 2012-05-02 04:37:41

+0

@ userSeven7s我很想嘗試這個選項。如果你願意去回答一個建議的代碼示例,說明如何做到這一點,我會很感激 – jamesc 2012-05-02 06:12:42

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代碼只有三個短文件。我正在寫一個類似於你的庫,並可能會在我自己的功能。

+0

謝謝你的迴應。我不願意改變這種間接性,儘管我之前已經考慮過這個問題,但依據「如果有效,請不要修復」。我發現一個解決方案能很好地滿足我的需求,這個解決方案基於我接受的答案,只使用應用程序單例而非自定義單例,這非常有效。然而,你提供了許多想法,可能還有更好的解決方案。現在我有一個工作庫的時間限制意味着我需要繼續前進,但事實是我有一個庫允許我在有時間的情況下進行重構。謝謝 – jamesc 2012-05-06 06:41:50

相關問題