Вызов функции 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)