AlarmManager
を使用して、信号をブロードキャストするインテントをトリガーしています。以下は私のコードです:
AlarmManager mgr = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
Intent i = new Intent(this, Wakeup.class);
try
{
PendingIntent pi = PendingIntent.getBroadcast(this, 0, i, 0);
Long elapsed += // sleep time;
mgr.set(AlarmManager.RTC_WAKEUP, elapsed, pi);
}
catch(Exception r)
{
Log.v(TAG, "RunTimeException: " + r);
}
この変数をActivity
から呼び出しているので、次のエラーがどのように発生するかわかりません...
ERROR/AndroidRuntime(7557): Java.lang.RuntimeException: Unable to start receiver com.wcc.Wakeup: Android.util.AndroidRuntimeException: Calling startActivity() from outside of an Activity context requires the FLAG_ACTIVITY_NEW_TASK flag. Is this really what you want?
AndroidバージョンがAndroid-6未満の場合、この行を追加する必要があります。そうしないと、Android-6より上で動作します。
...
Intent i = new Intent(this, Wakeup.class);
i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
...
同じアクティビティの複数インスタンスの場合、次のスニペットを使用します。
注:このスニペットは、Activity
以外で使用しています。 AndroidManifest
ファイルにAndroid:launchMode="singleTop|singleInstance"
が含まれていないことを確認してください。必要に応じて、Android:launchMode="standard"
に変更できます。
Intent i = new Intent().setClass(mActivity.getApplication(), TestUserProfileScreenActivity.class);
i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_MULTIPLE_TASK);
// Launch the new activity and add the additional flags to the intent
mActivity.getApplication().startActivity(i);
これは私には問題ありません。これが誰かの時間を節約することを願っています。誰かがより良い方法を見つけたら、私たちと共有してください。
Android Doc 言う-
FLAG_ACTIVITY_NEW_TASK要件が実施されました
Android 9では、インテントフラグFLAG_ACTIVITY_NEW_TASKを渡さない限り、非アクティビティコンテキストからアクティビティを開始できません。このフラグを渡さずにアクティビティを開始しようとすると、アクティビティは開始されず、システムはログにメッセージを出力します。
注:フラグの要件は常に意図された動作であり、Android 7.0(APIレベル24)よりも低いバージョンで適用されました。 Android 7.0のバグにより、フラグ要件が適用されませんでした。
つまり、(Build.VERSION.SDK_INT <= Build.VERSION_CODES.M) || (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P)
の場合、Activity
コンテキストの外部からstartActivity()
を呼び出しているときにIntent.FLAG_ACTIVITY_NEW_TASK
を追加する必要があります。
したがって、すべてのバージョンにフラグを追加することをお勧めします-
...
Intent i = new Intent(this, Wakeup.class);
i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
...
startActivity
を呼び出す部分は貼り付けませんでした。これは興味深い部分です。
startActivity
コンテキストまたはService
コンテキストでApplication
を呼び出している可能性があります。
startActivity
呼び出しを行う前にcatをログに記録するために "this"を出力し、それが何を参照しているかを確認します。
このエラーは、startActivity(...)
を明示的に呼び出さなくても発生する場合があります。たとえば、一部のユーザーはCrashlyticsで次のようなスタックトレースを見たことがあります。
Fatal Exception: Android.util.AndroidRuntimeException: Calling startActivity() from outside of an Activity context requires the FLAG_ACTIVITY_NEW_TASK flag. Is this really what you want?
at Android.app.ContextImpl.startActivity(ContextImpl.Java:1597)
at Android.app.ContextImpl.startActivity(ContextImpl.Java:1584)
at Android.content.ContextWrapper.startActivity(ContextWrapper.Java:337)
at Android.text.style.URLSpan.onClick(URLSpan.Java:62)
at Android.text.method.LinkMovementMethod.onTouchEvent(LinkMovementMethod.Java:217)
at Android.widget.TextView.onTouchEvent(TextView.Java:9522)
at Android.view.View.dispatchTouchEvent(View.Java:8968)
at Android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.Java:2709)
at Android.view.ViewGroup.dispatchTouchEvent(ViewGroup.Java:2425)
at Android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.Java:2709)
at Android.view.ViewGroup.dispatchTouchEvent(ViewGroup.Java:2425)
at Android.widget.AbsListView.dispatchTouchEvent(AbsListView.Java:5303)
at Android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.Java:2709)
at Android.view.ViewGroup.dispatchTouchEvent(ViewGroup.Java:2425)
at Android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.Java:2709)
at Android.view.ViewGroup.dispatchTouchEvent(ViewGroup.Java:2425)
at Android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.Java:2709)
at Android.view.ViewGroup.dispatchTouchEvent(ViewGroup.Java:2425)
at Android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.Java:2709)
at Android.view.ViewGroup.dispatchTouchEvent(ViewGroup.Java:2425)
at Android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.Java:2709)
at Android.view.ViewGroup.dispatchTouchEvent(ViewGroup.Java:2425)
at Android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.Java:2709)
at Android.view.ViewGroup.dispatchTouchEvent(ViewGroup.Java:2425)
at Android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.Java:2709)
at Android.view.ViewGroup.dispatchTouchEvent(ViewGroup.Java:2425)
at Android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.Java:2709)
at Android.view.ViewGroup.dispatchTouchEvent(ViewGroup.Java:2425)
at Android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.Java:2709)
at Android.view.ViewGroup.dispatchTouchEvent(ViewGroup.Java:2425)
at Android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.Java:2709)
at Android.view.ViewGroup.dispatchTouchEvent(ViewGroup.Java:2425)
at Android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.Java:2709)
at Android.view.ViewGroup.dispatchTouchEvent(ViewGroup.Java:2425)
at com.Android.internal.policy.impl.PhoneWindow$DecorView.superDispatchTouchEvent(PhoneWindow.Java:2559)
at com.Android.internal.policy.impl.PhoneWindow.superDispatchTouchEvent(PhoneWindow.Java:1767)
at Android.app.Activity.dispatchTouchEvent(Activity.Java:2866)
at Android.support.v7.view.WindowCallbackWrapper.dispatchTouchEvent(WindowCallbackWrapper.Java:67)
at Android.support.v7.view.WindowCallbackWrapper.dispatchTouchEvent(WindowCallbackWrapper.Java:67)
at com.Android.internal.policy.impl.PhoneWindow$DecorView.dispatchTouchEvent(PhoneWindow.Java:2520)
at Android.view.View.dispatchPointerEvent(View.Java:9173)
at Android.view.ViewRootImpl$ViewPostImeInputStage.processPointerEvent(ViewRootImpl.Java:4706)
at Android.view.ViewRootImpl$ViewPostImeInputStage.onProcess(ViewRootImpl.Java:4544)
at Android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.Java:4068)
at Android.view.ViewRootImpl$InputStage.onDeliverToNext(ViewRootImpl.Java:4121)
at Android.view.ViewRootImpl$InputStage.forward(ViewRootImpl.Java:4087)
at Android.view.ViewRootImpl$AsyncInputStage.forward(ViewRootImpl.Java:4201)
at Android.view.ViewRootImpl$InputStage.apply(ViewRootImpl.Java:4095)
at Android.view.ViewRootImpl$AsyncInputStage.apply(ViewRootImpl.Java:4258)
at Android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.Java:4068)
at Android.view.ViewRootImpl$InputStage.onDeliverToNext(ViewRootImpl.Java:4121)
at Android.view.ViewRootImpl$InputStage.forward(ViewRootImpl.Java:4087)
at Android.view.ViewRootImpl$InputStage.apply(ViewRootImpl.Java:4095)
at Android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.Java:4068)
at Android.view.ViewRootImpl.deliverInputEvent(ViewRootImpl.Java:6564)
at Android.view.ViewRootImpl.doProcessInputEvents(ViewRootImpl.Java:6454)
at Android.view.ViewRootImpl.enqueueInputEvent(ViewRootImpl.Java:6425)
at Android.view.ViewRootImpl$WindowInputEventReceiver.onInputEvent(ViewRootImpl.Java:6654)
at Android.view.InputEventReceiver.dispatchInputEvent(InputEventReceiver.Java:185)
at Android.os.MessageQueue.nativePollOnce(MessageQueue.Java)
at Android.os.MessageQueue.next(MessageQueue.Java:143)
at Android.os.Looper.loop(Looper.Java:130)
at Android.app.ActivityThread.main(ActivityThread.Java:5942)
at Java.lang.reflect.Method.invoke(Method.Java)
at Java.lang.reflect.Method.invoke(Method.Java:372)
at com.Android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.Java:1400)
at com.Android.internal.os.ZygoteInit.main(ZygoteInit.Java:1195)
トレースにはフレームワークコードしか含まれていないため、何が間違っているのか疑問に思うかもしれません。さて、これがどのように起こるかの例です。私たちがフラグメントにいるとしましょう。
Activity activity = getActivity();
Context activityContext = activity;
Context appContext = activityContext.getApplicationContext();
LayoutInflater inflater = LayoutInflater.from(appContext); // whoops!
View view = inflater.inflate(R.layout.some_layout, parent, false);
TextView tvWithLinks = (TextView) view.findViewById(R.id.tv_with_links);
tvWithLinks.setMovementMethod(LinkMovementMethod.getInstance()); // whoops!!
これで、ユーザーがそのテキストビューをクリックすると、上記のスタックトレースでアプリがクラッシュします。これは、layout inflaterにapplication contextへの参照があるため、text viewにアプリケーションコンテキストがあるためです。そのテキストビューをクリックすると暗黙的にがappContext.startActivity(...)
を呼び出します。
最後のメモ:Android 4、5、6、および7デバイスでこれをテストしました。 4、5、および6にのみ影響します。Android 7デバイスは、appContext.startActivity(...)
を呼び出すのに問題がないようです。
これが他の誰かに役立つことを願っています!
アプリケーションコンテキスト(つまり、getApplication(); getApplicationContext();
)の代わりに、この場合はアクティビティコンテキストを使用する必要があります---> YourActivity.this
次の行に変更してみてください。
PendingIntent pendingIntent = PendingIntent.getBroadcast(getContext(), 0, i, 0);
アクティビティの外部からのstartActivity
が一部のAndroidバージョン(NとO-MR1の間)で有効であり、興味深い点はAndroidソースのバグであることに注意してください。コード!
これは、startActivity
実装の上のコメントです。 here を参照してください。
FLAG_ACTIVITY_NEW_TASKを使用せずにアクティビティの外部から開始アクティビティを呼び出すことは、呼び出し元がアクティビティを起動するタスクIDを指定している場合を除き、通常は許可されません。これは動作します。
アプリ内でアクティビティを開く場合は、パラメーターとしてIntentを指定してstartActivity()メソッドを呼び出すことができます。その意図は、開きたいアクティビティになります。最初に、コンテキストとなる最初のパラメーターとターゲットアクティビティクラスとなる2番目のパラメーターを使用して、その目的のオブジェクトを作成する必要があります。
Intent intent = new Intent(this, Activity_a.class);
startActivity(intent);
これが役立つことを願っています。