Memanggil startActivity () dari luar Aktivitas?

196

Saya menggunakan a AlarmManageruntuk memicu niat yang menyiarkan sinyal. Berikut ini adalah kode saya:

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

Saya memanggil kode ini dari Activity, jadi saya tidak tahu bagaimana saya bisa mendapatkan kesalahan berikut ...

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?
Tom G
sumber

Jawaban:

494

jika versi Android Anda di bawah Android - 6 maka Anda perlu menambahkan baris ini jika tidak akan bekerja di atas Android - 6.

...
Intent i = new Intent(this, Wakeup.class);
i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
...
Cristian
sumber
8
ya ini berhasil. tetapi jika Anda ingin memulai beberapa contoh dari Kegiatan yang sama ini tidak berfungsi. Karena FLAG_ACTIVITY_NEW_TASK akan melanjutkan kembali Kegiatan yang ada
Ovidiu Latcu
7
Tambahkan bendera FLAG_ACTIVITY_Multiple_TASKS UNTUK MENYELESAIKAN masalah ANDA
Pavankumar Vijapur
Hati-hati, Anda memerlukan ini di Android 9+ juga, lihat jawaban ini untuk klarifikasi
Vadim Kotov
55

Untuk Beberapa Instance dari aktivitas yang sama, gunakan cuplikan berikut,

Catatan : Cuplikan ini, saya gunakan di luar Activity. Pastikan AndroidManifestfile Anda tidak mengandung android:launchMode="singleTop|singleInstance". jika perlu, Anda dapat mengubahnya ke 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);

Ini berfungsi baik untuk saya. Semoga ini menghemat waktu untuk seseorang. Jika ada yang menemukan cara yang lebih baik, silakan berbagi dengan kami.

Nandagopal T
sumber
5
Harap mengerti perbedaan antara metode setFlags () dan addFlag (). Yang Anda lakukan sekarang adalah meluncurkan aktivitas dengan FLAG_ACTIVITY_NEW_TASK. Seperti pada kode yang diposting oleh Cristian di bawah ini.
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
42

Android Doc mengatakan -

Persyaratan FLAG_ACTIVITY_NEW_TASK sekarang diberlakukan

Dengan Android 9, Anda tidak dapat memulai aktivitas dari konteks non-aktivitas kecuali Anda melewati flag niat FLAG_ACTIVITY_NEW_TASK. Jika Anda mencoba untuk memulai suatu kegiatan tanpa melewati flag ini, aktivitas tersebut tidak dimulai, dan sistem mencetak pesan ke log.

Catatan: Persyaratan bendera selalu merupakan perilaku yang dimaksudkan, dan diberlakukan pada versi yang lebih rendah dari Android 7.0 (API level 24). Bug di Android 7.0 mencegah persyaratan bendera ditegakkan.

Itu artinya untuk (Build.VERSION.SDK_INT <= Build.VERSION_CODES.M) || (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P)itu wajib menambahkan Intent.FLAG_ACTIVITY_NEW_TASKsambil menelepon startActivity()dari luar Activitykonteks.

Jadi lebih baik menambahkan bendera untuk semua versi -

...
Intent i = new Intent(this, Wakeup.class);
i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
...
Hrishikesh Kadam
sumber
12

Anda tidak menempel bagian yang Anda panggil startActivity , itu bagian yang menarik.

Anda mungkin memanggil startActivitydalam Servicekonteks, atau dalam Applicationkonteks.

Cetak "ini" untuk mencatat kucing sebelum melakukan startActivitypanggilan, dan lihat apa yang dimaksud, kadang-kadang kasus penggunaan batin "ini" secara tidak sengaja.

marmor
sumber
1
Ini kemungkinan masalah OP miliki. Saya pernah mengalami hal yang sama. Meluncurkan aktivitas dengan getApplicationContext () alih-alih aktivitas yang ada akan memicu kesalahan ini.
Hazen Hills Software
BAGUS :) Saya cukup yakin ini adalah kesalahan saya mencoba untuk melihat sepanjang malam. Terima kasih, Tuan.
Martin Pfeffer
9

Terkadang kesalahan ini dapat terjadi tanpa panggilan eksplisit ke startActivity(...). Misalnya, beberapa dari Anda mungkin telah melihat jejak tumpukan seperti ini di 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)

Dan Anda mungkin bertanya-tanya apa yang Anda lakukan salah, karena jejaknya hanya mencakup kode kerangka kerja. Nah, inilah contoh bagaimana ini bisa terjadi. Katakanlah kita berada dalam sebuah fragmen.

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

Sekarang, ketika pengguna mengklik pada tampilan teks itu, aplikasi Anda akan macet dengan jejak tumpukan di atas. Ini karena inflater tata letak memiliki referensi ke konteks aplikasi , dan karenanya tampilan teks Anda memiliki konteks aplikasi. Mengklik pada tampilan teks itu secara implisit memanggil appContext.startActivity(...).

Catatan akhir: Saya menguji ini pada perangkat Android 4, 5, 6, dan 7. Ini hanya memengaruhi 4, 5, dan 6. Perangkat Android 7 tampaknya tidak memiliki masalah saat memanggil appContext.startActivity(...).

Saya harap ini membantu orang lain!

Aplikasi Autonomous
sumber
2

Kesalahan yang sama ini saya hadapi jika mendapat Notifikasi di perangkat Android terbaru 9 dan 10.

Tergantung pada mode Luncurkan bagaimana Anda menanganinya. Gunakan kode di bawah ini: - android: launchMode = "singleTask"

Tambahkan bendera ini dengan Intent: - intent.setFlags (Intent.FLAG_ACTIVITY_NEW_TASK);

Puneet Kumar
sumber
1

Coba ubah ke baris ini:

PendingIntent pendingIntent = PendingIntent.getBroadcast(getContext(), 0, i, 0);
Luís Ledebour
sumber
1

Saya hanya ingin memperhatikan bahwa startActivitydari luar suatu kegiatan valid di beberapa versi android (antara N dan O-MR1) dan yang menarik adalah bahwa itu adalah bug dalam kode sumber android!


Inilah komentar startActivityimplementasi di atas . Lihat di sini .

Memanggil aktivitas mulai dari luar aktivitas tanpa FLAG_ACTIVITY_NEW_TASK pada umumnya tidak diizinkan, kecuali jika penelepon menentukan id tugas tempat aktivitas tersebut akan diluncurkan. Ada bug antara N dan O-MR1 yang memungkinkan ini berfungsi .

Fartab
sumber
apa solusi untuk itu
dominic_torreto
0

Ketika Anda ingin membuka suatu aktivitas di dalam aplikasi Anda maka Anda dapat memanggil metode startActivity () dengan parameter Intent as. Niat itu adalah aktivitas yang ingin Anda buka. Pertama, Anda harus membuat objek maksud itu dengan parameter pertama untuk menjadi konteks dan parameter kedua untuk menjadi kelas aktivitas yang ditargetkan.

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

Semoga ini bisa membantu.

Md. Shafiqur Rahman
sumber
3
Saya menulis sebagai resensi karena jawaban Anda telah ditandai untuk berkualitas rendah. Kelemahan dari jawaban ini adalah bahwa tidak ada penjelasan tentang apa yang kode Anda lakukan atau mengapa itu memecahkan masalah yang diajukan dalam pertanyaan. Tolong tambahkan beberapa komentar penjelasan, dengan mengingat bahwa banyak programmer dapat membaca jawaban Anda di masa depan untuk panduan. Terima kasih!
Bill Bell
Ketika Anda tidak ingin membuka suatu aktivitas di dalam aplikasi Anda maka Anda dapat memanggil metode startActivity () dengan parameter Intent as. Niat itu adalah aktivitas yang ingin Anda buka. Pertama, Anda harus membuat objek maksud itu dengan parameter pertama untuk menjadi konteks dan parameter kedua untuk menjadi kelas aktivitas yang ditargetkan. Semoga ini bisa membantu.
Md. Shafiqur Rahman
BAIK. Tetapi alih-alih memasukkan informasi itu dalam komentar, Anda harus mengedit jawaban Anda dan menaruhnya di sana. Saya menyesal mempercayai hal ini tetapi penting untuk melakukan ini untuk setiap jawaban. Salam Hormat.
Bill Bell
Ya, harap sertakan penjelasan mengapa jawaban Anda benar. Kami hanya belajar untuk menjadi programmer yang lebih baik ketika kami belajar MENGAPA kami melakukan hal-hal yang kami lakukan.
kiwicomb123