2011-10-12 19 views
8

No se puede registrar el receptor dinámicamente durante el arranque. No tengo actividad Y no quiero registrarlo en el servicio.No se puede registrar el receptor dinámicamente

Receptor de arranque, donde me registro otro receptor:

package zzz.zzz.zzz; 
import android.content.BroadcastReceiver; 
import android.content.Context; 
import android.content.Intent; 
import android.content.IntentFilter; 

public class AutoStart extends BroadcastReceiver 
{ 
    @Override 
    public void onReceive(Context context, Intent intent) 
    { 
     if ((intent.getAction() != null) && (intent.getAction().equals("android.intent.action.BOOT_COMPLETED"))) 
     { 
      IntentFilter filter = new IntentFilter(Intent.ACTION_SCREEN_ON); 
      filter.addAction(Intent.ACTION_SCREEN_OFF); 
      BroadcastReceiver mReceiver = new ScreenReceiver(); 
      context.registerReceiver(mReceiver, filter); 
     } 
    } 
} 

receptor que yo quiero registrar:

package zzz.zzz.zzz; 
import android.content.BroadcastReceiver; 
import android.content.Context; 
import android.content.Intent; 

public class ScreenReceiver extends BroadcastReceiver 
{ 
    @Override 
    public void onReceive(Context context, Intent intent) 
    { 
     if (intent.getAction().equals(Intent.ACTION_SCREEN_OFF)) 
     { 
      // some code    
     } 
     if (intent.getAction().equals(Intent.ACTION_SCREEN_ON)) 
     { 
      // some code   
     } 
    } 
} 

LogCat:

10-12 15:03:45.849: ERROR/AndroidRuntime(240): Uncaught handler: thread Thread-8 exiting due to uncaught exception 
10-12 15:03:45.859: ERROR/AndroidRuntime(240): android.content.ReceiverCallNotAllowedException: IntentReceiver components are not allowed to register to receive intents 
10-12 15:03:45.859: ERROR/AndroidRuntime(240):  at android.app.ReceiverRestrictedContext.registerReceiver(ApplicationContext.java:126) 
10-12 15:03:45.859: ERROR/AndroidRuntime(240):  at android.app.ReceiverRestrictedContext.registerReceiver(ApplicationContext.java:120) 
10-12 15:03:45.859: ERROR/AndroidRuntime(240):  at zzz.zzz.zzz.RegisterReceiver$1.run(RegisterReceiver.java:18) 
10-12 15:03:46.159: ERROR/ContactsProvider(98): Cannot determine the default account for contacts compatibility 
10-12 15:03:46.159: ERROR/ContactsProvider(98): android.accounts.AuthenticatorException: bind failure 
10-12 15:03:46.159: ERROR/ContactsProvider(98):  at android.accounts.AccountManager.convertErrorToException(AccountManager.java:1096) 
10-12 15:03:46.159: ERROR/ContactsProvider(98):  at android.accounts.AccountManager.access$500(AccountManager.java:74) 
10-12 15:03:46.159: ERROR/ContactsProvider(98):  at android.accounts.AccountManager$BaseFutureTask$Response.onError(AccountManager.java:1003) 
10-12 15:03:46.159: ERROR/ContactsProvider(98):  at android.accounts.IAccountManagerResponse$Stub.onTransact(IAccountManagerResponse.java:69) 
10-12 15:03:46.159: ERROR/ContactsProvider(98):  at android.os.Binder.execTransact(Binder.java:287) 
10-12 15:03:46.159: ERROR/ContactsProvider(98):  at dalvik.system.NativeStart.run(Native Method) 
10-12 15:03:46.879: ERROR/MediaPlayerService(31): Couldn't open fd for content://settings/system/notification_sound 
10-12 15:03:46.889: ERROR/MediaPlayer(52): Unable to to create media player 
+0

Havent ha visto un nombre de paquete así! :) – prijupaul

Respuesta

13

La respuesta está en el mensaje de error: IntentReceiver components are not allowed to register to receive intents. No puede registrar un BroadcastReceiver nuevo en un BroadcastReceiver existente.

+0

¡Oh sí! ¡tienes razón! Gracias – XXX

1

¿no puedes registrar esto en el manifiesto?

+1

No. No funciona desde manifiesto. http://stackoverflow.com/questions/1588061/android-how-to-receive-broadcast-intents-action-screen-on-off – XXX

+3

puede ser que pueda iniciar un servicio que puede registrar un BroadcastReceiver. Además, puede estar llamando a context.getApplicationContext() podría funcionar – njzk2

+1

Sí, tiene razón. Soled este problema con el servicio. ¡Gracias! – XXX

5

me han puesto en marcha el servicio en ACTION_BOOT_COMPLETED como

@Override 
public void onReceive(Context context, Intent intent) { 

    Log.d("BootReceiver", "onReceive() intent: " + intent.getAction()); 

    if (intent.getAction() != null) { 

     // Boot completed 
     if (intent.getAction().equals(Intent.ACTION_BOOT_COMPLETED)) { 
      if(!isMyServiceRunning(context)){ 
       startTheService(context); 
      } 
     } 

que va a crear mi solicitud detrás de la escena:

public class MyApplication extends Application 

y no tengo anular el onCreate:

@Override 
public void onCreate() { 
    super.onCreate(); 
    Log.d("MyApplication", "registering for screen states"); 
    registerClassBecauseManifestIsNotEnough(getApplicationContext()) ; 
} 

private void registerClassBecauseManifestIsNotEnough(Context context) { 
    IntentFilter intentFilter = new IntentFilter(Intent.ACTION_SCREEN_ON); 
    intentFilter.addAction(Intent.ACTION_SCREEN_OFF); 
    BroadcastReceiver mReceiver = new ScreenStateBroadcastReceiver();  
    context.registerReceiver(mReceiver, intentFilter); 
} 

Problema resuelto para mí, al menos.

1

Para Reproductor necesitaba una solución. Así es como he resuelto:

private static boolean isRegisteredFromCode = false; 
    @Override 
    public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) { 

     for (int i = 0; i < appWidgetIds.length; ++i) { 
      RemoteViews layout = buildLayout(context, appWidgetIds[i]); 
      appWidgetManager.updateAppWidget(appWidgetIds[i], layout); 
     } 
     super.onUpdate(context, appWidgetManager, appWidgetIds); 

     if(!isRegisteredFromCode){ 
      isRegisteredFromCode = true; 
      context.getApplicationContext().registerReceiver(this, new IntentFilter(Intent.ACTION_SCREEN_OFF)); 
      context.getApplicationContext().registerReceiver(this, new IntentFilter(Intent.ACTION_SCREEN_ON)); 
     }  
    } 

Widget es un BroadcastReceiver ...

0

Una solución bastante fácil lanza los nuevos servicios en un hilo separado:

public class BootServiceReceiver extends BroadcastReceiver {  

    @Override 
    public void onReceive(Context context, Intent intent) { 
     // Launcher is a Singleton. 
     // Note that you pass it context.getApplicationContext() as parameter 
     final Launcher launcher=Launcher.get(context.getApplicationContext()); 
     new Thread(new Runnable() { 

      @Override 
      public void run() { 
       launcher.doActions(); 
      } 
     }).start(); 
    } 
} 

En el Lanzador tenemos :

public class Launcher { 
    private static Launcher instance; 
    private Context ctx; 
    private BroadcastReceiver receiver1, receiver2; 

    private Launcher(Context ctx) { 
     this.ctx=ctx; 
    } 

    public static Launcher get(Context ctx) { 
     if (yo==null) 
      yo=new Launcher(ctx); 
     return yo; 
    } 

    public void doActions() { 
     receiver1=new Receiver1(); 
     IntentFilter filter1=new IntentFilter(Service1.MY_ACTION); 
     ctx.registerReceiver(receiver1, filter1); 

     Intent i1=new Intent(ctx, Service1.class); 
     ctx.startService(i1); 


     receiver2=new Receiver2(); 
     IntentFilter filter2=new IntentFilter(Service2.MY_ACTION); 
     ctx.registerReceiver(receiver2, filter2); 

     Intent i2=new Intent(ctx, Service2.class); 
     ctx.startService(i2); 
    } 
} 
Cuestiones relacionadas