Llamar a startActivity () desde fuera de un contexto de actividad

Implementé ListView en mi aplicación Android. Me enlace a este ListView usando una subclase personalizada de la clase ArrayAdapter . Dentro del método ArrayAdapter.getView(...) reemplazado, asigno un OnClickListener . En el método onClick de OnClickListener , quiero iniciar una nueva actividad. Obtengo la excepción:

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

¿Cómo puedo obtener el Context que está trabajando el ListView (la Activity actual)?

Ya sea

  • almacenar en caché el objeto Contexto mediante el constructor en su adaptador, o
  • obténgalo de su vista.

O como último recurso,

  • agrega – indicador FLAG_ACTIVITY_NEW_TASK a tu intención:

_

 myIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 

Editar: evitaría establecer indicadores ya que interferiría con el flujo normal del evento y la stack de historial.

Lo resolví con ” addFlags ” en lugar de “setFlags”

 myIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 

De acuerdo con la documentación que hace:

Agregue banderas adicionales a la intención (o con el valor de banderas existente).

EDITAR

Tenga en cuenta que si usa banderas, cambia la stack del historial, como dice la respuesta de Alex Volovoy :

… evite establecer indicadores ya que interferirá con el flujo normal del evento y la stack de historial.

En lugar de usar (getApplicationContext) use YourActivity.this

Si recibiste un error debido al uso de crear el selector como a continuación:

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

Establezca la bandera para crear un selector como este:

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

Creo que quizás estés implementando OnClickListener en el lugar equivocado; por lo general, definitivamente debes implementar un OnItemClickListener en tu Actividad y configurarlo en el ListView, o tendrás problemas con tus eventos …

Además: si muestra enlaces en la vista de lista en fragmento , no lo cree de esta manera

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

en cambio llama

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

el adaptador funciona bien en ambos casos, pero los enlaces funcionan solo en el último.

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

o

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

cambiar a debajo

 CustomAdapter mAdapter = new CustomAdapter( this, yourlist); 

Mira, si estás creando un bash dentro de un listiner en algún método

 override onClick (View v). 

luego llama al contexto a través de esta vista también:

 v.getContext () 

Ni siquiera necesitará SetFlags …

Para que cualquiera pueda obtener esto en Xamarin.Android (MonoDroid) incluso cuando se llame a StartActivity por actividad, este es en realidad un error de Xamarin con el nuevo tiempo de ejecución de ART, consulte https://bugzilla.xamarin.com/show_bug.cgi?id=17630.

En mi opinión, es mejor usar el método de startActivity() solo en el código de Activity.class . Si usa eso en el Adapter u otra clase, resultará en eso.

Este error ocurre cuando la actividad no sabe cuál es su actividad. Entonces debes agregar actividad antes de startActivity ()

debes establecer

 activity.startActivity(yourIntent); 

Elaborando la respuesta de Alex Volovoy un poco más –

en caso de que tenga este problema con fragmentos, getActivity () funciona bien para obtener el contexto

En otros casos:

Si no quieres usar-

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

luego haga una función como esta en su OutsideClass –

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

Ahora, en su actividad principal, siempre que haga una nueva clase OutsideClass, llame al método anterior inmediatamente después de definir OutsideClass, dando el contexto de la actividad como argumento. También en su actividad principal haga una función-

 public void startNewActivity(final String 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 

Ahora vuelve a tu OutsideClass, y para comenzar una nueva actividad haz algo como esto:

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

De esta forma, podrá iniciar diferentes actividades llamadas desde diferentes OutsideClass sin tener que jugar con banderas.

Nota: intente no almacenar en caché el objeto de contexto a través del constructor para el fragmento (con el adaptador, está bien). Un fragmento debe tener un constructor vacío, de lo contrario la aplicación se bloquea en algunos escenarios.

recuerda llamar

 OutsideClass.gettingContext(Context context); 

en la función onResume () también.

También tuve el mismo problema. Verifica todo el contexto que has pasado. Para ‘ enlaces ‘, necesita Contexto de actividad, no contexto de aplicación .

Este es el lugar donde debes verificar:

1.) Si usó LayoutInflater, entonces verifique el contexto que ha pasado.

2.) Si está utilizando cualquier adaptador, verifique el contexto que ha pasado.

Yo tuve el mismo problema. El problema es con el contexto. Si desea abrir cualquier enlace (por ejemplo, compartir cualquier enlace a través del selector), pase el contexto de la actividad, no el contexto de la aplicación.

No olvides agregar myIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK) si no estás en tu actividad.

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

Espero que esto funcione.

Enfrentado al mismo problema luego implementado
intent.addFlags (Intent.FLAG_ACTIVITY_NEW_TASK);
y se resolvió el problema.

Puede haber otro motivo relacionado con el adaptador de vista de lista.
puedes ver este blog , lo describió muy bien.

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

usa este código funciona bien para mí; Compartir algo desde fuera de una actividad

  Intent intent = new Intent(Intent.ACTION_SEND); intent.setType("text/plain"); // Append Text String 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 está invocando el plugin Compartir intención en Cordova, configurar la bandera no ayudará. En lugar de usar esto,

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

Mi situación era un poco diferente, estoy probando mi aplicación usando Espresso y tuve que iniciar mi actividad con ActivityTestRule desde el Context de la instrumentación (que no proviene de una Activity ).

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

Tuve que cambiar las banderas y agregar una or bitwise ( | en Java) con Intent.FLAG_ACTIVITY_NEW_TASK

Entonces resulta en:

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

Dado que la adición de indicadores afecta a event_flow y stack_history, es mejor pasar el ‘contexto de la aplicación’ a la no actividad desde donde necesita llamar a una clase de actividad de la siguiente manera:

“ActivityClassName.this” (Mientras pasa el contexto de esta manera, contendrá todos los detalles y la información que necesita para llamar a una actividad desde un escenario sin actividad)

Por lo tanto, no es necesario establecer ni agregar indicadores, esto funcionará bien en todos los casos.