アクティビティコンテキスト外からのstartActivity()の呼び出し


367

ListViewAndroidアプリケーションにを実装しました。クラスの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いるを取得するにはどうすればよいですか?ListViewActivity


1
Alexの答えは、より一般的な方法であなたが言及したエラーを修正するため、問題に対する「受け入れられた」解決策であると思います
devanshu_kaushik

10
「これは本当にあなたが欲しいのですか?」...その前に、「どこかで放送受信機の登録を解除することを忘れていませんか?」というメッセージがありました。驚くばかり!これらの小さなメッセージをすべて入れて、私たちがしゃがむのを手伝ってくれる人には敬意を表します。
Nerdy Bunz 2016年

1
私はこの問題に会いました。targetSdkVersionを28に更新したとき
illusionJJ

回答:


574

どちらか

  • アダプターのコンストラクターを介してContextオブジェクトをキャッシュする、または
  • あなたの視点からそれを取得します。

または最後の手段として、

  • 追加-FLAG_ACTIVITY_NEW_TASKフラグをインテントに追加します。

_

myIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);

編集-イベントと履歴スタックの通常のフローを妨害するため、フラグの設定を避けます。


6
システムによって作成されたインテント(およびフラグ)を制御できないTextViewのオートリンク機能についてはどうですか?
Alex Semeniuk 2013

75
私がこのようなことをしているときに私がこのタイプからタイプにcontext.startActivity(intent);変更contextApplicationContextたときに、この例外が発生しましたActivity。これで問題が解決しました。
スーフィアン2013年

@AlexSemeniukはこれまでに解決策を見つけましたか?

@AlexSemeniuk-アクティビティーをコンテキストとしてアダプターに渡す限り、autoLinkは機能します
Georges

コンストラクターを介してContextオブジェクトを渡しましたが、機能しません。FLAG_ACTIVITY_NEW_TASKは非常にうまく機能しています。
Hiren

100

あなたは代わりにaddFlagsでそれを達成することができますsetFlags

myIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);

ドキュメントによると、それはします:

インテントにフラグを追加します(または既存のフラグ値を使用)。


編集

Alex Volovoyの答えが言うように、履歴スタックを変更するフラグを使用している場合は注意してください。

...フラグを設定しないでください。フラグを設定すると、イベントと履歴スタックの通常のフローが妨げられます。


1
非常に似た問題があります。上記の答えが示唆するように、履歴スタックまたは何か他の問題を経験しましたか?
Einar Sundgren 2013年

1
あなたが探しているものは正確にはわかりませんが、そのような履歴なしでアクティビティを開始できます:Intent intent = new Intent(Intent.ACTION_VIEW、 "http:\\ www.google.com")); intent。 addFlags(Intent.FLAG_ACTIVITY_NO_HISTORY); startActivity(intent);
Bruno Bieri

ここでaddFlagsを推奨しないのはなぜですか?イベントと履歴スタックの通常のフローを妨害することはどれほど重要ですか?
Jason Krs 2018年

@JasonKrsはaddFlagsを使用できます。追加するフラグに応じて履歴スタックを変更できることに注意してください。FLAG_ACTIVITY_NEW_TASKはこの状況で使用できます。詳細については読む:developer.android.com/reference/android/content/...
ブルーノBieri


40

以下のような作成チューザーを使用したためにエラーが発生した場合:

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

4
とても役に立ちました。厳密にセレクターインテントにはこのフラグが必要です!
Mahdi、

2
これが正しいsoluctionある、としなければならない、まさに、intent.chooserでNEW_TASK
ラファエル・ギマランイス

15

加えて、フラグメントのリストビューにリンクを表示する場合は、このように作成しないでください

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

代わりに電話する

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

アダプターはどちらの場合も正常に機能しますが、リンクは最後の1つでのみ機能します。


@ user2676468:これで自動リンクの問題が解決しました。
オタクのヘッド、2014

フラグを使用する代わりに、これは受け入れられる答えである必要があります。
ガストンSaillén

@GastónSaillén、私は使用しませんgetApplicationContext()(アプリケーションの初期化を除く)が、この例外をキャッチしました。したがって、状況は異なる場合があります。
CoolMind

これは私の問題でした、私はコンテキストにgetApplicationContext()を使用しました。thisコンテキストとして設定すると、現在のアクティビティに関連して機能します。
Brlja

14

OnClickListenerを間違った場所に実装していると思います。通常、アクティビティにOnItemClickListenerを確実に実装し、代わりにListViewに設定する必要があります。そうしないと、イベントで問題が発生します...


2
あなたは私を解決策に導きます。ListViewに割り当てられたOnItemClickListenerを使用する必要がありました。他の人のためのリンクをいくつか紹介します:developer.android.com/reference/android/widget/…androidpeople.com/… 助けて くれてありがとう。
Sako73

一般的な答えを入力してください。以下のAlex Volovoyの答えは、一般的な方法で問題を解決します。
devanshu_kaushik 2012年

後世のために:コンポーネントでsetListener(new Listener)として直接定義する場合、コンテキストが必要な場合、信じられないようなメモリリークを引き起こすアクティビティ全体への暗黙の参照を作成します。これは、静的内部クラスリスナーを作成するか、複数の起点からの入力を処理する必要がある場合はリスナーを別のクラスに移動することで回避できます。
G_V 2015年

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

または

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

下に変更

CustomAdapter mAdapter = new CustomAdapter( this, yourlist);

8

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

これは28以上のデバイスに必要です。
Md Mohsin

7

何らかの方法でlistiner内にインテントを作成している場合は、参照してください

override onClick (View v).

次に、このビューからもコンテキストを呼び出します。

v.getContext ()

SetFlagsも必要ありません...


そして、何が悪い状況でしたか?v.getApplicationContext()?
CoolMind

3

StartActivityがアクティビティから呼び出された場合でも、Xamarin.Android(MonoDroid)でこれを取得している人は、これは実際には新しいARTランタイムのXamarinのバグです。https ://bugzilla.xamarin.com/show_bug.cgi?id = 17630を参照してください


ええ、あなたは上で説明したことをしなければならないだけですが、言い回しが変更されました... intent.SetFlags(ActivityFlags.NewTask);
ルークアルダートン

3

Alex Volovoyの回答についてもう少し詳しく-

フラグメントでこの問題が発生している場合、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()関数でも同様です。


3

このエラーは、startactivityが彼のアクティビティを知らない場合に発生します。したがって、startActivity()の前にアクティビティを追加する必要があります

あなたが設定する必要があります

context.startActivity(yourIntent);

startActivityから呼び出す場合Fragment、呼び出し元はアクティビティではなくフラグメントであることがよくあります。
CoolMind

2

私の意見startActivity()では、のコードでのみのメソッドを使用する方が良いActivity.classです。Adapterまたは他のクラスでそれを使用すると、その結果になります。


2

私も同じ問題を抱えていました。渡したすべてのコンテキストを確認してください。「リンク」の場合は、アプリケーションコンテキストではなくアクティビティコンテキストが必要です。

これはあなたがチェックするべき場所です:

1.)LayoutInflaterを使用した場合は、渡したコンテキストを確認します。

2.)アダプタを使用している場合は、渡したコンテキストを確認してください。


2

私も同じ問題を抱えていました。問題はコンテキストにあります。リンクを開く(たとえば、チューザを介してリンクを共有する)場合は、アプリケーションコンテキストではなく、アクティビティコンテキストを渡します。

myIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)アクティビティに参加していない場合は、忘れずに追加してください。


2

このコードを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);

できます....


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

これがうまくいくことを願っています。


1

同じ問題に直面して実装された

intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);

問題を解決しました。

リストビューアダプターに関連する別の理由がある可能性があります。
あなたはこのブログを見ることができ、それを非常によく説明しました。


役立つブログ、ありがとうございます。:)
Rucha Bhatt Joshi 2017

1

このコードを使用します。私にとってはうまくいきます。アクティビティの外部から何かを共有する:

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

フラグを追加するevent_flowと、stack_history、あなたが次のようにアクティビティクラスを呼び出す必要がどこから非活動に「アプリケーションコンテキスト」を渡す方が良いです。

"ActivityClassName.this"(この方法でコンテキストを渡す間、非アクティビティシナリオからアクティビティを呼び出すために必要なすべての詳細と情報が含まれます)

したがって、フラグを設定または追加する必要はありません。これは、すべての場合で正常に機能します。


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

0

Cordovaプラグインで共有インテントを呼び出す場合、フラグを設定しても効果がありません。代わりにこれを使用してください-

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

0

私の状況は少し異なっていました。私は使用して自分のアプリをテストしているため、インストルメンテーション(からのものではない)からEspressoアクティビティを起動する必要がありました。ActivityTestRuleContextActivity

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)

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.