2011-10-12 85 views
8

無法在啓動時動態註冊接收者。我沒有活動。我不想在服務中註冊它。無法動態註冊接收者

引導接收器,其中我註冊另一接收器:

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); 
     } 
    } 
} 

接收機,我要註冊:

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

尚未見過這樣的包名! :) – prijupaul

回答

13

答案是錯誤消息: IntentReceiver components are not allowed to register to receive intents。您不能在現有的BroadcastReceiver中註冊新的BroadcastReceiver。

+0

哦,是的!你是對的!謝謝 – XXX

1

難道你不能在清單中註冊這個嗎?

+1

不。它不能從清單工作。 http://stackoverflow.com/questions/1588061/android-how-to-receive-broadcast-intents-action-screen-on-off – XXX

+3

可能你可以啓動一個可以註冊BroadcastReceiver的服務。另外,可能會調用context.getApplicationContext()可以工作 – njzk2

+1

是的,你是對的。我用服務解決了這個問題。謝謝! – XXX

5

我在ACTION_BOOT_COMPLETED推出的服務爲

@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); 
      } 
     } 

,將創建我的應用場景的背後:

public class MyApplication extends Application 

,並在那裏我有覆蓋的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); 
} 

問題至少解決了我。

1

對於小部件需要一個解決方案。這裏是我已經解決了:

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是一個BroadcastReceiver ...

0

一個相當簡單的解決方案在一個獨立的線程啓動新的服務:

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(); 
    } 
} 

在啓動,我們有:

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); 
    } 
}