Banyak pengguna Android memiliki berbagai situasi yang membuat mereka berinteraksi dengan ponselnya dengan cara yang berbeda. Bagi pengguna yang tidak dapat menggunakan ponsel pintar Android karena penglihatan, pendengaran, atau alasan fisik lainnya, Android menyediakan fungsi dan layanan Aksesibilitas untuk membantu pengguna mengoperasikan perangkat dengan lebih sederhana, termasuk text-to-speech, umpan balik sentuhan, pengoperasian isyarat, trackball dan Tangani operasi. Pengembang dapat membangun layanan Aksesibilitas mereka sendiri, yang dapat meningkatkan kegunaan aplikasi, seperti perintah suara, umpan balik fisik, dan mode pengoperasian opsional lainnya.
Implementasi spesifiknya adalah berjalan di latar belakang melalui layanan AccessibilityService dan menerima callback untuk peristiwa tertentu melalui AccessibilityEvent. Peristiwa tersebut mewakili beberapa transisi keadaan oleh pengguna di antarmuka, seperti: fokus berubah, tombol diklik, dll. Layanan tersebut secara opsional memiliki kemampuan untuk meminta konten jendela aktif. Sederhananya, AccessibilityService adalah layanan pemantauan latar belakang. Ketika konten yang Anda pantau berubah, metode panggilan balik dari layanan latar belakang akan dipanggil.
Tulis kelas Layanan Anda sendiri dan ganti metode onServiceConnected(), metode onAccessibilityEvent(), dan metode onInterrupt()
public class QHBAccessibilityService extends AccessibilityService {
/**
* 当启动服务的时候就会被调用
*/
@ Override
protected void onServiceConnected () {
super . onServiceConnected ();
}
/**
* 监听窗口变化的回调
*/
@ Override
public void onAccessibilityEvent ( AccessibilityEvent event ) {
int eventType = event . getEventType ();
//根据事件回调类型进行处理
}
/**
* 中断服务的回调
*/
@ Override
public void onInterrupt () {
}
}
Berikut ini adalah pengenalan metode yang umum digunakan di AccessibilityService
Karena ini adalah layanan latar belakang, kita perlu mengonfigurasi informasi layanan dalam manifes
< service
android : name = " .AccessibilityService.QHBAccessibilityService "
android : enabled = " true "
android : exported = " true "
android : label = " @string/label "
android : permission = " android.permission.BIND_ACCESSIBILITY_SERVICE " >
< intent-filter >
< action android : name = " android.accessibilityservice.AccessibilityService " />
</ intent-filter >
</ service >
Kita harus memperhatikan: kesalahan konfigurasi informasi apa pun akan membuat layanan tidak responsif
Mengonfigurasi parameter layanan mengacu pada: mengonfigurasi untuk menerima peristiwa dari jenis tertentu, mendengarkan paket tertentu, mengambil konten jendela, mendapatkan waktu jenis peristiwa, dll. Ada dua cara untuk mengonfigurasi parameter layanan:
Tambahkan tag meta-data ke manifes asli untuk menentukan file xml
< service
android : name = " .AccessibilityService.QHBAccessibilityService "
android : enabled = " true "
android : exported = " true "
android : label = " @string/label "
android : permission = " android.permission.BIND_ACCESSIBILITY_SERVICE " >
< intent-filter >
< action android : name = " android.accessibilityservice.AccessibilityService " />
</ intent-filter >
< meta-data
android : name = " android.accessibilityservice "
android : resource = " @xml/accessibility_service_config " />
</ service >
Selanjutnya adalah konfigurasi file access_service_config
<? xml version = " 1.0 " encoding = " utf-8 " ?>
< accessibility-service xmlns : android = " http://schemas.android.com/apk/res/android "
android : accessibilityEventTypes = " typeNotificationStateChanged|typeWindowStateChanged|typeWindowContentChanged|typeWindowsChanged "
android : accessibilityFeedbackType = " feedbackGeneric "
android : accessibilityFlags = " flagDefault "
android : canRetrieveWindowContent = " true "
android : description = " @string/description "
android : notificationTimeout = " 100 "
android : packageNames = " com.tencent.mm " />
Berikut ini adalah pengenalan parameter xml
accessabilityEventTypes: Menunjukkan perubahan mana pada antarmuka yang diinginkan layanan, yaitu peristiwa mana yang diberitahukan, seperti pembukaan jendela, geser, perubahan fokus, tekan lama, dll. Nilai spesifiknya dapat ditemukan di kelas AccessibilityEvent. Misalnya, typeAllMask berarti menerima semua notifikasi acara.
aksesibilitasFeedbackType: menunjukkan metode umpan balik, seperti pemutaran suara atau getaran
canRetrieveWindowContent: Menunjukkan apakah layanan dapat mengakses konten di jendela aktif. Artinya, jika Anda ingin mendapatkan konten formulir di layanan, Anda perlu menyetel nilainya ke true
deskripsi: Deskripsi fitur aksesibilitas, seperti terlihat pada gambar di bawah ini
noticeTimeout: Interval waktu untuk menerima acara, biasanya diatur ke 100
packageNames: Menunjukkan paket mana yang digunakan layanan untuk memantau peristiwa. Di sini kami mengambil nama paket WeChat sebagai contoh.
Konfigurasikan informasi AccessibilityServiceInfo untuk AccessibilityService kami melalui kode
private void settingAccessibilityInfo () {
String [] packageNames = { "com.tencent.mm" };
AccessibilityServiceInfo mAccessibilityServiceInfo = new AccessibilityServiceInfo ();
// 响应事件的类型,这里是全部的响应事件(长按,单击,滑动等)
mAccessibilityServiceInfo . eventTypes = AccessibilityEvent . TYPES_ALL_MASK ;
// 反馈给用户的类型,这里是语音提示
mAccessibilityServiceInfo . feedbackType = AccessibilityServiceInfo . FEEDBACK_SPOKEN ;
// 过滤的包名
mAccessibilityServiceInfo . packageNames = packageNames ;
setServiceInfo ( mAccessibilityServiceInfo );
}
Kelas AccessibilityServiceInfo terlibat di sini. Kelas AccessibilityServiceInfo digunakan untuk mengonfigurasi informasi AccessibilityService. Kelas ini berisi sejumlah besar bidang konstan untuk konfigurasi dan atribut xml.
Di sini kita perlu mengaktifkan fungsi ini secara manual di fungsi aksesibilitas, jika tidak, kita tidak dapat melanjutkan. Anda dapat membuka daftar fungsi aksesibilitas sistem melalui kode berikut
Intent intent = new Intent ( Settings . ACTION_ACCESSIBILITY_SETTINGS );
startActivity ( intent );
Karena kita memantau bilah notifikasi dan antarmuka acara, ketika bilah notifikasi atau antarmuka nama paket yang ditentukan berubah, acara kita akan dipanggil kembali melalui onAccessibilityEvent, lalu acara tersebut akan diproses.
@ Override
public void onAccessibilityEvent ( AccessibilityEvent event ) {
int eventType = event . getEventType ();
//根据事件回调类型进行处理
switch ( eventType ) {
//当通知栏发生改变时
case AccessibilityEvent . TYPE_NOTIFICATION_STATE_CHANGED :
break ;
//当窗口的状态发生改变时
case AccessibilityEvent . TYPE_WINDOW_STATE_CHANGED :
break ;
}
}
Saat kami menerima notifikasi di WeChat, pesan push akan tiba di bilah status. Saat ini, pesan tersebut akan dipantau oleh TYPE_NOTIFICATION_STATE_CHANGED dan konten di dalamnya akan dieksekusi dipantau oleh TYPE_WINDOW_STATE_CHANGED. Jalankan konten di dalamnya
Metode AccessibilityEvent
Setelah mendapatkan perubahan jendela antarmuka, saat ini perlu untuk mendapatkan node kontrol. Node dari seluruh jendela pada dasarnya adalah struktur pohon. Informasi node dioperasikan melalui yang berikut ini
AccessibilityNodeInfo nodeInfo = getRootInActiveWindow ();
//通过文本找到对应的节点集合
List < AccessibilityNodeInfo > list = nodeInfo . findAccessibilityNodeInfosByText ( text );
//通过控件ID找到对应的节点集合,如com.tencent.mm:id/gd
List < AccessibilityNodeInfo > list = nodeInfo . findAccessibilityNodeInfosByViewId ( clickId );
Setelah kita mendapatkan informasi node, kita dapat melakukan simulasi klik, penekanan lama, dan operasi lainnya pada node kontrol. Kelas AccessibilityNodeInfo menyediakan metode performAction() yang memungkinkan kita melakukan operasi simulasi . Operasi yang umum digunakan tercantum di sini.
//模拟点击
accessibilityNodeInfo . performAction ( AccessibilityNodeInfo . ACTION_CLICK );
//模拟长按
accessibilityNodeInfo . performAction ( AccessibilityNodeInfo . ACTION_LONG_CLICK );
//模拟获取焦点
accessibilityNodeInfo . performAction ( AccessibilityNodeInfo . ACTION_FOCUS );
//模拟粘贴
accessibilityNodeInfo . performAction ( AccessibilityNodeInfo . ACTION_PASTE );
Saat ponsel kita terhubung ke kabel USB, pilih perangkat di Android Device Monitor dan buka alat Dump View Hierarchy for UI Automator, yang melaluinya kita dapat memperoleh informasi kontrol
Q:
AccessibilityNodeInfo nodeInfo = getRootInActiveWindow();
selalu melaporkan pointer null. Apakah blogger mengalami masalah ini? Saya juga mengalami masalah seperti masalah Anda. Saya pikir itu ada di "Parameter Layanan Konfigurasi". Saya baru saja mulai mengonfigurasinya dalam kode, dan itu juga mengembalikan nol ", tetapi ternyata tidak. Saya menemukan pengaturan yang sesuai dengan android:canRetrieveWindowContent="true", jadi saya mengubahnya untuk mengkonfigurasinya dalam xml, dan itu baik-baik saja.
T: Bagaimana cara mendapatkan nama kelas ini com.tencent.mm.ui.LauncherUI? A: String className = event.getClassName().toString(); Gunakan Log untuk mencetaknya, dan buka WeChat untuk melihat informasi Log
Teks asli: blog Hensen_