Comment puis-je transmettre des données à partir d'un BroadcastReceiver par une activité en cours de démarrage?

StackOverflow https://stackoverflow.com/questions/2616859

Question

J'ai une application Android qui doit être pris conscience de façon sporadique tout au long de la journée.

Pour ce faire, j'utilise le AlarmManager de mettre en place un PendingIntent et à ce déclencheur d'une BroadcastReceiver. Cette BroadcastReceiver commence alors une activité pour amener l'interface utilisateur au premier plan.

Tous les ci-dessus semble fonctionner, en ce que l'activité se lance correctement; mais je voudrais que le BroadcastReceiver d'informer l'activité qu'il a été lancé par l'alarme (au lieu d'être lancé par l'utilisateur). Pour ce faire, je suis en train, de la méthode OnReceive () du BroadcastReceiver pour définir une variable dans le faisceau de figurants de l'intention, ainsi:

    Intent i = new Intent(context, MyActivity.class);
    i.putExtra(wakeupKey, true);
    i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
    context.startActivity(i);

Dans la méthode onResume () de mon activité, je cherche alors l'existence de cette variable booléenne:

protected void onResume() {
    super.onResume();

    String wakeupKey = "blah";      
    if (getIntent()!=null && getIntent().getExtras()!=null)
        Log.d("app", "onResume at " + System.currentTimeMillis() + ":" + getIntent().getExtras().getBoolean(wakeupKey));
    else
        Log.d("app", "onResume at " + System.currentTimeMillis() + ": null");
}

L'appel à onResume () retourne toujours null getIntent () getExtras () -.. Je ne semble pas être en mesure de passer à travers tous les extras du tout dans cet ensemble

Si j'utilise la même méthode pour lier extras à la PendingIntent qui déclenche la BroadcastReceiver cependant, les extras viennent à travers bien.

Quelqu'un peut-il me dire ce qui est différent au sujet de passer un paquet d'un BroadcastReceiver à une activité, par opposition à passer le faisceau d'une activité à un BroadcastReceiver? Je crains que je sois en train de faire quelque chose de très évident mal ici ...

Était-ce utile?

La solution

Juste pour préciser (parce que j'utilisé beaucoup de temps à trouver comment le faire fonctionner)

Dans la classe de service qui s'étend BroadcastReceiver. Mettre dans le code suivant dans onReceive()

Intent intent2open = new Intent(context, YourActivity.class);
intent2open.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
intent2open.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
String name = "KEY";
String value = "String you want to pass";
intent2open.putExtra(name, value);
context.startActivity(intent2open);

Le FLAG_ACTIVITY_SINGLE_TOP fait que les applications ne pas rouvrir si elle est déjà ouverte. Cela signifie que le « vieux » l'intention qui a ouvert YourActivity en premier lieu est réutilisée et il ne contiendra pas les valeurs supplémentaires. Vous devez les attraper dans une autre méthode appelée onNewIntent() dans YourActivity.

public class YourActivity extends Activity {
    private String memberFieldString;

    @Override
    public void onCreate(Bundle savedInstanceState) { 
         super.onCreate(savedInstanceState);
         setContentView(R.layout.main);

         // Code doing your thing...
    } // End of onCreate()

    @Override
    protected void onNewIntent(Intent intent) {
    Log.d("YourActivity", "onNewIntent is called!");

    memberFieldString = intent.getStringExtra("KEY");

    super.onNewIntent(intent);
} // End of onNewIntent(Intent intent)

    @Override
    protected void onResume() {
        if (memberFieldString != null) {
            if (opstartsIntent.getStringExtra(KEY) != null) {
               Log.d("YourActivity", "memberFieldString: "+ memberFieldString);
            } else {
               Log.d("YourActivity", "The intent that started YourActivity did not have an extra string value");
            }
        }
    } // End of onResume()

}  // End of YourActivity

S'il vous plaît noter les deux instructions if - le onResume() ne sait pas si elle est appelée après OnCreate()->OnStart() OR onRestart()->onStart()
S'il vous plaît voir: http://www.anddev.org/images /android/activity_lifecycle.png

Il est juste utilisé pour tester si l'application est lancée par l'utilisateur (sans intention extras) ou par le BroadcastReceiver (intention avec extras).

Autres conseils

  

Cette BroadcastReceiver commence alors une   Activité pour amener l'interface utilisateur à la   premier plan.

Cela peut être le point crucial de votre problème. Essayez primordial onNewIntent() et de voir si le Intent lui a été transmis a votre supplémentaire. Si oui, c'est à cause de la façon dont vous configurez l'activité dans le manifeste (par exemple, vous utilisez singleTop) et le fait que, dans ce cas précis, l'activité existait déjà.

Vous pouvez également envisager de se débarrasser de i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); et voir si cela change les questions.

Le résultat est que ce que vous faites - mettre le plus dans le Intent pour startActivity() - devrait fonctionner parfaitement. En fait, vous pouvez voir des exemples de cette . Cela donne à penser qu'il est quelque chose géniale de l'activité (par exemple, singleTop) ou la façon dont vous invoquer l'activité (par exemple, FLAG_ACTIVITY_NEW_TASK).

EDIT:

Depuis mes premiers coups de feu ne fonctionnent pas, et compte tenu de votre commentaire « de curiouser » ci-dessus ...

Cela se sent un peu comme un PendingIntent - avec ceux-ci, à moins que vous prenez des mesures, vous ne serez pas en mesure de mettre à jour extras

.

Sur un coup de tête, essayez d'ajouter une deuxième <intent-filter> à votre activité dans le manifeste, juste sur une chaîne d'action unique et essayez de démarrer votre activité de votre récepteur à l'aide que. Ou, tout simplement lancer une chaîne d'action dans votre Intent que le récepteur utilise pour startActivity(), sans déconner avec le manifeste.

Au lieu de getIntent().getExtras().getBoolean(wakeupKey) il est plus classique d'écrire getIntent().getBooleanExtra(wakeupKey, defaultValue). Je ne peux pas être sûr si cela est lié à votre problème, mais il y a des choses à faire avec la création d'un paquet à l'intérieur getExtras () que je ne suis pas sûr, donc il peut être la peine d'y aller quand même.

Set drapeau SingleTop travaux (ne pas mélanger avec d'autres drapeaux)

Intent intent = new Intent(ContextManager.getContext(),OrderList.class);
intent.setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
Bundle bundle = new Bundle();       

bundle.putString("username",username);
bundle.putString("password",password);

intent.putExtras(bundle);
startActivityForResult(intent,0); 

surchargent Juste le onNewIntent comme celui-ci et le var Bundle sera disponible dans la méthode onResume:

@Override
protected void onNewIntent(Intent intent) {
    super.onNewIntent(intent);
    setIntent(intent);
}
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top