Aplikasi Android saya dipanggil oleh maksud yang meneruskan informasi (pendingintent di statusbar).
Ketika saya menekan tombol beranda dan membuka kembali aplikasi saya dengan menahan tombol beranda, itu memanggil maksud lagi dan ekstra yang sama masih ada.
@Override
public void onSaveInstanceState(Bundle savedInstanceState) {
super.onSaveInstanceState(savedInstanceState);
}
@Override
public void onRestoreInstanceState(Bundle savedInstanceState) {
super.onRestoreInstanceState(savedInstanceState);
}
ini adalah kode yang tidak berjalan seperti yang seharusnya
String imgUrl;
Bundle extras = this.getIntent().getExtras();
if(extras != null){
imgUrl = extras.getString("imgUrl");
if( !imgUrl.equals(textView01.getText().toString()) ){
imageView.setImageDrawable( getImageFromUrl( imgUrl ) );
layout1.setVisibility(0);
textView01.setText(imgUrl);//textview to hold the url
}
}
Dan maksud saya:
public void showNotification(String ticker, String title, String message,
String imgUrl){
String ns = Context.NOTIFICATION_SERVICE;
NotificationManager mNotificationManager =
(NotificationManager) getSystemService(ns);
int icon = R.drawable.icon; // icon from resources
long when = System.currentTimeMillis(); // notification time
CharSequence tickerText = ticker; // ticker-text
//make intent
Intent notificationIntent = new Intent(this, activity.class);
notificationIntent.putExtra("imgUrl", imgUrl);
notificationIntent.setFlags(
PendingIntent.FLAG_UPDATE_CURRENT |
PendingIntent.FLAG_ONE_SHOT);
PendingIntent contentIntent =
PendingIntent.getActivity(this, 0,
notificationIntent, PendingIntent.FLAG_UPDATE_CURRENT |
PendingIntent.FLAG_ONE_SHOT);
//make notification
Notification notification = new Notification(icon, tickerText, when);
notification.setLatestEventInfo(this, title, message, contentIntent);
//flags
notification.flags = Notification.FLAG_SHOW_LIGHTS |
Notification.FLAG_ONGOING_EVENT |
Notification.FLAG_ONLY_ALERT_ONCE |
Notification.FLAG_AUTO_CANCEL;
//sounds
notification.defaults |= Notification.DEFAULT_SOUND;
//notify
mNotificationManager.notify(1, notification);
}
Adakah cara untuk menghapus maksud atau memeriksa apakah sudah digunakan sebelumnya?
android
android-intent
Mars
sumber
sumber
Jawaban:
MEMPERBARUI:
Saya tidak menyadari bahwa jawaban ini akan begitu banyak dirujuk ketika saya pertama kali menulisnya lebih dari 5 tahun yang lalu!
Saya akan menjelaskan untuk menunjukkan bahwa sesuai dengan jawaban @ tato-rodrigo ini tidak akan membantu Anda mendeteksi maksud yang sudah ditangani dalam beberapa situasi.
Saya juga harus menunjukkan bahwa saya meletakkan "jelas" dalam tanda kutip karena suatu alasan - Anda tidak benar - benar membersihkan maksud dengan melakukan ini, Anda hanya menggunakan penghapusan ekstra sebagai tanda bahwa maksud ini telah dilihat oleh aktivitas .
Saya memiliki masalah yang persis sama.
Jawaban di atas menempatkan saya di jalur yang benar dan saya menemukan solusi yang lebih sederhana, gunakan:
pemanggilan metode untuk "menghapus" Intent.
Agak terlambat menjawab karena ini ditanyakan setahun yang lalu, tapi semoga ini membantu orang lain di masa depan.
sumber
setIntent(new Intent())
dan bekerja dengan baik sekarang.EDIT: Saya mengedit untuk memposting solusi lengkap yang saya gunakan.
Solusi ini akan berfungsi jika masalahnya adalah "Tidak menjalankan beberapa kode saat aktivitas dimulai dari Riwayat (Aplikasi Terbaru)" .
Pertama-tama, nyatakan a
boolean
di AndaActivity
untuk menunjukkan jikaIntent
sudah digunakan:Kemudian, simpan dan pulihkan nilai ini dengan aman menggunakan metode
onSaveInstanceState
danonCreate
untuk menangani perubahan konfigurasi dan kasus yang dapat mematikan sistemActivity
saat Anda beralih ke latar belakang.Sekarang, periksa apakah Anda dapat menjalankan kode Anda di bawah
onResume
metode.Selain itu, jika Anda
Activity
dikonfigurasi kesingleTop
, Anda harus mengatur ulang bendera Anda ketika yang baruIntent
dikirim.sumber
(intent.getFlags() & Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY)
jadi sekarang saya bisa mengetahui kapan dimulainya aktivitas dari sejarah dan saya bisa mengabaikan ekstra saya.boolean shouldThisIntentTriggerMyCode = [...];
dari jawaban (untuk apa?)consumedIntent
sebagaiString
mengandung pemberitahuan Uid. Uid ini dapat dengan mudah ditambahkan ke notifikasi di backend sebagai stempel waktu saat ini. Anda juga harus menyimpan Uid inionSaveInstanceState
hanya jika Intent telah datangonCreate
. Ini berarti Anda tidak boleh menyimpan Uid darionNewIntent
.Jawaban maksimal berfungsi untuk membersihkan ekstra:
Perintah berguna lainnya adalah:
Anda juga bisa menandai maksud dengan memanggil:
dan kemudian periksa nilainya.
sumber
Saat kami meluncurkan aplikasi Android dari Riwayat (Aplikasi Terkini), aplikasi tersebut dapat diluncurkan dengan tiga tanda Maksud yang berbeda.
FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY
Ini adalah saat aktivitas diluncurkan dari riwayat aplikasi yang diminimalkan (tekan lama tombol home).
Nilai Konstan: 1048576 (0x00100000)
FLAG_ACTIVITY_NEW_TASK
Ini adalah saat aktivitas diluncurkan melalui "ikon aplikasi mengklik" atau melalui " Filter maksud ". Di sini aktivitas akan menjadi awal tugas baru di tumpukan riwayat ini.
Nilai Konstanta: 268435456 (0x10000000)
FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY | FLAG_ACTIVITY_NEW_TASK
Ini adalah saat aplikasi ditutup dengan menekan tombol kembali dan kemudian melanjutkan dari Riwayat (aplikasi terbaru).
Nilai Konstanta: 269484032 (0x10100000)
Nilai konstanta dapat diambil melalui
getIntent().getFlags()
Dalam kasus ketiga, Android memuat ulang nilai Intent terakhir dari memorinya. Jadi maksud aplikasi Anda (
getIntent
) akan memiliki nilai dari maksud terakhir yang meluncurkan aplikasi.Sebenarnya, aplikasi harus berperilaku seolah-olah itu adalah peluncuran baru, dengan nilai maksud untuk peluncuran baru, bukan nilai maksud dari peluncuran sebelumnya. Perilaku ini bisa dilihat jika Anda meluncurkan aplikasi dengan mengklik ikon aplikasi, nilai maksud lama tidak akan pernah ada. Ini karena, Android menggunakan filter maksud berikut untuk skenario ini
Namun dalam kasus ketiga (Aplikasi yang ditutup, diluncurkan dari Riwayat aplikasi Terbaru), OS Android menggunakan maksud terakhir yang meluncurkan aplikasi sebelum ditutup (dengan menekan tombol kembali). Jadi, Anda akhirnya memiliki nilai maksud lama dan aliran aplikasi tidak tepat.
Menghapus niat adalah salah satu cara untuk menyelesaikannya, tetapi itu tidak akan menyelesaikan masalah sepenuhnya! Saat OS Android memuat ulang Intent dari peluncuran terakhir aplikasi, dan bukan instance terakhir dari maksud peluncuran.
Cara yang tepat untuk menghindari hal ini terjadi, adalah menanganinya dengan mendapatkan jenis Intent untuk menentukan jenis peluncuran.
Jadi dalam LaunchActivity Anda (The salah satu yang memiliki filter maksud didefinisikan dalam manifest), Anda bisa menggunakan kode berikut dalam
onCreate()
,onStart()
atauonResume()
metode.Saya kira
normalLaunch()
, sebaiknya tidak menggunakan parameter dari Intent; jika tidak, Anda perlu memisahkan dan mengoptimalkan metode peluncuran default untuk tidak menggunakan parameter Intent.sumber
getIntent().getFlags() & Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY
tidak masalah jika saya memulai aktivitas dari aktivitas lain (metode startActivity) atau membukanya kembali dari tumpukan Riwayat (aplikasi terbaru).Menghapus objek maksud :
sumber
Jawaban singkatnya adalah Tidak mungkin
Jawaban panjang. Tidak ada yang namanya niat "sekali tembak". Dari percobaan diketahui bahwa riwayat aktivitas terkini di Android modern tidak lebih dari "Riwayat maksud". Maksud terbaru yang diteruskan ke aktivitas hanya masuk ke sistem dan itulah kesepakatannya. Orang-orang di atas menyarankan untuk menggunakan
Tapi itu tidak berfungsi karena maksud sudah dicatat sampai Anda mendapatkannya di dalam metode onNewIntent () atau onStart ().
Saya memecahkan masalah dengan menghindari penggunaan maksud. Masalah saya mirip dengan yang diposting oleh penulis. Saya mencoba menerapkan Global Exit dari aplikasi melalui kontrol di area notifikasi. Ini harus menghentikan layanan yang mendasari dan menutup semua aktivitas aplikasi. Anda dapat menemukan perilaku yang sama di aplikasi Waze.
Algoritma:
Saya berharap ini akan membantu seseorang karena saya tidak menemukan jawabannya di internet.
sumber
Pastikan bahwa Anda menggunakan PendingIntent.FLAG_UPDATE_CURRENT bendera untuk PendingIntent .
Dimana
mPutIntent
milikmuIntent
.Semoga ini bisa membantu Anda.
sumber
Saya baru-baru ini mengalami masalah ini dan saya menyelesaikannya dengan menambahkan stempel waktu sebagai parameter tambahan ke maksud:
Setelah itu, simpan stempel waktu ke preferensi bersama:
sumber
Saya punya masalah yang persis sama. Solusi saya adalah menambahkan
boolean
variabel yang diatur kapanIntent
'digunakan' danif
pernyataan berdasarkan iniboolean
untuk memeriksa apakah Anda harus menggunakanIntent
atau tidak.sumber
Saat Anda selesai memproses Intent, lakukan ini:
Anda tidak akan melihat Intent yang telah diproses itu lagi, dan Anda tidak akan menutupi masalah dengan mengedit konten Intent yang telah diproses.
sumber
Saya tidak dapat menemukan cara untuk menghapus Intent Extra . Tidak ada jawaban tentang penghapusan ekstra dari maksud yang berfungsi jika Anda mengaktifkan "Jangan Simpan Aktivitas " dari Opsi Pengembang (Dengan begitu, Anda dapat menghancurkan Aktivitas dan kembali untuk menguji apakah Ekstra masih ada).
Sebagai solusi untuk masalah ini, saya menyimpan nilai boolean di SharedPreferences setelah Intent Extras diproses. Ketika Intent yang sama dikirim ulang ke Activity, saya memeriksa nilai SharedPreference dan memutuskan untuk memproses Intent Extra. Jika Anda mengirim Intent Extra baru lagi ke Aktivitas yang sama, Anda membuat nilai SharedPreference menjadi false dan Aktivitas akan memprosesnya. Contoh :
sumber
Bahkan setelah secara manual menghapus ekstra Intent dan Intent setelah mereka diurai, tampaknya Activity.getIntent () akan selalu mengembalikan Intent asli yang memulai Activity.
Untuk menyiasati ini, saya merekomendasikan sesuatu seperti ini:
Dengan cara ini, terdapat mekanisme untuk membuang Intent asli sambil tetap mempertahankan kemampuan untuk secara eksplisit mempertahankan bagian tertentu dari ekstra Intent / Intent asli.
Perhatikan bahwa saya belum menguji semua mode peluncuran Aktivitas.
sumber
Cara langsungnya adalah menghindari pemanggilan getIntent () dari metode selain onCreate (). Tetapi ini akan menyebabkan masalah selama peluncuran berikutnya jika pengguna meninggalkan Aktivitas kami dengan mengetuk tombol Beranda. Saya pikir masalah ini tidak memiliki solusi yang berfungsi penuh.
sumber
Saya menghadapi masalah yang sama dan mencoba menggunakan metode di atas tetapi tidak berhasil.
Saya rasa itu mungkin karena mode peluncuran aktivitas yang saya gunakan mode singleTop.
Ketika saya melatarbelakangi aplikasi dan menggunakan RamEater untuk mensimulasikan masalah, maksud itu selalu memiliki ekstra bahkan saya menyetelnya nol atau menghapus kunci.
Masalahnya hilang dengan menggunakan penyimpanan preferensi di Android untuk memeriksa yang telah lewat.
sumber
Ini bukan praktik yang baik untuk menambahkan ekstra hanya untuk mengetahui apakah ekstra telah dikonsumsi atau tidak, mengapa tidak melakukan ini ?:
sumber
Bagaimana dengan ini? Setel newIntent sebagai maksud.
sumber
Bagaimana jika Anda ingin menghapus maksud - menggantinya dengan yang kosong?
misalnya.
sumber
Semoga ini bisa membantu semua orang. Jadi pertama kita mendapatkan maksudnya
Tempatkan ini di suatu tempat di onCreate
Sekarang mari kita atur ini sehingga setiap kali aplikasi kita dihancurkan atau keluar kita akan menghapus data
Anda mendapatkan idenya, jika ini tidak cukup temukan lebih banyak panggilan balik 'on'
sumber
Meskipun
Intent.removeExtra("key")
akan menghapus satu kunci tertentu dari ekstra, ada juga metode Intent.replaceExtras (Bundle) , yang dapat digunakan untuk menghapus seluruh ekstra dari Intent, jikanull
diteruskan sebagai parameter.Dari dokumen:
Karena metode putXXX () menginisialisasi ekstra dengan Bundle baru jika null, ini bukan masalah.
sumber
sumber