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

Estoy usando un AlarmManager para activar un bash 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); } 

Estoy llamando a este código de una Activity , por lo 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? 

¿Qué pasa si agrega esta línea?

 ... Intent i = new Intent(this, Wakeup.class); i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); ... 

Para Instancias Múltiples de la misma actividad, use el siguiente fragmento,

Nota : Este fragmento, lo estoy usando fuera de mi Activity . Asegúrate de que tu archivo AndroidManifest no contenga android:launchMode="singleTop|singleInstance" . si es necesario, puedes 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, esto ahorra tiempos para alguien. Si alguien encuentra una mejor manera, por favor, comparta con nosotros.

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

Es posible que llame a startActivity en un contexto de Service o en un contexto de Application .

Imprima “this” para registrar cat antes de hacer la llamada de startActivity , y vea a qué se refiere, a veces es un caso de usar un “esto” interno accidentalmente.

A veces, este error puede ocurrir sin una llamada explícita a startActivity(...) . Por ejemplo, algunos de ustedes pueden haber visto un seguimiento de stack 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 puede preguntarse 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 stack 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 se llama implícitamente a appContext.startActivity(...) .

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

¡Espero que esto ayude a alguien más!

Android Docs dice:

El requisito FLAG_ACTIVITY_NEW_TASK ahora se aplica

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

Nota: El requisito de bandera siempre ha sido el comportamiento previsto, y se aplicaba en versiones inferiores a Android 7.0 (API nivel 24). Un error en Android 7.0 evitó que se aplicara el requisito de bandera.

Eso significa que para (Build.VERSION.SDK_INT <= Build.VERSION_CODES.M) && (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) es obligatorio agregar Intent.FLAG_ACTIVITY_NEW_TASK al llamar a startActivity() desde fuera de una Activity contexto.

Entonces, es mejor agregar un indicador para todas las versiones:

 ... Intent i = new Intent(this, Wakeup.class); i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); ... 

Intenta cambiar a esta línea:

 PendingIntent pendingIntent = PendingIntent.getBroadcast(getContext(), 0, i, 0); 

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

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

Espero que esto ayude

en lugar del contexto de la aplicación (es decir, getApplication(); getApplicationContext(); ) necesita usar el contexto de la actividad en este caso —> YourActivity.this