Вызов функции startActivity() извне контекста активности

Я применил ListView в своем приложении для Android. Я привязываюсь к этому ListView с помощью пользовательского подкласса класса ArrayAdapter. Внутри переопределенного метода ArrayAdapter.getView(...) я назначаю OnClickListener. В методе onClick OnClickListener я хочу запустить новое действие. Я получаю исключение:

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

Как я могу получить Context, что работает ListView (текущий Activity)?

Ответ 1

Либо

  • кешировать объект Context через конструктор в вашем адаптере или
  • получить его из вашего представления.

Или, в крайнем случае,

  • добавить флаг FLAG_ACTIVITY_NEW_TASK в свои намерения:

_

myIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);

Изменить - я бы избегал установки флагов, поскольку это будет мешать нормальному потоку событий и стека истории.

Ответ 2

Вы можете достичь этого с помощью addFlags вместо setFlags

myIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);

Согласно документации это делает:

Добавьте дополнительные флаги к цели (или с существующим значением флагов).


РЕДАКТИРОВАТЬ

Имейте в виду, что если вы используете флаги, вы меняете стек истории, как сказал Алексей Воловой:

... избегайте установки флагов, так как это будет мешать нормальному потоку событий и стека истории.

Ответ 3

Вместо использования (getApplicationContext) используйте YourActivity.this

Ответ 4

Если вы получили ошибку из-за использования create chooser, как показано ниже:

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

Установите флаг для создания выбора:

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

Ответ 5

Я думаю, что, возможно, вы внедряете OnClickListener в неподходящее место - обычно вам нужно обязательно реализовать OnItemClickListener в своей деятельности и вместо этого установить его в ListView, иначе у вас появятся проблемы с вашими событиями...

Ответ 6

Кроме того: если вы показываете ссылки в списке в фрагменте, не создавайте его так

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

вместо вызова

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

В обоих случаях адаптер работает нормально, но ссылки работают только в последнем.

Ответ 7

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

или же

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

изменить на ниже

CustomAdapter mAdapter = new CustomAdapter( this, yourlist);

Ответ 8

См., если вы создаете намерение в списке в каком-то методе

override onClick (View v).

затем вызовите контекст через это представление:

v.getContext ()

Вам даже не нужны SetFlags...

Ответ 9

Для любого, кто получает это на Xamarin.Android(MonoDroid), даже когда StartActivity вызывается из активности - это на самом деле ошибка Xamarin с новым временем выполнения ART, см. https://bugzilla.xamarin.com/show_bug.cgi?id=17630

Ответ 10

Эта ошибка возникает, когда стартовая активность не знает, чем он занимается. Таким образом, вы должны добавить активность перед startActivity()

вы должны установить

context.startActivity(yourIntent);

Ответ 11

На мой взгляд, лучше использовать метод startActivity() только в вашем коде Activity.class. Если вы используете это в Adapter или другом классе, это приведет к этому.

Ответ 12

Разрабатывая Алекс Воловой, ответьте немного больше -

в случае, если u получает эту проблему с фрагментами, getActivity() отлично работает, чтобы получить контекст

В других случаях:

Если вы не хотите использовать -

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

затем создайте такую ​​функцию в OutsideClass -

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

Теперь, в своем основном действии, когда вы делаете новый OutsideClass, вызывается вышеупомянутый метод сразу же после того, как вы определяете OutsideClass, предоставляя контекст активности в качестве аргумента. Также в вашем основном действии сделайте функцию -

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

теперь вернитесь к OutsideClass, и чтобы начать новую деятельность, сделайте что-то вроде этого -

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

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

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

Таким образом, вы сможете запускать различные действия, вызываемые из другого OutsideClass, не испортив флаги.

Примечание. Не пытайтесь кэшировать объект-контекст через конструктор для фрагмента (с адаптером, его тонким). У фрагмента должен быть пустой конструктор, в противном случае приложение вылетает в некоторых сценариях.

не забудьте позвонить

OutsideClass.gettingContext(Context context);

в функции onResume().

Ответ 13

У меня также была та же проблема. Проверьте весь контекст, который вы прошли. Для ссылок для этого требуется Контекст Контекст < Контекст приложения.

Это место, где вы должны проверить:

1.) Если вы использовали LayoutInflater, то проверьте, в каком контексте вы прошли.

2.) Если вы используете любой Адаптер, проверьте, в каком контексте вы прошли.

Ответ 14

У меня была та же проблема. Проблема связана с контекстом. Если вы хотите открыть какие-либо ссылки (например, поделитесь любой ссылкой с помощью выбора), перейдите в контекст активности, а не в контекст приложения.

Не забудьте добавить myIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK), если вы не в своей деятельности.

Ответ 15

Используйте этот код в вашей Adapter_Activity и используйте context.startActivity(intent_Object) и intent_Object.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);

Как это:

Intent n_act = new Intent(context, N_Activity.class);
n_act.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(n_act);

Оно работает....

Ответ 16

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

Надеюсь, что это сработает.

Ответ 17

Столкнулся с той же проблемой, а затем реализовал

intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);

и получил решение проблемы.

Может быть другая причина, связанная с адаптером представления списка.
Вы можете увидеть этот блог, описал его очень хорошо.

Ответ 18

Используйте этот код. У меня отлично работает. Поделитесь чем-то извне деятельности:

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

Ответ 19

Поскольку добавление флагов влияет на event_flow и stack_history лучше передать "контекст приложения" в stack_history из которого необходимо вызвать класс действия следующим образом:

"ActivityClassName.this" (если вы передадите контекст таким образом, он будет содержать все детали и информацию, необходимые для вызова действия из сценария бездействия)

Таким образом, нет необходимости устанавливать или добавлять флаги, это будет работать нормально в каждом случае.

Ответ 20

На Android 28(Android P) startActivity

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

Так что лучше всего добавить 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);

Ответ 21

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

Ответ 22

Если вы вызываете share Intent в плагине Кордовы, установка флажка не поможет. Вместо этого используйте это -

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

Ответ 23

Моя ситуация немного отличалась, я тестирую свое приложение с помощью Espresso и мне пришлось запустить Activity с ActivityTestRule из Context инструментария (который не является результатом Activity).

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

Мне пришлось изменить флаги и добавить or побитовый (| в Java) с Intent.FLAG_ACTIVITY_NEW_TASK

Так что это приводит к:

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

Ответ 24

Я просто хочу заметить, что startActivity извне действия действует в некоторых версиях Android (между N и O-MR1), и интересным моментом является то, что это ошибка в исходном коде Android!


Это комментарий выше реализации startActivity. Смотрите здесь

Вызов начального действия извне действия без FLAG_ACTIVITY_NEW_TASK, как правило, не допускается, за исключением случаев, когда вызывающая сторона указывает идентификатор задачи, в котором должно быть запущено действие. Между N и O-MR1 существовала ошибка, которая позволяла этому работать.

Ответ 25

Котлин версия

val intent = Intent(Intent.ACTION_EDIT, ContactsContract.Profile.CONTENT_URI)
intent.flags = Intent.FLAG_ACTIVITY_NEW_TASK
this.startActivity(intent)