Chiamare startActivity () dall'esterno di un'attività?


196

Sto usando un AlarmManagerper innescare un intento che trasmette un segnale. Il seguente è il mio codice:

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

Sto chiamando questo codice da un Activity, quindi non so come potrei ottenere il seguente errore ...

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?

Risposte:


494

se la tua versione di Android è inferiore ad Android - 6, devi aggiungere questa linea, altrimenti funzionerà sopra Android - 6.

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

8
si questo funziona. ma se si desidera avviare più istanze della stessa attività, ciò non funziona. Poiché FLAG_ACTIVITY_NEW_TASK riprenderà la stessa attività esistente
Ovidiu Latcu,

7
Aggiungi flag FLAG_ACTIVITY_Multiple_TASK PER RISOLVERE IL TUO problema
Pavankumar Vijapur

Attenzione, ne hai bisogno anche su Android 9+, vedi questa risposta per chiarimenti
Vadim Kotov

55

Per Istanza multipla della stessa attività, utilizza il frammento seguente,

Nota : questo frammento che sto utilizzando al di fuori del mio Activity. Assicurati che il tuo AndroidManifestfile non contenga android:launchMode="singleTop|singleInstance". se necessario, puoi cambiarlo in 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);

Questo funziona bene per me. Spero, questo fa risparmiare tempo a qualcuno. Se qualcuno trova un modo migliore, per favore condividi con noi.


5
Comprendi la differenza tra i metodi setFlags () e addFlag (). Tutto quello che stai facendo ora è avviare un'attività con FLAG_ACTIVITY_NEW_TASK. Come nel codice pubblicato da Cristian di seguito.
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:

Il requisito FLAG_ACTIVITY_NEW_TASK è ora applicato

Con Android 9, non è possibile avviare un'attività da un contesto di non attività se non si passa il flag di intento FLAG_ACTIVITY_NEW_TASK. Se si tenta di avviare un'attività senza passare questo flag, l'attività non si avvia e il sistema stampa un messaggio nel registro.

Nota: il requisito flag è sempre stato il comportamento previsto ed è stato applicato su versioni precedenti ad Android 7.0 (livello API 24). Un bug in Android 7.0 ha impedito l'applicazione del flag flag.

Ciò significa (Build.VERSION.SDK_INT <= Build.VERSION_CODES.M) || (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P)che è obbligatorio aggiungere Intent.FLAG_ACTIVITY_NEW_TASKdurante la chiamata startActivity()dall'esterno di un Activitycontesto.

Quindi è meglio aggiungere flag per tutte le versioni -

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

12

Non hai incollato la parte in cui chiami startActivity, questa è la parte interessante.

Potresti chiamare startActivityin un Servicecontesto o in un Applicationcontesto.

Stampa "questo" per registrare il gatto prima di effettuare la startActivitychiamata e vedere a cosa si riferisce, a volte è un caso di usare un "questo" interno per sbaglio.


1
Questo è probabilmente il problema con OP. Ho incontrato lo stesso. L'avvio di un'attività con getApplicationContext () invece di un'attività esistente attiverà questo errore.
Hazen Hills Software

BELLO :) Sono abbastanza sicuro che questo sia stato l'errore che cerco di individuare tutta la sera. Grazie signore.
Martin Pfeffer,

9

A volte questo errore può verificarsi senza una chiamata esplicita a startActivity(...). Ad esempio, alcuni di voi potrebbero aver visto una traccia dello stack come questa in 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)

E potresti chiederti cosa hai fatto di sbagliato, poiché la traccia include solo il codice del framework. Bene, ecco un esempio di come ciò possa accadere. Diciamo che siamo in un frammento.

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

Ora, quando un utente fa clic su quella vista di testo, l'app si arresta in modo anomalo con la traccia dello stack sopra. Questo perché il gonfiatore del layout ha un riferimento al contesto dell'applicazione , quindi la vista di testo ha un contesto dell'applicazione. Cliccando su quella vista di testo si chiama implicitamenteappContext.startActivity(...) .

Nota finale: l'ho testato su dispositivi Android 4, 5, 6 e 7. Colpisce solo 4, 5 e 6. Apparentemente i dispositivi Android 7 non hanno problemi a chiamare appContext.startActivity(...).

Spero che questo aiuti qualcun'altro!


2

Lo stesso errore che ho riscontrato in caso di ricezione di notifiche negli ultimi dispositivi Android 9 e 10.

Dipende dalla modalità di avvio come la stai gestendo. Usa sotto il codice: - android: launchMode = "singleTask"

Aggiungi questo flag con Intent: - intent.setFlags (Intent.FLAG_ACTIVITY_NEW_TASK);


1

Prova a passare a questa linea:

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

1

Voglio solo notare che startActivityda fuori un'attività è valida in alcune versioni di Android (tra N e O-MR1) e il punto interessante è che è un bug nel codice sorgente di Android!


Questo è il commento sopra l' startActivityimplementazione. Vedi qui .

La chiamata dell'attività di avvio dall'esterno di un'attività senza FLAG_ACTIVITY_NEW_TASK non è generalmente consentita, tranne se il chiamante specifica l'id dell'attività in cui deve essere avviata l'attività. Tra N e O-MR1 esisteva un bug che consentiva il funzionamento .


qual è la soluzione per questo
dominic_torreto

0

Quando desideri aprire un'attività all'interno della tua app, puoi chiamare il metodo startActivity () con un parametro Intent come. Quell'intenzione sarebbe l'attività che si desidera aprire. Per prima cosa devi creare un oggetto con quell'intento con il primo parametro come contesto e il secondo parametro come classe di attività target.

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

Spero che questo possa aiutare.


3
Sto scrivendo come revisore perché la tua risposta è stata contrassegnata come di bassa qualità. Il difetto di questa risposta è che non c'è spiegazione di ciò che fa il tuo codice o del motivo per cui risolve il problema posto nella domanda. Vorresti per favore aggiungere alcuni commenti esplicativi, tenendo presente che molti programmatori potrebbero leggere la tua risposta in futuro come guida. Grazie!
Bill Bell,

Quando desideri aprire un'attività all'interno della tua app, puoi chiamare il metodo startActivity () con un parametro Intent come. Quell'intenzione sarebbe l'attività che si desidera aprire. Per prima cosa devi creare un oggetto con quell'intento con il primo parametro come contesto e il secondo parametro come classe di attività target. Spero che questo possa aiutare.
Md. Shafiqur Rahman,

OK. Invece di inserire tali informazioni in un commento, è necessario modificare la risposta e inserirla lì. Mi dispiace di non aver detto questo punto, ma è importante farlo per ogni risposta. I migliori saluti.
Bill Bell,

Sì, includi spiegazioni sul perché la tua risposta è corretta. Impariamo a essere programmatori migliori solo quando apprendiamo PERCHÉ facciamo le cose che facciamo.
kiwicomb123
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.