Appel de startActivity () en dehors d’un contexte d’activité

J’ai implémenté un ListView dans mon application Android. Je lie à ce ListView utilisant une sous-classe personnalisée de la classe ArrayAdapter . Dans la ArrayAdapter.getView(...) remplacée, ArrayAdapter.getView(...) un OnClickListener . Dans la méthode onClick du OnClickListener , je souhaite lancer une nouvelle activité. Je reçois l’exception:

 Calling startActivity() from outside of an Activity context requires the FLAG_ACTIVITY_NEW_TASK flag. Is this really what you want? 

Comment puis-je obtenir le Context lequel fonctionne le ListView (l’ Activity )?

Non plus

  • mettre en cache l’object Context via le constructeur de votre adaptateur, ou
  • Obtenez-le de votre vue.

Ou en dernier recours,

  • Ajouter l’indicateur FLAG_ACTIVITY_NEW_TASK à votre intention:

_

 myIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 

Edit – j’éviterais de paramétrer les drapeaux car ils interféreraient avec le stream normal de la stack d’événements et d’historique.

Je l’ai résolu avec ” addFlags “ au lieu de “setFlags”

 myIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 

Selon la documentation, il fait:

Ajoutez des indicateurs supplémentaires à l’intention (ou à la valeur des indicateurs existants).

MODIFIER

Sachez que si vous utilisez des indicateurs pour modifier la stack d’historique, comme le dit la réponse d’Alex Volovoy :

… évitez de définir des indicateurs, car cela pourrait interférer avec le stream normal de la stack d’événements et d’historique.

Au lieu d’utiliser (getApplicationContext) utilisez YourActivity.this

Si vous avez une erreur en raison de l’utilisation de create chooser comme ci-dessous:

 Intent sharingIntent = new Intent(Intent.ACTION_VIEW); sharingIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); sharingIntent.setData(Uri.parse("http://google.com")); startActivity(Intent.createChooser(sharingIntent, "Open With")); 

Définissez l’indicateur pour créer un sélecteur comme ceci:

 Intent sharingIntent = new Intent(Intent.ACTION_VIEW); sharingIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); sharingIntent.setData(Uri.parse("http://google.com")); Intent chooserIntent = Intent.createChooser(sharingIntent, "Open With"); chooserIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); startActivity(chooserIntent); 

Je pense que peut-être vous implémentez OnClickListener au mauvais endroit – en général, vous devriez certainement implémenter un OnItemClickListener dans votre activité et le définir à la place sur ListView, sinon vous rencontrerez des problèmes avec vos événements …

En outre: si vous affichez des liens dans listview dans fragment , ne le créez pas comme ça

  adapter = new ListAdapter(getActivity().getApplicationContext(),mSsortingngs); 

appeler à la place

  adapter = new ListAdapter(getActivity(),mSsortingngs); 

L’adaptateur fonctionne bien dans les deux cas, mais les liens ne fonctionnent que dans le dernier.

 CustomAdapter mAdapter = new CustomAdapter( getApplicationContext(), yourlist); 

ou

 Context mContext = getAppliactionContext(); CustomAdapter mAdapter = new CustomAdapter( mContext, yourlist); 

changer en dessous

 CustomAdapter mAdapter = new CustomAdapter( this, yourlist); 

Voir, si vous créez une intention dans une liste dans une méthode

 override onClick (View v). 

puis appeler le contexte à travers cette vue également:

 v.getContext () 

Il n’y aura même pas besoin de SetFlags …

Pour quiconque obtient ceci sur Xamarin.Android (MonoDroid) même lorsque StartActivity est appelé depuis l’activité – il s’agit en fait d’un bogue Xamarin avec le nouveau runtime ART, voir https://bugzilla.xamarin.com/show_bug.cgi?id=17630

A mon avis, il est préférable d’utiliser la méthode de startActivity() juste dans votre code de Activity.class . Si vous l’utilisez dans l’ Adapter ou dans une autre classe, cela entraînera cela.

Cette erreur se produit lorsque l’activité de démarrage ne sait pas quelle est son activité. Vous devez donc append une activité avant startActivity ()

vous devez définir

 activity.startActivity(yourIntent); 

Elaborant la réponse d’Alex Volovoy un peu plus –

au cas où vous rencontrez ce problème avec des fragments, getActivity () fonctionne bien pour obtenir le contexte

Dans d’autres cas:

Si vous ne voulez pas utiliser-

 myIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);//not recommend 

faites ensuite une fonction comme celle-ci dans votre classe OutsideClass –

 public void gettingContext(Context context){ real_context = context;//where real_context is a global variable of type Context } 

Maintenant, dans votre activité principale, chaque fois que vous créez une nouvelle classe OutsideClass, appelez la méthode ci-dessus immédiatement après avoir défini la classe OutsideClass en donnant comme argument le contexte de l’activité. Aussi dans votre activité principale faites une fonction-

 public void startNewActivity(final Ssortingng activity_to_start) { if(activity_to_start.equals("ACTIVITY_KEY")); //ACTIVITY_KEY-is a custom key,just to //differentiate different activities Intent i = new Intent(MainActivity.this, ActivityToStartName.class); activity_context.startActivity(i); }//you can make a if-else ladder or use switch-case 

maintenant revenez à votre OutsideClass, et pour commencer une nouvelle activité, faites quelque chose comme ça-

 @Override public void onClick(View v) { ........ case R.id.any_button: MainActivity mainAct = (MainActivity) real_context; mainAct.startNewActivity("ACTIVITY_KEY"); break; } ........ } 

De cette façon, vous serez en mesure de démarrer différentes activités appelées à partir de OutsideClass différentes sans perturber les drapeaux.

Remarque: Essayez de ne pas mettre en cache l’object contextuel via le constructeur pour fragment (avec l’adaptateur, c’est bien). Un fragment doit avoir un constructeur vide, sinon l’application se bloque dans certains scénarios.

rappelez-vous d’appeler

 OutsideClass.gettingContext(Context context); 

dans la fonction onResume () également.

J’ai aussi eu le même problème. Vérifiez tout le contexte que vous avez passé. Pour les « liens », il faut un contexte d’activité et non un contexte d’application .

C’est l’endroit où vous devriez vérifier:

1.) Si vous avez utilisé LayoutInflater, vérifiez le contexte que vous avez passé.

2.) Si vous utilisez un adaptateur, vérifiez le contexte que vous avez passé.

J’ai eu le même problème. Le problème est avec le contexte. Si vous souhaitez ouvrir des liens (par exemple, partager un lien via le sélecteur), transmettez le contexte d’activité et non le contexte d’application.

N’oubliez pas d’append myIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK) si vous n’êtes pas dans votre activité.

 Intent viewIntent = new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS); viewIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); startActivity(viewIntent); 

J’espère que cela fonctionnera.

Face au même problème alors mis en œuvre
intent.addFlags (Intent.FLAG_ACTIVITY_NEW_TASK);
et a résolu le problème.

Il peut y avoir une autre raison liée à l’adaptateur de vue liste.
vous pouvez voir ce blog , décrit très bien.

 Intent i= new Intent(context, NextActivity.class); i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_SINGLE_TOP); 

utilisez ce code. fonctionne bien pour moi; Partager quelque chose en dehors d’une activité

  Intent intent = new Intent(Intent.ACTION_SEND); intent.setType("text/plain"); // Append Text Ssortingng Text = "Your Text Here" intent.putExtra(Intent.EXTRA_TEXT, Text); intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); Intent shareIntent = Intent.createChooser(intent,"Share . . . "); shareIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); G.context.getApplicationContext().startActivity(shareIntent); 

Si vous invoquez le partage Intent dans le plug-in Cordova, définir le drapeau ne vous aidera pas. Au lieu de cela, utilisez ceci –

 cordova.getActivity().startActivity(Intent.createChooser(shareIntent, "title")); 

Ma situation était un peu différente, je teste mon application en utilisant Espresso et j’ai du lancer mon activité avec ActivityTestRule partir du Context instrumentation (qui n’est pas celui provenant d’une Activity ).

  fun intent(context: Context) = Intent(context, HomeActivity::class.java) .addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP) 

J’ai dû changer les drapeaux et append un or un bit ( | en Java) avec Intent.FLAG_ACTIVITY_NEW_TASK

Donc, il en résulte:

  fun intent(context: Context) = Intent(context, HomeActivity::class.java) .addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP or Intent.FLAG_ACTIVITY_NEW_TASK) 

Étant donné que l’ajout de drapeaux affecte event_flow et stack_history, il est préférable de passer le «contexte d’application» à la non-activité à partir de laquelle vous devez appeler une classe d’activité de la manière suivante:

“ActivityClassName.this” (Pendant que vous passez le contexte de cette manière, il contiendra tous les détails et informations nécessaires pour appeler une activité à partir d’un scénario autre qu’une activité)

Il n’est donc pas nécessaire de définir ou d’append des indicateurs, cela fonctionnera parfaitement dans tous les cas.