Bir Etkinliğin dışından startActivity () çağrılsın mı?


196

AlarmManagerBir sinyal yayınlayan bir amacı tetiklemek için kullanıyorum . Kodum şudur:

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

Bu kodu birinden arıyorum Activity, bu yüzden nasıl aşağıdaki hatayı alıyorum bilmiyorum ...

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?

Yanıtlar:


494

Android sürümünüz Android - 6'nın altındaysa, bu satırı eklemeniz gerekir, aksi takdirde Android - 6'nın üstünde çalışır.

...
Intent i = new Intent(this, Wakeup.class);
i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
...

8
evet bu işe yarıyor. ancak aynı Etkinliğin birden çok örneğini başlatmak istiyorsanız bu çalışmaz. FLAG_ACTIVITY_NEW_TASK aynı mevcut Etkinliğe devam edeceğinden
Ovidiu Latcu


Dikkat edin, Android 9+ üzerinde de buna ihtiyacınız var, açıklamalar için bu cevaba bakın
Vadim Kotov

55

Aynı etkinliğin Birden Çok Örneği için aşağıdaki snippet'i kullanın,

Not : Bu pasaj, benim dışımda kullanıyorum Activity. AndroidManifestDosyanızın içermediğinden emin olun android:launchMode="singleTop|singleInstance". gerekirse bunu değiştirebilirsiniz 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);

Bu benim için iyi çalışıyor. Umarım, bu birisi için zaman kazandırır. Birisi daha iyi bir yol bulursa, lütfen bizimle paylaşın.


5
Lütfen setFlags () ve addFlag () yöntemleri arasındaki farkı anlayın. Şu anda tek yaptığınız FLAG_ACTIVITY_NEW_TASK ile bir etkinlik başlatmak. Aşağıdaki Cristian tarafından yayınlanan kodda olduğu gibi.
JehandadK

-------------------------------------------------- ----------------- i.addFlag (Intent.FLAG_ACTIVITY_MULTIPLE_TASK); i.addFlag (Intent.FLAG_ACTIVITY_NEW_TASK); -------------------------------------------------- ----------------- i.setFlags (Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_MULTIPLE_TASK);
JehandadK

43

Android Doc diyor -

FLAG_ACTIVITY_NEW_TASK gereksinimi uygulandı

Android 9 ile, FLAG_ACTIVITY_NEW_TASK niyet bayrağını geçmedikçe etkinlik dışı bir bağlamdan etkinlik başlatamazsınız. Bu bayrağı geçmeden bir etkinlik başlatmaya çalışırsanız, etkinlik başlatılmaz ve sistem günlüğe bir ileti yazdırır.

Not: İşaret gereksinimi her zaman amaçlanan davranış olmuştur ve Android 7.0'dan (API düzey 24) daha düşük sürümlerde uygulanmıştır. Android 7.0'daki bir hata, bayrak gereksiniminin uygulanmasını engelledi.

Bu , bir bağlamın dışından çağrı yaparken (Build.VERSION.SDK_INT <= Build.VERSION_CODES.M) || (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P)eklemek zorunludur .Intent.FLAG_ACTIVITY_NEW_TASKstartActivity()Activity

Bu nedenle, tüm sürümler için bayrak eklemek daha iyidir -

...
Intent i = new Intent(this, Wakeup.class);
i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
...

12

Aradığınız kısmı yapıştırmadınız startActivity, ilginç kısım bu.

startActivityBir Servicebağlamda veya bir bağlamda arıyor olabilirsiniz Application.

startActivityÇağrı yapmadan önce kediyi günlüğe kaydetmek için "this" yazdırabilir ve ne demek istediğini görebilirsiniz.


1
Bu muhtemelen OP'nin yaşadığı sorundur. Aynı şeyle karşılaştım. Mevcut bir etkinlik yerine getApplicationContext () ile bir etkinliğin başlatılması bu hatayı tetikler.
Hazen Hills Yazılımı

GÜZEL :) Bu bütün akşam tespit etmeye çalıştığım hata oldu eminim. Teşekkürler, bayım.
Martin Pfeffer

9

Bazen bu hata açık bir çağrı yapılmadan ortaya çıkabilir startActivity(...). Örneğin, bazılarınız Crashlytics'te böyle bir yığın izini görmüş olabilirsiniz:

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)

Ne yaptığınızı merak edebilirsiniz, çünkü izleme yalnızca çerçeve kodunu içerir. İşte bunun nasıl olabileceğine bir örnek. Diyelim ki bir parçadayız.

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!!

Artık bir kullanıcı bu metin görünümünü tıkladığında, uygulamanız yukarıdaki yığın izlemesiyle kilitlenecektir. Bunun nedeni mizanpaj şişiricisinin uygulama içeriğine bir başvurusu olması ve bu nedenle metin görünümünüzün bir uygulama içeriğinin olmasıdır. Bu metin görünümünü tıklamak dolaylı olarak çağırır appContext.startActivity(...).

Son not: Bunu Android 4, 5, 6 ve 7 cihazlarda test ettim. Sadece 4, 5 ve 6'yı etkiliyor. Android 7 cihazlarının arama yapma konusunda hiçbir sorunu yok appContext.startActivity(...).

Umarım bunun bir başkasına yardımı olur!


2

En son Android cihazlarında 9 ve 10'da Bildirim alma durumunda karşılaştığım aynı hata.

Nasıl başlatacağınız Launch moduna bağlıdır. Aşağıdaki kodu kullanın: - android: launchMode = "singleTask"

Bu bayrağı Amaç ile ekleyin: - intent.setFlags (Intent.FLAG_ACTIVITY_NEW_TASK);


1

Bu satıra geçmeyi deneyin:

PendingIntent pendingIntent = PendingIntent.getBroadcast(getContext(), 0, i, 0);

1

Sadece startActivitybir etkinliğin dışarıdan bazı android sürümlerinde (N ve O-MR1 arasında) geçerli olduğunu ve ilginç nokta bunun android kaynak kodunda bir hata olduğunu fark etmek istiyorum!


Bu, yukarıdaki startActivityuygulamanın yorumudur. Buraya bakın .

Arayanın etkinliğin başlatılması gereken görev kimliğini belirtmesi dışında, FLAG_ACTIVITY_NEW_TASK içermeyen bir etkinliğin dışından başlatma etkinliğini çağırmaya genellikle izin verilmez. N ve O-MR1 arasında bunun çalışmasına izin veren bir hata vardı .


bunun için çözüm nedir
dominic_torreto

0

Uygulamanızda bir etkinlik açmak istediğinizde, bir Intent as parametresiyle startActivity () yöntemini çağırabilirsiniz. Bu niyet, açmak istediğiniz etkinlik olacaktır. İlk önce bağlam, ikinci parametre hedeflenen aktivite sınıfı olacak şekilde bu niyette bir nesne oluşturmanız gerekir.

Intent intent = new Intent(this, Activity_a.class);
startActivity(intent);

Umarım bu yardımcı olur.


3
Yorumcum olarak yazıyorum çünkü cevabınız düşük kalite için işaretlendi. Bu cevabın eksikliği, kodunuzun ne yaptığı veya soruda ortaya çıkan sorunu neden çözdüğüne dair bir açıklama olmamasıdır. Lütfen, birçok programcının cevabınızı gelecekte rehberlik için okuyabileceğini aklınızda bulundurarak bazı açıklayıcı yorumlar ekler misiniz? Teşekkür ederim!
Bill Bell

Uygulamanızda bir etkinlik açmak istediğinizde, bir Intent as parametresiyle startActivity () yöntemini çağırabilirsiniz. Bu niyet, açmak istediğiniz etkinlik olacaktır. İlk önce bağlam, ikinci parametre hedeflenen aktivite sınıfı olacak şekilde bu niyette bir nesne oluşturmanız gerekir. Umarım bu yardımcı olur.
Md. Shafiqur Rahman

TAMAM. Ancak bu bilgiyi bir yorum yapmak yerine cevabınızı düzenlemeli ve oraya koymalısınız. Bu noktadan dolayı pişmanım ama her cevap için bunu yapmak önemlidir. Saygılarımla.
Bill Bell

Evet, lütfen cevabınızın neden doğru olduğuna dair açıklamalar ekleyin. Daha iyi programcı olmayı sadece yaptığımız şeyleri neden yaptığımızı öğrendiğimizde öğreniyoruz.
kiwicomb123
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.