Receptor como clase interna en Android

En mi código hay una clase interna que extiende BroadcastReceiver .

Y agregué la siguiente línea al AndroidManifest.xml :

  

Pero estoy recibiendo el siguiente error:

incapaz de instanciar el receptor org.example.test.OuterClass $ InnerClass

¿Cómo puedo resolver este problema?

Una clase interna (no estática) no puede ser instanciada por Android a través de AndroidManifest.xml ( documentación del desarrollador de Android en BroadcastReceiver ):

Puede registrar dinámicamente una instancia de esta clase con Context.registerReceiver () o publicar de forma estática una implementación a través de la etiqueta en su AndroidManifest.xml.

Entonces puedes registrar dinámicamente el receptor. En mi aplicación, quería hacer lo mismo para usar la mensajería de nube a dispositivo de Google (C2DM) y mi AndroidManifest.xml original contenía:

             

Eliminé esa sección del receptor y registré dinámicamente el receptor de la siguiente manera:

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

La notación $ no denota una clase interna, sino una clase anidada estática. Entonces, en teoría hay 2 formas de resolver este problema en particular:

  1. Denomínala como una clase interna real, es decir, OuterClass.InnerClass (aunque no estoy seguro de si Android se comerá eso ya que la creación de instancias de una clase interna es bastante más compleja que hacer Class#newInstance() .

  2. Declare que la clase es una clase anidada estática, es decir, agregue static a la class InnerClass {} . De esta forma, OuterClass$InnerClass debe poder crear una nueva instancia a partir de él.

Si eso no resuelve el problema, aparentemente Android simplemente no lo come de esa manera. Me gustaría extraerlo en su propia clase independiente entonces.

Ver también:

  • Tutorial de Java – Clases anidadas
  • Responda con un ejemplo de código cómo crear una instancia de una clase anidada interna o estática utilizando la reflexión (como Android debería estar haciendo “debajo de las cubiertas”)

¿Podría ser que solo falta un punto y una cotización de cierre? Me gusta

  

Esto es lo que funcionó para mí:

 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:

   

no necesita usar $ … Si recibe una advertencia para una clase que no es realmente una clase interna, es porque está usando caracteres en mayúsculas en el nombre de su paquete , lo cual no es convencional.

Intenté también cambiar solo la primera letra del nombre del paquete en minúsculas, la advertencia y el error desaparecieron.

Acabo de conocer el mismo problema.

Tengo un servicio para comunicarme con muchas actividades, y también tengo un receptor en mi servicio como clase interna. cuando el receptor recibe un mensaje, debe llamar al método de servicio. así que sigue así:

1. Código de servicio:

 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. Registrar el receptor en manifest.xml: