2010-10-03 6 views
28

Je suis en train de démarrer automatiquement mon application NightClock sur charge à l'aide BroadcastReceiver suivant mis en œuvre dans le OnPause() méthode: méthodestartActivity() de BroadcastReceiver

BroadcastReceiver test = new BroadcastReceiver() { 
    @Override 
    public void onReceive(Context context, Intent intent) { 
     unregisterReceiver(this); 
     Intent i = new Intent(context, NightClock.class); 
     i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 
     context.startActivity(i); 
    }   
}; 
registerReceiver(test, new IntentFilter(Intent.ACTION_POWER_CONNECTED)); 

Le OnReceive() est déclenché lorsque le câble USB est branché, mais l'activité ne démarre pas. Cependant, le journal affiche ceci:

I/ActivityManager( 79): Starting activity: Intent { flg=0x10000000 cmp=com.meins.nightclock/.NightClock } 

Des idées pour lesquelles le journal indique que l'activité est démarrée, mais rien ne se passe?

+0

Veuillez mettre à jour votre problème avec plus de LogCat - quelques lignes avant celle-ci et une douzaine de lignes après celle-ci. En outre, pourquoi 'FLAG_ACTIVITY_NEW_TASK'? Aussi, l'activité qui a enregistré ce 'BroadcastReceiver' est toujours là quand ACTION_POWER_CONNECTED se produit? – CommonsWare

+0

Il n'y a plus de lignes dans LogCat lors de la connexion à l'alimentation. Le 'BroadcastReceiver' est enregistré dans la même activité qu'il devrait commencer. Cette activité fonctionne toujours en arrière-plan (l'application LogCat a été mise en avant). Si cette activité est supprimée dans le gestionnaire de tâches, le 'BroadcastReceiver' ne semble pas déclencher du tout. Est-ce que cette approche d'autostart mon application mal depuis le début? – Gubbel

Répondre

16

Si votre objectif est que vous voulez que NightClock soit démarré à chaque envoi d'une diffusion ACTION_POWER_CONNECTED, votre approche d'utilisation d'un BroadcastReceiver est correcte. Cependant, ne l'enregistrez pas à partir d'une activité. Au contraire, inscrivez-vous dans le manifeste:

<receiver android:name=".OnPowerReceiver"> 
     <intent-filter> 
       <action android:name="android.intent.action.ACTION_POWER_CONNECTED" /> 
     </intent-filter> 
</receiver> 

Ensuite, demandez à votre BroadcastReceiver en tant que classe Java publique (ici nommé OnPowerReceiver, mais vous pouvez l'appeler ce que vous voulez), et faites appel startActivity().

Gardez à l'esprit que les utilisateurs ne veulent probablement pas que vous le fassiez. Il existe de nombreux autres cas pour connecter un téléphone à l'alimentation en plus de démarrer une "horloge de nuit". Je vous suggère humblement de laisser simplement les utilisateurs démarrer votre activité via l'écran d'accueil.

+0

J'ai enregistré le 'BroadcastReceiver' dans le manifeste comme vous l'avez dit avec cet appel dans la méthode' onReceive() ':' context.startActivity (new Intent (context, NightClock.class)), 'Mais rien ne se passe quand je me connecte le téléphone pour alimenter. Pas même une entrée de journal est ajoutée si j'ajoute 'Log.d (this.toString()," essayant de démarrer l'application ... ");' à la méthode. – Gubbel

+2

@Gubbel: Oups. Essayez ''. La plupart du temps, ils n'ont pas le 'ACTION_' dans la chaîne, mais apparemment ils le font sur celui-ci. – CommonsWare

+0

Ça marche! Je vous remercie. – Gubbel

46

Vous avez contexte passé en paramètre à la méthode onRecieve(), donc il suffit d'utiliser:

@Override 
public void onReceive(Context context, Intent intent) { 
    //start activity 
    Intent i = new Intent(); 
    i.setClassName("com.test", "com.test.MainActivity"); 
    i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 
    context.startActivity(i); 
} 

Il fonctionne, bien sûr, vous devez changer l'emballage et le nom de la classe d'activité à votre propre.

+2

Pourquoi la liste déroulante? Est-ce mauvais? Ça m'a aidé à le faire, alors que je n'ai rien trouvé en disant que c'est une mauvaise approche. – Mafro34

+0

@ Mafro34 Je viens d'essayer la même approche et la raison pour laquelle je pense que ce n'est pas l'idéal est le drapeau qu'il met en place. Parce que si ce n'est pas ce que vous voulez (en exécutant une nouvelle tâche), cela pourrait sérieusement perturber la logique de votre application - c'est ce que j'ai fait avec le mien quand même. Donc, sauf si c'est ce que vous voulez, je recommande de trouver une autre approche. – AgentKnopf

+5

@AgentKnopf On dirait que vous n'avez pas beaucoup de choix: (sur http://developer.android.com/reference/android/content/Context.html#startActivity%28android.content.Intent,%20android.os.Bundle % 29): "Notez que si cette méthode est appelée depuis l'extérieur d'un contexte d'activité, l'intention doit inclure l'indicateur de lancement FLAG_ACTIVITY_NEW_TASK car, sans être démarré à partir d'une activité existante, il n'existe aucune tâche existante dans laquelle placer la nouvelle activité et donc il doit être placé dans sa propre tâche séparée. " – aberaud

-3

De Docs:

Ne pas démarrer les activités de récepteurs de radiodiffusion parce que l'expérience utilisateur est sonné faux; surtout s'il y a plus d'un récepteur. Au lieu de cela, pensez à afficher une notification.

+0

Ils remplacent cela dans de nombreuses applications par défaut comme les alarmes et les appels entrants. Donc, si l'utilisateur veut que cela arrive, c'est son appel. Et votre réponse ne répond pas à la question. – Dpedrinha

Questions connexes