Vous appelez startActivity () depuis l'extérieur d'une activité?

196

J'utilise un AlarmManagerpour déclencher une intention qui diffuse un signal. Voici mon code:

AlarmManager mgr = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
Intent i = new Intent(this, Wakeup.class);
try
{
    PendingIntent pi = PendingIntent.getBroadcast(this, 0, i, 0);
    Long elapsed +=  // sleep time;
    mgr.set(AlarmManager.RTC_WAKEUP, elapsed, pi);
}
catch(Exception r)
{
    Log.v(TAG, "RunTimeException: " + r);
}

J'appelle ce code à partir d'un Activity, donc je ne sais pas comment je pourrais obtenir l'erreur suivante ...

ERROR/AndroidRuntime(7557): java.lang.RuntimeException: Unable to start receiver com.wcc.Wakeup: android.util.AndroidRuntimeException: Calling startActivity() from outside of an Activity  context requires the FLAG_ACTIVITY_NEW_TASK flag. Is this really what you want?
Tom G
la source

Réponses:

494

si votre version Android est inférieure à Android - 6, vous devez ajouter cette ligne, sinon cela fonctionnera au-dessus d'Android - 6.

...
Intent i = new Intent(this, Wakeup.class);
i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
...
Cristian
la source
8
oui cela fonctionne. mais si vous souhaitez démarrer plusieurs instances de la même activité, cela ne fonctionne pas. Depuis le FLAG_ACTIVITY_NEW_TASK reprendra la même activité existante
Ovidiu Latcu
7
Ajouter le drapeau FLAG_ACTIVITY_Multiple_TASKS POUR RÉSOUDRE VOTRE problème
Pavankumar Vijapur
Attention, vous en avez également besoin sur Android 9+, voir cette réponse pour des clarifications
Vadim Kotov
55

Pour plusieurs instances de la même activité, utilisez l'extrait de code suivant,

Remarque : Cet extrait de code que j'utilise en dehors de mon Activity. Assurez-vous que votre AndroidManifestfichier ne contient pas android:launchMode="singleTop|singleInstance". si nécessaire, vous pouvez le remplacer par android:launchMode="standard".

Intent i = new Intent().setClass(mActivity.getApplication(), TestUserProfileScreenActivity.class);  
i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_MULTIPLE_TASK);

// Launch the new activity and add the additional flags to the intent
mActivity.getApplication().startActivity(i);

Cela fonctionne bien pour moi. J'espère que cela fait gagner du temps à quelqu'un. Si quelqu'un trouve un meilleur moyen, veuillez partager avec nous.

Nandagopal T
la source
5
Veuillez comprendre la différence entre les méthodes setFlags () et addFlag (). Tout ce que vous faites maintenant, c'est lancer une activité avec FLAG_ACTIVITY_NEW_TASK. Comme dans le code affiché par Cristian ci-dessous.
JehandadK
-------------------------------------------------- ----------------- i.addFlag (Intent.FLAG_ACTIVITY_MULTIPLE_TASK); i.addFlag (Intent.FLAG_ACTIVITY_NEW_TASK); -------------------------------------------------- ----------------- i.setFlags (Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_MULTIPLE_TASK);
JehandadK
42

Android Doc dit -

L'exigence FLAG_ACTIVITY_NEW_TASK est désormais appliquée

Avec Android 9, vous ne pouvez pas démarrer une activité à partir d'un contexte de non-activité à moins de passer l'indicateur d'intention FLAG_ACTIVITY_NEW_TASK. Si vous essayez de démarrer une activité sans passer cet indicateur, l'activité ne démarre pas et le système imprime un message dans le journal.

Remarque: L'exigence d'indicateur a toujours été le comportement souhaité et a été appliquée aux versions inférieures à Android 7.0 (API niveau 24). Un bogue dans Android 7.0 a empêché l'application de l'exigence d'indicateur.

Cela signifie (Build.VERSION.SDK_INT <= Build.VERSION_CODES.M) || (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P)qu'il est obligatoire d'ajouter Intent.FLAG_ACTIVITY_NEW_TASKlors de l'appel startActivity()depuis l'extérieur d'un Activitycontexte.

Il est donc préférable d'ajouter un drapeau pour toutes les versions -

...
Intent i = new Intent(this, Wakeup.class);
i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
...
Hrishikesh Kadam
la source
12

Vous n'avez pas collé la partie où vous appelez startActivity, c'est la partie intéressante.

Vous appelez peut-être startActivitydans un Servicecontexte ou dans un Applicationcontexte.

Imprimez "ceci" pour enregistrer le chat avant de startActivitypasser l' appel, et voyez à quoi il se réfère, il s'agit parfois d'utiliser accidentellement un "ceci" intérieur.

marmor
la source
1
C'est probablement le problème que OP rencontre. J'ai rencontré la même chose. Le lancement d'une activité avec getApplicationContext () au lieu d'une activité existante déclenchera cette erreur.
Hazen Hills Software
NICE :) Je suis sûr que c'était l'erreur que j'essaie de repérer toute la soirée. Merci monsieur.
Martin Pfeffer
9

Parfois, cette erreur peut se produire sans appel explicite à startActivity(...). Par exemple, certains d'entre vous ont peut-être vu une trace de pile comme celle-ci dans Crashlytics:

Fatal Exception: android.util.AndroidRuntimeException: Calling startActivity() from outside of an Activity  context requires the FLAG_ACTIVITY_NEW_TASK flag. Is this really what you want?
       at android.app.ContextImpl.startActivity(ContextImpl.java:1597)
       at android.app.ContextImpl.startActivity(ContextImpl.java:1584)
       at android.content.ContextWrapper.startActivity(ContextWrapper.java:337)
       at android.text.style.URLSpan.onClick(URLSpan.java:62)
       at android.text.method.LinkMovementMethod.onTouchEvent(LinkMovementMethod.java:217)
       at android.widget.TextView.onTouchEvent(TextView.java:9522)
       at android.view.View.dispatchTouchEvent(View.java:8968)
       at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2709)
       at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2425)
       at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2709)
       at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2425)
       at android.widget.AbsListView.dispatchTouchEvent(AbsListView.java:5303)
       at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2709)
       at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2425)
       at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2709)
       at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2425)
       at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2709)
       at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2425)
       at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2709)
       at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2425)
       at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2709)
       at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2425)
       at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2709)
       at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2425)
       at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2709)
       at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2425)
       at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2709)
       at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2425)
       at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2709)
       at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2425)
       at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2709)
       at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2425)
       at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2709)
       at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2425)
       at com.android.internal.policy.impl.PhoneWindow$DecorView.superDispatchTouchEvent(PhoneWindow.java:2559)
       at com.android.internal.policy.impl.PhoneWindow.superDispatchTouchEvent(PhoneWindow.java:1767)
       at android.app.Activity.dispatchTouchEvent(Activity.java:2866)
       at android.support.v7.view.WindowCallbackWrapper.dispatchTouchEvent(WindowCallbackWrapper.java:67)
       at android.support.v7.view.WindowCallbackWrapper.dispatchTouchEvent(WindowCallbackWrapper.java:67)
       at com.android.internal.policy.impl.PhoneWindow$DecorView.dispatchTouchEvent(PhoneWindow.java:2520)
       at android.view.View.dispatchPointerEvent(View.java:9173)
       at android.view.ViewRootImpl$ViewPostImeInputStage.processPointerEvent(ViewRootImpl.java:4706)
       at android.view.ViewRootImpl$ViewPostImeInputStage.onProcess(ViewRootImpl.java:4544)
       at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:4068)
       at android.view.ViewRootImpl$InputStage.onDeliverToNext(ViewRootImpl.java:4121)
       at android.view.ViewRootImpl$InputStage.forward(ViewRootImpl.java:4087)
       at android.view.ViewRootImpl$AsyncInputStage.forward(ViewRootImpl.java:4201)
       at android.view.ViewRootImpl$InputStage.apply(ViewRootImpl.java:4095)
       at android.view.ViewRootImpl$AsyncInputStage.apply(ViewRootImpl.java:4258)
       at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:4068)
       at android.view.ViewRootImpl$InputStage.onDeliverToNext(ViewRootImpl.java:4121)
       at android.view.ViewRootImpl$InputStage.forward(ViewRootImpl.java:4087)
       at android.view.ViewRootImpl$InputStage.apply(ViewRootImpl.java:4095)
       at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:4068)
       at android.view.ViewRootImpl.deliverInputEvent(ViewRootImpl.java:6564)
       at android.view.ViewRootImpl.doProcessInputEvents(ViewRootImpl.java:6454)
       at android.view.ViewRootImpl.enqueueInputEvent(ViewRootImpl.java:6425)
       at android.view.ViewRootImpl$WindowInputEventReceiver.onInputEvent(ViewRootImpl.java:6654)
       at android.view.InputEventReceiver.dispatchInputEvent(InputEventReceiver.java:185)
       at android.os.MessageQueue.nativePollOnce(MessageQueue.java)
       at android.os.MessageQueue.next(MessageQueue.java:143)
       at android.os.Looper.loop(Looper.java:130)
       at android.app.ActivityThread.main(ActivityThread.java:5942)
       at java.lang.reflect.Method.invoke(Method.java)
       at java.lang.reflect.Method.invoke(Method.java:372)
       at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1400)
       at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1195)

Et vous vous demandez peut-être ce que vous avez fait de mal, car la trace inclut uniquement le code du framework. Eh bien, voici un exemple de la façon dont cela peut se produire. Disons que nous sommes dans un fragment.

Activity activity = getActivity();
Context activityContext = activity;
Context appContext = activityContext.getApplicationContext();
LayoutInflater inflater = LayoutInflater.from(appContext); // whoops!
View view = inflater.inflate(R.layout.some_layout, parent, false);
TextView tvWithLinks = (TextView) view.findViewById(R.id.tv_with_links);

tvWithLinks.setMovementMethod(LinkMovementMethod.getInstance()); // whoops!!

Désormais, lorsqu'un utilisateur clique sur cette vue de texte, votre application se bloque avec la trace de pile ci-dessus. Cela est dû au fait que le gonfleur de mise en page a une référence au contexte d'application , et donc que votre vue texte a un contexte d'application. Cliquer sur cette vue texte appelle implicitementappContext.startActivity(...) .

Remarque finale: j'ai testé cela sur les appareils Android 4, 5, 6 et 7. Cela n'affecte que 4, 5 et 6. Les appareils Android 7 n'ont apparemment aucun problème pour appeler appContext.startActivity(...).

J'espère que ça aidera quelqu'un d'autre!

AutonomousApps
la source
2

Cette même erreur que j'ai rencontrée en cas de notification sur les derniers appareils Android 9 et 10.

Cela dépend du mode de lancement de la façon dont vous le gérez. Utilisez le code ci-dessous: - android: launchMode = "singleTask"

Ajoutez cet indicateur avec Intent: - intent.setFlags (Intent.FLAG_ACTIVITY_NEW_TASK);

Puneet Kumar
la source
1

Essayez de passer à cette ligne:

PendingIntent pendingIntent = PendingIntent.getBroadcast(getContext(), 0, i, 0);
Luís Ledebour
la source
1

Je veux juste remarquer que startActivityde l'extérieur une activité est valide dans certaines versions d'Android (entre N et O-MR1) et le point intéressant est qu'il s'agit d'un bug dans le code source Android!


C'est le commentaire ci-dessus de startActivitymise en œuvre. Voyez ici .

L'appel d'une activité de démarrage à l'extérieur d'une activité sans FLAG_ACTIVITY_NEW_TASK n'est généralement pas autorisé, sauf si l'appelant spécifie l'ID de tâche dans lequel l'activité doit être lancée. Un bogue existait entre N et O-MR1 qui permettait à cela de fonctionner .

Fartab
la source
quelle est la solution pour cela
dominic_torreto
0

Lorsque vous souhaitez ouvrir une activité dans votre application, vous pouvez appeler la méthode startActivity () avec un paramètre Intent comme paramètre. Cette intention serait l'activité que vous souhaitez ouvrir. Vous devez d'abord créer un objet de cette intention avec le premier paramètre comme contexte et le second paramètre comme classe d'activité ciblée.

Intent intent = new Intent(this, Activity_a.class);
startActivity(intent);

J'espère que cela vous aidera.

Md. Shafiqur Rahman
la source
3
J'écris en tant que critique car votre réponse a été signalée comme étant de mauvaise qualité. Le défaut de cette réponse est qu'il n'y a aucune explication de ce que fait votre code ou pourquoi il résout le problème posé dans la question. Pourriez-vous s'il vous plaît ajouter quelques commentaires explicatifs, sachant que de nombreux programmeurs pourraient lire votre réponse à l'avenir pour obtenir des conseils. Je vous remercie!
Bill Bell
Lorsque vous souhaitez ouvrir une activité dans votre application, vous pouvez appeler la méthode startActivity () avec un paramètre Intent. Cette intention serait l'activité que vous souhaitez ouvrir. Vous devez d'abord créer un objet de cette intention avec le premier paramètre comme contexte et le second paramètre comme classe d'activité ciblée. J'espère que cela vous aidera.
Md. Shafiqur Rahman
D'ACCORD. Mais plutôt que de mettre cette information dans un commentaire, vous devez modifier votre réponse et la mettre là. Je regrette d'avoir insisté sur ce point, mais il est important de le faire pour chaque réponse. Meilleures salutations.
Bill Bell
Oui, veuillez expliquer pourquoi votre réponse est correcte. Nous apprenons à être de meilleurs programmeurs uniquement lorsque nous apprenons POURQUOI nous faisons les choses que nous faisons.
kiwicomb123