Wywołanie funkcji startActivity () spoza kontekstu aktywności

Zaimplementowałem ListView w mojej aplikacji na Androida. I bind to ListView using a custom subclass of the ArrayAdapter class. Wewnątrz nadpisanej metody ArrayAdapter.getView(...) przypisuję OnClickListener. W metodzie onClick OnClickListener chcę uruchomić nową aktywność. Dostaję wyjątek:

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

Jak mogę uzyskać Context, pod którym działa ListView (bieżący Activity)?

Author: user, 2010-10-12

25 answers

Albo

  • buforuj obiekt kontekstowy za pomocą konstruktora w adapterze lub
  • / Align = "left" /

Lub w ostateczności,

  • Dodaj flagę-FLAG_ACTIVITY_NEW_TASK do swojej intencji:

_

myIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);

Edit-unikałbym ustawiania FLAG, ponieważ będzie to zakłócać normalny przepływ zdarzenia i stos historii.

 603
Author: Alex Volovoy,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-09-12 15:50:28

Możesz to osiągnąć za pomocą addFlags zamiast setFlags

myIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);

Zgodnie z dokumentacją robi:

Dodaj dodatkowe flagi do intencji (lub z istniejącą wartością flags).


EDIT

Bądź świadomy, jeśli używasz flag, które zmieniasz stos historii jako Alex Volovoy ' s answer says:

...unikaj ustawiania FLAG, ponieważ będzie to zakłócać normalny przepływ zdarzeń i historii stack.

 103
Author: Bruno Bieri,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-11-14 06:43:52

Zamiast (getApplicationContext) użyj YourActivity.this

 66
Author: Jeffrey Nyauke,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-07-27 08:44:42

Jeśli masz błąd z powodu użycia create chooser jak poniżej:

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

Ustaw flagę, aby utworzyć wybór w następujący sposób:

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);
 51
Author: sanath_p,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2020-02-02 20:37:17

Dodatkowo: jeśli pokażesz linki w listview we fragmencie , nie twórz tego w ten sposób

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

Zamiast wywołać

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

Adapter działa dobrze w obu przypadkach, ale linki działają tylko w ostatnim.

 15
Author: djdance,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-04-12 09:17:38

Myślę, że może implementujesz onclicklistener w niewłaściwym miejscu - zazwyczaj powinieneś zdecydowanie zaimplementować OnItemClickListener w swojej aktywności i zamiast tego ustawić go na ListView, lub będziesz miał problemy z wydarzeniami...

 14
Author: mreichelt,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-10-12 20:14:51
CustomAdapter mAdapter = new CustomAdapter( getApplicationContext(), yourlist);

Lub

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

Zmień na poniżej

CustomAdapter mAdapter = new CustomAdapter( this, yourlist);
 9
Author: Murtaza Ashraf,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-04-12 09:17:17

Na początku Android 28(Android P)

if ((intent.getFlags() & Intent.FLAG_ACTIVITY_NEW_TASK) == 0
        && (targetSdkVersion < Build.VERSION_CODES.N
                || targetSdkVersion >= Build.VERSION_CODES.P)
        && (options == null
                || ActivityOptions.fromBundle(options).getLaunchTaskId() == -1)) {
    throw new AndroidRuntimeException(
            "Calling startActivity() from outside of an Activity "
                    + " context requires the FLAG_ACTIVITY_NEW_TASK flag."
                    + " Is this really what you want?");
}

Więc najlepszym sposobem jest dodanie FLAG_ACTIVITY_NEW_TASK

Intent intent = new Intent(context, XXXActivity.class);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
    intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
}
context.startActivity(intent);
 9
Author: Alen Lee,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-08-14 08:29:00

Zobacz, jeśli tworzysz intencję wewnątrz listinera w jakiejś metodzie

override onClick (View v).

Następnie wywołaj kontekst również przez ten Widok:

v.getContext ()

Nie będzie nawet potrzebne SetFlags ...

 8
Author: Paulo Linhares - Packapps,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-03-11 12:44:43

Dla każdego, kto ma to na Xamarin.Android (MonoDroid) nawet gdy StartActivity jest wywoływany z activity - jest to błąd Xamarin z nowym uruchomieniem Art, Zobacz https://bugzilla.xamarin.com/show_bug.cgi?id=17630

 3
Author: rouen,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-02-25 15:19:42

Rozwinięcie odpowiedzi Alexa Volovoya trochę bardziej-

Jeśli u dostajesz ten problem z fragmentami, getActivity() działa dobrze, aby uzyskać kontekst

W Innych Przypadkach:

Jeśli nie chcesz używać -

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

Następnie stwórz taką funkcję w swoim OutsideClass-

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

Teraz, w Twojej głównej aktywności, gdy kiedykolwiek wykonasz Nowy OutsideClass wywołaj powyższą metodę natychmiast po zdefiniowaniu OutsideClass podając kontekst działania jako argument. Również w swojej głównej aktywności stwórz funkcję -

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

Teraz wróć do swojej zewnętrznej Eklasy i aby rozpocząć nową aktywność, zrób coś takiego -

@Override
public void onClick(View v) {
........
case R.id.any_button:

            MainActivity mainAct = (MainActivity) real_context;             
            mainAct.startNewActivity("ACTIVITY_KEY");                   

        break;
    }
........
}

W ten sposób będziesz mógł rozpocząć różne działania nazwane z różnych zewnętrznych klas bez bałaganu z flagami.

Notatka-staraj się nie buforować obiektu kontekstowego za pomocą konstruktora dla fragmentu(z adapterem,jest w porządku).Fragment powinien mieć pusty konstruktor w przeciwnym razie aplikacja ulegnie awarii w niektórych scenariuszach.

Pamiętaj o call

OutsideClass.gettingContext(Context context);

W funkcji onResume ().

 3
Author: Flying Monkey,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-11-16 16:20:22

Ten błąd pojawia się, gdy startactivity nie wie, która jest jego aktywność. Więc musisz dodać aktywność przed startActivity ()

Musisz ustawić

context.startActivity(yourIntent);
 3
Author: Cabezas,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-07-19 09:46:50

Moim zdaniem lepiej użyć metody startActivity() tylko w kodzie Activity.class. Jeśli użyjesz tego w Adapter lub innej klasie, spowoduje to.

 2
Author: kaosmys,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-08-28 03:44:13

Też miałem ten sam problem. Sprawdź cały kontekst, który przeszedłeś. Dla 'links ' potrzebny jest kontekst aktywności a nie kontekst aplikacji.

To jest miejsce, w którym powinieneś sprawdzić:

1.) Jeśli użyłeś LayoutInflater to sprawdź jaki kontekst przeszedłeś.

2.) Jeśli używasz dowolnego Adaptera sprawdź, jaki kontekst przeszedłeś.

 2
Author: codemaniac,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-06-12 07:06:40

Miałem ten sam problem. Problem tkwi w kontekście. Jeśli chcesz otworzyć dowolne łącza (na przykład udostępnić dowolne łącze przez wybór), podaj kontekst aktywności, a nie kontekst aplikacji.

Nie zapomnij dodać myIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK), jeśli nie jesteś w swojej aktywności.

 2
Author: Coder29,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-12-21 14:00:40

Użyj tego kodu w adapter_activity i użyj context.startActivity(intent_Object) i intent_Object.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);

Tak:

Intent n_act = new Intent(context, N_Activity.class);
n_act.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(n_act);
To Działa....
 2
Author: Gaurav Lambole,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-04-12 09:12:04
Intent viewIntent = new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS);    
viewIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);    
startActivity(viewIntent);   
Mam nadzieję, że to zadziała.
 1
Author: Chirag Patel,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-09-11 06:26:36

Napotkał ten sam problem, a następnie zaimplementował

intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
I rozwiązałem problem.

Może być inny powód, który jest związany z list view adapter.
Można zobaczyć ten blog , opisał go bardzo dobrze.

 1
Author: Mayank Sharma,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-04-12 09:08:42

Użyj tego kodu. Mi pasuje. Udostępnij coś spoza aktywności:

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);
 1
Author: Pooya Hayati,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-04-12 09:10:12

Ponieważ dodanie FLAG wpływa na event_flow i stack_history lepiej jest przekazać 'kontekst aplikacji' do non-activity, z którego należy wywołać klasę activity w następujący sposób:

"ActivityClassName.to " (gdy przekazujesz kontekst w ten sposób, będzie on zawierał wszystkie szczegóły i informacje potrzebne do wywołania aktywności ze scenariusza braku aktywności)

Więc nie ma potrzeby, aby ustawić lub dodać flagi, to będzie działać dobrze w każdym przypadku.

 1
Author: Musthafa,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-04-12 09:12:54
Intent i= new Intent(context, NextActivity.class);
i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_SINGLE_TOP);
 0
Author: Chandan Lal,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-09-08 12:02:53

Jeśli wywołujesz zamiar akcji w Cordova plugin, ustawienie flagi nie pomoże. Zamiast tego użyj tego -

cordova.getActivity().startActivity(Intent.createChooser(shareIntent, "title"));
 0
Author: Sandeep Kumar,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-11-27 17:41:12

Moja sytuacja była trochę inna, testuję moją aplikację za pomocą Espresso i musiałem uruchomić moją aktywność z ActivityTestRule z oprzyrządowania Context (który nie pochodzi z Activity).

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

Musiałem zmienić flagi i dodać or bitowe (| w Javie) z Intent.FLAG_ACTIVITY_NEW_TASK

Więc daje:

fun intent(context: Context) = 
    Intent(context, HomeActivity::class.java)
        .addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP or Intent.FLAG_ACTIVITY_NEW_TASK)
 0
Author: Rafael Ruiz Muñoz,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-04-12 09:11:39

Wersja Kotlina

val intent = Intent(Intent.ACTION_EDIT, ContactsContract.Profile.CONTENT_URI)
intent.flags = Intent.FLAG_ACTIVITY_NEW_TASK
this.startActivity(intent)
 0
Author: Sazzad Hissain Khan,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2020-06-20 09:12:55

W aktywności (gdzie wywołujesz adapter) po prostu zmień getActivityContext() na YourActivity.this. Oto exemple:

yourAdapter = new YourAdapter(yourList, YourActivity.this); // Here YourActivity.this is the Context instead of getActivityContext()
recyclerView.setAdapter(yourAdapter);
 0
Author: Félix Maroy,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2020-09-29 12:23:24