¿Llamar a startActivity () desde fuera de una actividad?

196

Estoy usando un AlarmManagerpara activar una intención que transmite una señal. El siguiente es mi código:

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

Llamo a este código desde un Activity, así que no sé cómo podría obtener el siguiente error ...

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
fuente

Respuestas:

494

si su versión de Android está por debajo de Android - 6, entonces necesita agregar esta línea; de lo contrario, funcionará por encima de Android - 6.

...
Intent i = new Intent(this, Wakeup.class);
i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
...
Cristian
fuente
8
Si esto funciona. pero si desea iniciar varias instancias de la misma Actividad, esto no funciona. Dado que FLAG_ACTIVITY_NEW_TASK reanudará la misma Actividad existente
Ovidiu Latcu el
77
Agregue la bandera FLAG_ACTIVITY_Multiple_TASKS PARA RESOLVER SU problema
Pavankumar Vijapur
Tenga cuidado, también necesita esto en Android 9+, vea esta respuesta para aclaraciones
Vadim Kotov
55

Para la instancia múltiple de la misma actividad, use el siguiente fragmento,

Nota : este fragmento, lo estoy usando fuera de mi Activity. Asegúrese de que su AndroidManifestarchivo no contenga android:launchMode="singleTop|singleInstance". si es necesario, puede cambiarlo a 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);

Esto funciona bien para mi. Espero que esto ahorre tiempo para alguien. Si alguien encuentra una mejor manera, comparta con nosotros.

Nandagopal T
fuente
55
Por favor, comprenda la diferencia entre los métodos setFlags () y addFlag (). Todo lo que está haciendo ahora es lanzar una actividad con FLAG_ACTIVITY_NEW_TASK. Como en el código publicado por Cristian a continuación.
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 dice:

El requisito FLAG_ACTIVITY_NEW_TASK ahora se aplica

Con Android 9, no puede iniciar una actividad desde un contexto de no actividad a menos que pase el indicador de intención FLAG_ACTIVITY_NEW_TASK. Si intenta iniciar una actividad sin pasar este indicador, la actividad no se inicia y el sistema imprime un mensaje en el registro.

Nota: El requisito de marca siempre ha sido el comportamiento previsto, y se aplicaba en versiones inferiores a Android 7.0 (nivel de API 24). Un error en Android 7.0 impidió el cumplimiento del requisito de marca.

Eso significa (Build.VERSION.SDK_INT <= Build.VERSION_CODES.M) || (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P)que es obligatorio agregar Intent.FLAG_ACTIVITY_NEW_TASKmientras se llama startActivity()desde fuera de un Activitycontexto.

Por lo tanto, es mejor agregar un indicador para todas las versiones:

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

No pegaste la parte donde llamas startActivity, esa es la parte interesante.

Puede estar llamando startActivityen un Servicecontexto o en un Applicationcontexto.

Imprima "this" para registrar el gato antes de hacer la startActivityllamada, y vea a qué se refiere, a veces es un caso de usar accidentalmente un "this" interno.

marmor
fuente
1
Este es probablemente el problema que tiene OP. Me he encontrado con lo mismo. Lanzar una actividad con getApplicationContext () en lugar de una actividad existente activará este error.
Hazen Hills Software
NICE :) Estoy bastante seguro de que este fue el error que trato de detectar toda la noche. Gracias Señor.
Martin Pfeffer
9

A veces, este error puede ocurrir sin una llamada explícita a startActivity(...). Por ejemplo, algunos de ustedes pueden haber visto un rastro de pila como este en 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)

Y es posible que se pregunte qué hizo mal, ya que la traza solo incluye código de marco. Bueno, aquí hay un ejemplo de cómo puede suceder esto. Digamos que estamos en un fragmento.

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!!

Ahora, cuando un usuario hace clic en esa vista de texto, su aplicación se bloqueará con el seguimiento de la pila anterior. Esto se debe a que el inflador de diseño tiene una referencia al contexto de la aplicación y, por lo tanto, su vista de texto tiene un contexto de aplicación. Al hacer clic en esa vista de texto, las llamadas están implícitamenteappContext.startActivity(...) .

Nota final: probé esto en dispositivos Android 4, 5, 6 y 7. Solo afecta a 4, 5 y 6. Aparentemente, los dispositivos Android 7 no tienen problemas para llamar appContext.startActivity(...).

¡Espero que esto ayude a alguien más!

Aplicaciones autónomas
fuente
2

Este mismo error me he enfrentado en caso de recibir notificaciones en los últimos dispositivos Android 9 y 10.

Depende del modo de inicio cómo lo esté manejando. Utilice el siguiente código: - android: launchMode = "singleTask"

Agregue este indicador con Intent: - intent.setFlags (Intent.FLAG_ACTIVITY_NEW_TASK);

Puneet Kumar
fuente
1

Intenta cambiar a esta línea:

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

Solo quiero notar que startActivity desde afuera una actividad es válida en algunas versiones de Android (entre N y O-MR1) y lo interesante es que es un error en el código fuente de Android!


Este es el comentario de la startActivityimplementación anterior . Ver aquí .

Por lo general, no se permite llamar a la actividad de inicio desde fuera de una actividad sin FLAG_ACTIVITY_NEW_TASK, excepto si la persona que llama especifica la identificación de la tarea en la que se debe iniciar la actividad. Hubo un error entre N y O-MR1 que permitió que esto funcionara .

Fartab
fuente
cuál es la solución para eso
dominic_torreto
0

Cuando desee abrir una actividad dentro de su aplicación, puede llamar al método startActivity () con un Intent como parámetro. Esa intención sería la actividad que desea abrir. Primero debe crear un objeto de esa intención con el primer parámetro como contexto y el segundo parámetro como la clase de actividad objetivo.

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

Espero que esto ayude.

MD Shafiqur Rahman
fuente
3
Estoy escribiendo como revisor porque su respuesta se ha marcado como de baja calidad. La desventaja de esta respuesta es que no hay una explicación de lo que hace su código o de por qué resuelve el problema planteado en la pregunta. ¿Podría agregar algunos comentarios explicativos, teniendo en cuenta que muchos programadores podrían leer su respuesta en el futuro para obtener orientación? ¡Gracias!
Bill Bell
Cuando desee abrir una actividad dentro de su aplicación, puede llamar al método startActivity () con un Intent como parámetro. Esa intención sería la actividad que desea abrir. Primero debe crear un objeto de esa intención con el primer parámetro como contexto y el segundo parámetro como clase de actividad objetivo. Espero que esto ayude.
Md. Shafiqur Rahman
OKAY. Pero en lugar de poner esa información en un comentario, debe editar su respuesta y ponerla allí. Lamento haber insistido en este punto, pero es importante hacerlo para cada respuesta. Atentamente.
Bill Bell
Sí, incluya explicaciones de por qué su respuesta es correcta. Solo aprendemos a ser mejores programadores cuando aprendemos POR QUÉ hacemos las cosas que hacemos.
kiwicomb123