web-dev-qa-db-ja.com

Activityコンテキストの外部からstartActivity()を呼び出す

私は自分のAndroidアプリケーションにListViewを実装しました。 ListViewクラスのカスタムサブクラスを使用して、このArrayAdapterにバインドします。オーバーライドされたArrayAdapter.getView(...)メソッドの中で、私はOnClickListenerを割り当てます。 onClickOnClickListenerメソッドで、私は新しいアクティビティを立ち上げたいです。私は例外を得ます:

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

Context(現在のListView)が動作しているActivityを取得する方法

317
Sako73

どちらでも

  • アダプタのコンストラクタを介してContextオブジェクトをキャッシュする。
  • あなたの見解からそれを入手してください。

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

  • あなたの意図にFLAG_ACTIVITY_NEW_TASKフラグを追加:

_

myIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);

編集 - イベントや履歴スタックの通常の流れを妨げるので、フラグの設定は避けます。

514
Alex Volovoy

setFlagsの代わりにaddFlagsで実現できます。

myIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);

ドキュメント によると、

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


編集

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

イベントや履歴スタックの通常の流れを妨げるので、フラグの設定は避けてください。

89
Bruno Bieri

(getApplicationContext)を使用する代わりにYourActivity.thisを使用してください

54
Jeffrey Nyauke

以下のように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);
29
sanath_p

OnClickListenerを間違った場所に実装しているのではないかと思います。通常は、必ずOnItemClickListenerをActivityに実装し、代わりにListViewに設定する必要があります。そうしないと、問題が発生します。

13
mreichelt

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

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

代わりに呼び出す

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

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

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

または

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

以下に変更してください

CustomAdapter mAdapter = new CustomAdapter( this, yourlist);
7
Murtaza Ashraf

何らかの方法でlistiner内にインテントを作成しているかどうか見てください

override onClick (View v).

それからこのビューを通してコンテキストを呼び出します。

v.getContext ()

SetFlagsさえ必要ないでしょう...

このエラーはstartactivityがどちらが彼のアクティビティなのかわからないときに起こります。だからstartActivity()の前にアクティビティを追加しなければなりません

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

activity.startActivity(yourIntent);
3
Cabezas

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

3
rouen

私の意見では、Activity.classのコードの中でstartActivity()のメソッドを使うほうが良いです。あなたがAdapterや他のクラスでそれを使うと、それはそれになるでしょう。

2
kaosmys

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

活動していない場合は、myIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)を追加することを忘れないでください。

2
Coder29

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を定義した直後にアクティビティのコンテキストを引数として与えて、すぐに上記のメソッドを呼び出してください。またあなたの主な活動で機能を作りなさい -

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()関数でも同様です。

2
Flying Monkey

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

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

1.)あなたがLayoutInflaterを使ったなら、あなたがどんなコンテキストを渡したかチェックしてください。

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

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

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

1
Chirag Patel

その後実装された同じ問題に直面しました

intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);

そして問題を解決しました。

リストビューアダプタに関連している別の理由があるかもしれません。
このブログ をよくご覧になれます。

1
Mayank Sharma

このコードを使ってください。私にとってはうまくいきます。活動の外から何かを共有する:

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
Pooya Hayati

このコードを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
Gaurav Lambole

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);
1
Alen Lee

フラグを追加することはevent_flowstack_historyに影響を与えるので、次のようにしてアクティビティクラスを呼び出す必要があるところから 'application context'を非アクティビティに渡す方が良いです:

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

そのため、フラグを設定または追加する必要はありません。これはどの場合でもうまく機能します。

0
Musthafa

Cordovaプラグインでshare Intentを起動している場合、フラグを設定しても意味がありません。代わりにこれを使用してください -

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

コトリン版

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

私の状況は少し異なっていました、私はEspressoname__を使って私のアプリをテストしています、そして私はActivityTestRulename__(Contextname__から来たものではありません)からActivityname__で私のActivityを立ち上げなければなりませんでした。

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

フラグを変更し、|を使ってorname__ビット単位(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)
0
Intent i= new Intent(context, NextActivity.class);
i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_SINGLE_TOP);
0
Chandan Lal