web-dev-qa-db-ja.com

Androidの内部クラスとしてのレシーバー

私のコードには、BroadcastReceiverを拡張する内部クラスがあります。

そして、AndroidManifest.xmlに次の行を追加しました。

<receiver Android:name="OuterClass$InnerClass Android:enabled="true"/>

しかし、次のエラーが発生します。

レシーバーorg.example.test.OuterClass $ InnerClassをインスタンス化できません

この問題を解決するにはどうすればよいですか?

20
Kunal P.Bharati

(非静的) 内部クラス は、AndroidManifestを介してAndroid .xml( BroadcastReceiverに関するAndroid開発者向けドキュメント ):

このクラスのインスタンスをContext.registerReceiver()に動的に登録するか、AndroidManifest.xmlのタグを介して実装を静的に公開できます。

したがって、レシーバーを動的に登録できます。私のアプリケーションでは、GoogleのCloud to Device Messaging(C2DM)を使用するために同じことをしたいと思っていましたが、元のAndroidManifest.xmlには次のものが含まれていました。

<application...>
    <receiver Android:name=".MyC2dmReceiver" Android:permission="com.google.Android.c2dm.permission.SEND">
        <intent-filter>
            <action Android:name="com.google.Android.c2dm.intent.RECEIVE" />
            <category Android:name="com.example.myapp" />
        </intent-filter>
        <intent-filter>
            <action Android:name="com.google.Android.c2dm.intent.REGISTRATION" />
            <category Android:name="com.example.myapp" />
        </intent-filter>
    </receiver>
</application>

そのreceiverセクションを削除し、次のようにレシーバーを動的に登録しました。

public class AndroidService extends IntentService
{
    ... 
    @Override
    public int onStartCommand(Intent intent, int flags, int startId)
    {
        IntentFilter filter = new IntentFilter();
        filter.addAction("com.google.Android.c2dm.intent.RECEIVE");
        filter.addAction("com.google.Android.c2dm.intent.REGISTRATION");
        filter.addCategory("com.example.myapp");
        this.registerReceiver(new MyC2dmReceiver(), filter, "com.google.Android.c2dm.permission.SEND", null);
        return super.onStartCommand(intent,flags,startId);
    }

    public class MyC2dmReceiver extends BroadcastReceiver
    {
        ...
    }
}
32
Bert Regelink

_$_表記は、内部クラスではなく、静的にネストされたクラスを示します。したがって、理論的には、この特定の問題を解決する2つの方法があります。

  1. それを実際の内部クラス、つまり_OuterClass.InnerClass_として示します(内部クラスのインスタンス化はClass#newInstance()を実行するよりもかなり複雑なので、Androidがそれを食べるかどうかはわかりません。 。

  2. 代わりに、クラスを静的なネストされたクラスとして宣言します。つまり、staticを_class InnerClass {}_に追加します。このようにして、_OuterClass$InnerClass_はそれから新しいインスタンスを作成できなければなりません。

それでも問題が解決しない場合は、明らかにAndroidは単にそのように食べていません。次に、それを独自のスタンドアロンクラスに抽出します。

参照:

17
BalusC

ドットと終了引用符だけが欠落している可能性がありますか?お気に入り

<receiver Android:name=".OuterClass$InnerClass" Android:enabled="true"/>
7
DonGru

これは私のために働いたものです:

public class OuterClass {
    public static class InnerStaticClass extends BroadcastReceiver {
        @Override
        public void onReceive(final Context context, final Intent intent) {
            final Location location = (Location) intent.getExtras().get(LocationClient.KEY_LOCATION_CHANGED);
        }
    }
}

AndroidManifest.xml:

    <receiver Android:name=".OuterClass$OuterClassConnector$InnerStaticClass" />
4
Gavriel

私はちょうど同じ問題に遭遇しました。

私は多くの活動と通信するサービスを持っています、そして私はまた私のサービスの内部クラスとして受信機を持っています。受信者がメッセージを受け取ると、サービスのメソッドを呼び出す必要があります。だからそれはこのように続きます:

1。サービスコード:

public class XXService extends Service{

     // I want the inner receiver call the methd of XXService,
    // so I have to write this constructor like this.

    private XXService instance;
    public XXService(){instance = this;}
    public XXService getInstance(){
       return instance;
    }
    public void sayHello(){
    }
    public static class XXReceiver extends BroadcastReceiver{

        onReceive(......){
            XXService.getInstance.sayHello();
        } 
   }
}

2。レシーバーをmanifest.xmlに登録します:

<receiver Android:name=".XXService$XXReceiver" Android:enabled="true"/>
0
River

$ ...を使用する必要はありません。実際には内部クラスではないクラスに対して警告が表示された場合は、使用しているためですパッケージ名の大文字、これは従来のものではありません。

パッケージ名の最初の文字だけを小文字に変更しようとしましたが、警告とエラーが消えました。

0
MBH