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

ライブラリにシングルトンクラスを追加します。送信者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ではなくメンバーとして使用するようにしてください。次に、必要なリソースを取得できます。私に知らせてください。

于 2012-05-02T09:15:46.663 に答える
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 つの短いファイルのみです。私はあなたのものに似たライブラリを書いていますが、おそらく自分で機能を引き出すでしょう。

于 2012-05-06T05:06:01.177 に答える
1

これは、私が試みていた方法では実行できないという結論に達しました。ライブラリプロジェクトのクラスから派生した各アプリに新しいクラスを作成し、各アプリのコンストラクターをオーバーライドすることで、問題を一時的に解決しました。

これはアイデアの解決策ではなく、ライブラリを持つという点を無効にしますが、少なくともコードのほとんどを共有できます。

于 2012-05-02T01:41:34.757 に答える
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 に答える