Apakah ada cara android asli untuk mendapatkan referensi ke Aktivitas yang sedang berjalan dari layanan?
Saya memiliki layanan yang berjalan di latar belakang, dan saya ingin memperbarui Aktivitas saya saat ini ketika suatu peristiwa terjadi (dalam layanan). Apakah ada cara mudah untuk melakukan itu (seperti yang saya sarankan di atas)?
android
service
android-activity
George
sumber
sumber
Jawaban:
Anda mungkin tidak memiliki "Aktivitas yang sedang berjalan".
Intent
ke aktivitas - ini adalah contoh proyek yang menunjukkan pola iniPendingIntent
(misalnya, melaluicreatePendingResult()
) yang diminta oleh layananbindService()
, dan minta layanan memanggil metode peristiwa pada objek panggilan balik / pendengar ituIntent
ke aktivitas, dengan prioritas rendahBroadcastReceiver
sebagai cadangan (untuk menaikkanNotification
jika aktivitas tidak ada di layar) - di sini ada posting blog dengan lebih banyak tentang pola inisumber
instanceof
cek atau refactoring kegiatan untuk berbagi superclass atau antarmuka umum. Dan jika Anda akan memperbaiki kegiatan, Anda mungkin melakukannya dengan cara yang lebih sesuai dengan kerangka kerja dan mencakup lebih banyak skenario, seperti tidak ada kegiatan Anda yang aktif. # 4 mungkin yang paling tidak bekerja dan paling fleksibel.Pembaruan : ini tidak lagi berfungsi dengan aktivitas aplikasi lain pada Android 5.0
Berikut cara yang baik untuk melakukannya menggunakan pengelola aktivitas. Pada dasarnya Anda mendapatkan runningTasks dari manajer aktivitas. Itu akan selalu mengembalikan tugas yang sedang aktif terlebih dahulu. Dari sana Anda bisa mendapatkan TopActivity.
Contoh di sini
Ada cara mudah untuk mendapatkan daftar tugas yang berjalan dari layanan ActivityManager. Anda dapat meminta jumlah tugas maksimum yang berjalan di telepon, dan secara default, tugas yang aktif dikembalikan terlebih dahulu.
Setelah Anda memilikinya, Anda bisa mendapatkan objek ComponentName dengan meminta topActivity dari daftar Anda.
Ini sebuah contoh.
Anda memerlukan izin berikut pada manifes Anda:
sumber
As of LOLLIPOP, this method is no longer available to third party applications: the introduction of document-centric recents means it can leak person information to the caller. For backwards compatibility, it will still return a small subset of its data: at least the caller's own tasks, and possibly some other tasks such as home that are known to not be sensitive.
Peringatan: Pelanggaran Google Play
Google telah mengancam akan menghapus aplikasi dari Play Store jika mereka menggunakan layanan aksesibilitas untuk tujuan non-aksesibilitas. Namun, ini dilaporkan sedang dipertimbangkan kembali .
Gunakan sebuah
AccessibilityService
AccessibilityService
.onAccessibilityEvent
panggilan balik, periksa jenis acara untuk menentukan kapan jendela saat ini berubah.TYPE_WINDOW_STATE_CHANGED
PackageManager.getActivityInfo()
.Manfaat
GET_TASKS
izin.Kekurangan
AccessibilityService
, mereka tidak dapat menekan tombol OK jika aplikasi telah meletakkan overlay pada layar. Beberapa aplikasi yang melakukan ini adalah Velis Auto Brightness dan Lux. Ini bisa membingungkan karena pengguna mungkin tidak tahu mengapa mereka tidak bisa menekan tombol atau cara mengatasinya.AccessibilityService
tidak akan mengetahui aktivitas saat ini sampai perubahan aktivitas pertama.Contoh
Layanan
AndroidManifest.xml
Gabungkan ini ke manifes Anda:
Info Layanan
Masukkan ini
res/xml/accessibilityservice.xml
:Mengaktifkan Layanan
Setiap pengguna aplikasi harus mengaktifkan secara eksplisit agar aplikasi
AccessibilityService
tersebut dapat digunakan. Lihat jawaban StackOverflow ini untuk cara melakukan ini.Perhatikan bahwa pengguna tidak akan dapat menekan tombol OK ketika mencoba mengaktifkan layanan aksesibilitas jika aplikasi telah meletakkan overlay pada layar, seperti Velis Auto Brightness atau Lux.
sumber
settingsActivity
dariyour.app.ServiceSettingsActivity
, sehingga Anda harus mengubah itu untuk aktivitas pengaturan Anda sendiri untuk layanan aksesibilitas Anda. Saya pikir aktivitas pengaturan adalah opsional, jadi saya telah menghapus bagian itu dari jawaban saya untuk membuatnya lebih sederhana.onAccessibilityEvent
tidak menerima peristiwa apa pun, tetapi jika saya menonaktifkan, dan mengaktifkan kembali Layanan Aksesibilitas, layanan itu diaktifkan kembali danonAccessibilityEvent
mulai berfungsi.Itu bisa dilakukan dengan:
Laksanakan kelas aplikasi Anda sendiri, daftar untuk ActivityLifecycleCallbacks - dengan cara ini Anda dapat melihat apa yang terjadi dengan aplikasi kami. Pada setiap saat melanjutkan, panggilan balik menetapkan aktivitas yang terlihat saat ini di layar dan pada jeda itu menghapus tugas. Itu menggunakan metode
registerActivityLifecycleCallbacks()
yang ditambahkan dalam API 14.Dalam panggilan layanan Anda
getApplication()
dan berikan ke nama kelas aplikasi Anda (Aplikasi dalam hal ini). Daripada Anda dapat meneleponapp.getActiveActivity()
- yang akan memberi Anda Aktivitas yang terlihat saat ini (atau nol saat tidak ada aktivitas yang terlihat). Anda bisa mendapatkan nama Kegiatan dengan meneleponactiveActivity.getClass().getSimpleName()
sumber
onActivityResumed()
,onActivityPaused()
dangetActiveActivity()
untuk melihat bagaimana itu callet, jika pernah begitu.activity
danactiveActivity
yang sama sebelum menugaskanactiveActivity
dengannull
untuk kesalahan menghindari karena agar memanggil bercampur metode siklus hidup berbagai kegiatan.Saya tidak dapat menemukan solusi yang akan membuat tim kami senang, jadi kami menggulung sendiri. Kami menggunakan
ActivityLifecycleCallbacks
untuk melacak aktivitas saat ini dan kemudian mengeksposnya melalui layanan:Kemudian konfigurasikan wadah DI Anda untuk mengembalikan instance
MyApplication
untukContextProvider
, misalnya(Perhatikan bahwa implementasi
getCurrent()
dihilangkan dari kode di atas. Itu hanya variabel statis yang ditetapkan dari konstruktor aplikasi)sumber
activity
dancurrentActivity
yang sama sebelum menugaskancurrentActivity
dengannull
untuk kesalahan menghindari karena agar memanggil bercampur metode siklus hidup berbagai kegiatan.Menggunakan
ActivityManager
Jika Anda hanya ingin mengetahui aplikasi yang berisi aktivitas saat ini, Anda dapat melakukannya menggunakan
ActivityManager
. Teknik yang dapat Anda gunakan tergantung pada versi Android:ActivityManager.getRunningTasks
( contoh )ActivityManager.getRunningAppProcesses
( contoh )Manfaat
Kekurangan
ActivityManager.RunningAppProcessInfo.processState
Contoh (berdasarkan kode KNaito )
Nyata
Tambahkan
GET_TASKS
izin keAndroidManifest.xml
:sumber
Saya menggunakan ini untuk tes saya. Itu API> 19, dan hanya untuk aktivitas aplikasi Anda.
sumber
Gunakan kode ini untuk API 21 atau lebih tinggi. Ini bekerja dan memberikan hasil yang lebih baik dibandingkan dengan jawaban lain, ia mendeteksi dengan sempurna proses latar depan.
sumber
Inilah jawaban saya yang berfungsi dengan baik ...
Anda seharusnya bisa mendapatkan Aktivitas saat ini dengan cara ini ... Jika Anda menyusun aplikasi Anda dengan beberapa Aktivitas dengan banyak fragmen dan Anda ingin melacak apa Aktivitas Anda saat ini, itu akan membutuhkan banyak pekerjaan. Senario saya adalah saya memiliki satu Kegiatan dengan beberapa Fragmen. Jadi saya bisa melacak Aktivitas Terkini melalui Objek Aplikasi, yang dapat menyimpan semua variabel Global saat ini.
Inilah caranya. Ketika Anda memulai aktivitas Anda, Anda menyimpan aktivitas itu dengan Application.setCurrentActivity (getIntent ()); Aplikasi ini akan menyimpannya. Di kelas layanan Anda, Anda bisa melakukannya seperti Intent currentIntent = Application.getCurrentActivity (); getApplication (). startActivity (currentIntent);
sumber
Saya tidak tahu apakah ini jawaban yang bodoh, tetapi menyelesaikan masalah ini dengan menyimpan bendera di preferensi bersama setiap kali saya memasukkan onCreate () dari aktivitas apa pun, lalu saya menggunakan nilai dari preferensi terpusat untuk mencari tahu apa itu aktivitas latar depan.
sumber
Baru-baru ini mengetahui tentang ini. Dengan apis sebagai:
targetSdkVersion 26
ActivityManager.getCurrentActivity (konteks)
Semoga ini ada gunanya.
sumber
getCurrentActivity()
fungsi diActivityManager
kelas ( developer.android.com/reference/android/app/ActivityManager ). Lucu bahwa fungsi ini tidak ada:ActivityManager.isUserAMonkey()
.