自動搶紅包AccessibilityService

微信紅包自打出世以來就極其受歡迎,搶紅包插件可謂紅極一時.今天,我們重新談談搶紅包插件的哪些事兒.本質上,搶紅包插件的原理不難理解,其過程就是在收到紅包時,自動模擬點擊.做過自動化UI測試的童鞋應該非常熟悉了.那么問題來了,我們怎么知道有沒有紅包,又怎么模擬點擊操作呢?在PC端我們有按鍵精靈,那么在Android設備上呢?話說也偶然,Google為了讓Android系統更實用,為用戶提供了無障礙輔助服務(AccessibilityService).

AccessibilityService運行在后臺,并且能夠收到由系統發出的一些事件(AccessibilityEvent,這些事件表示用戶界面一系列的狀態變化),比如焦點改變,輸入內容變化,按鈕被點擊了等等,該種服務能夠請求獲取當前活動窗口并查找其中的內容.換言之,界面中產生的任何變化都會產生一個時間,并由系統通知給AccessibilityService.這就像監視器監視著界面的一舉一動,一旦界面發生變化,立刻發出警報.

是不是感覺很棒?接下來,讓我們來看看如何AccessibilityService的基本使用,在不同的階段,對其中的一些點做深入的說明,之后我們從實際應用出發,探討其中的一些使用場景.

深入AccessibilityService使用

1. 創建服務類

編寫自己的服務類,需要繼承AccessibilityService類.其中要實現onAccessibilityEvent(AccessibilityEvent event)及onInterruput()兩個重要的方法:

publicclassRobServiceextendsAccessibilityService{@OverridepublicvoidonAccessibilityEvent(AccessibilityEvent event){? }@OverridepublicvoidonInterrupt(){? }

這里我們對該類常用的方法做下說明,更詳細的內容參見官方文檔

方法作用

disableSelf()禁用當前服務,也就是在服務可以通過該方法停止運行

findFoucs(int falg)查找擁有特定焦點類型的控件

getRootInActiveWindow()如果配置能夠獲取窗口內容,則會返回當前活動窗口的根結點

getSeviceInfo()獲取當前服務的配置信息

onAccessibilityEvent(AccessibilityEvent event)有關AccessibilityEvent事件的回調函數.系統通過sendAccessibiliyEvent()不斷的發送AccessibilityEvent到此處

performGlobalAction(int action)執行全局操作,比如返回,回到主頁,打開最近等操作

setServiceInfo(AccessibilityServiceInfo info)設置當前服務的配置信息

getSystemService(String name)獲取系統服務

onKeyEvent(KeyEvent event)如果允許服務監聽按鍵操作,該方法是按鍵事件的回調,需要注意,這個過程發生了系統處理按鍵事件之前

onServiceConnected()系統成功綁定該服務時被觸發,也就是當你在設置中開啟相應的服務,系統成功的綁定了該服務時會觸發,通常我們可以在這里做一些初始化操作

2. 聲明服務

像其他Service服務一樣,需要在AndroidManifest.xml中聲明該服務.除此之外,該服務還必須配置以下兩項:

配置,其name為固定的:

android.accessibilityservice.AccessibilityService

聲明BIND_ACCESSIBILITY_SERVICE權限,以便系統能夠綁定該服務(4.0版本后要求)

注意:任何一點配置錯誤,系統都無反應,因此其固定配置如下:

? ? ? ? ? ? ? ?

3. 服務參數設置

在AndroidManifest.xml聲明了該服務之后,接下來就是需要對該服務進行一些參數設置了.該服務能夠被配置用來接受指定類型的事件,監聽指定package,檢索窗口內容,獲取事件類型的時間等等.目前有兩種配置方法:

方法一:4.0之后提供了可以通過標簽進行配置

方法二:通過setServiceInfo()進行配置

3.1. 通過進行配置

在AndroidManifest.xml生命的的service中提供一個meta-data標簽,然后通過android:resource指定相應的配置文件(在res目錄下創建xml文件,并在其中創建配置文件accessibility.xml):

接下來我們來看accessibility.xml的相關配置:

后面,我們在只需要仿照該配置文件根據自己的需求進行修改即可.下面我們會對這些屬性進行介紹.

3.2 通過setServiceInfo(AccessibilityServiceInfo info)

也可以通過setServiceInfo(AccessibilityServiceInfo)為其配置信息,除此之外,通過該方法可以在運行期間動態修改服務配置.需要注意,該方法只能用來配置動態屬性:eventTypes,feedbackType,flags,notificaionTimeout及packageNames.

通常是在onServiceConnected()進行配置,如下代碼:

@OverrideprotectedvoidonServiceConnected(){? ? ? ? AccessibilityServiceInfo serviceInfo =newAccessibilityServiceInfo();? ? ? ? serviceInfo.eventTypes = AccessibilityEvent.TYPES_ALL_MASK;? ? ? ? serviceInfo.feedbackType = AccessibilityServiceInfo.FEEDBACK_GENERIC;? ? ? ? serviceInfo.packageNames =newString[]{"com.tencent.mm"};? ? ? ? serviceInfo.notificationTimeout=100;? ? ? ? setServiceInfo(serviceInfo);? ? }

在這里涉及到了AccessibilityServiceInfo類,做個說明:

AccessibilityServiceInfo該類被用于配置AccessibilityService信息,該類中包含了大量用于配置的常量字段及用來xml 屬性,比如常見的:

android:accessibilityEventTypes,android:canRequestFilterKeyEvents,android:packageNames等等,更多信息參見官方文檔

現在我們對配置中的重要屬性進行說明:

accessibilityEventTypes:表示該服務對界面中的哪些變化感興趣,即哪些事件通知,比如窗口打開,滑動,焦點變化,長按等.具體的值可以在AccessibilityEvent類中查到,如typeAllMask表示接受所有的事件通知.

accessibilityFeedbackType:表示反饋方式,比如是語音播放,還是震動

canRetrieveWindowContent:表示該服務能否訪問活動窗口中的內容.也就是如果你希望在服務中獲取窗體內容的化,則需要設置其值為true.

notificationTimeout:接受事件的時間間隔,通常將其設置為100即可.

packageNames:表示對該服務是用來監聽哪個包的產生的事件

4. 啟動服務

當我們做完以上操作,便可將app安裝到手機.安裝成功后,在設置->輔助功能中便可以找到我們的服務.該服務默認處在關閉狀態,需要手動開啟.

5. 獲取事件信息

上面我們說道,onAccessibilityEvent(AccessibilityEvent event)是該服務的核心方法,其中參數event封裝來自界面相關事件的信息,比如我們可以獲得該事件的事件類型,進而根據起類型選擇不同的處理方式:

publicvoidonAccessibilityEvent(AccessibilityEventevent){inteventType =event.getEventType();switch(eventType) {caseAccessibilityEvent.TYPE_VIEW_CLICKED://界面點擊break;caseAccessibilityEvent.TYPE_VIEW_TEXT_CHANGED://界面文字改動break;? ? ? ? }? ? }

這里我們對AccessibilityEvent進行簡單的說明:

當用戶發生發生變化時,系統會發送一系列的AccessibilityEvent事件,比如按鈕被點擊時會發送TYPE_VIEW_CLICKED類型的事件.

方法說明

getEventType()事件類型

getSource()獲取事件源對應的結點信息

getClassName()獲取事件源對應類的類型,比如點擊事件是有某個Button產生的,那么此時獲取的就是Button的完整類名

getText()獲取事件源的文本信息,比如事件是有TextView發出的,此時獲取的就是TextView的text屬性.如果該事件源是樹結構,那么此時獲取的是這個樹上所有具有text屬性的值的集合

isEnabled()事件源(對應的界面控件)是否處在可用狀態

getItemCount()如果事件源是樹結構,將返回該樹根節點下子節點的數量

系統不斷的產生各種事件,有些是界面控件產生的,有些是系統產生的.對于由界面控件的產生的事件,通常我們將該控件稱之為事件源.并不是所有的事件都能通過getSource()方法獲取到事件源,比如像通知消息類型的事件(TYPE_NOTIFICATION_STATE_CHANGED).

6. 獲取窗口內容

僅僅知道事件的信息是不夠的,我們還希望通過事件來獲取發出該事件(事件源)的信息,比如Button按鈕被點擊時它的text.一個服務可以配置為允許服務檢索窗口內容,即獲取窗口內容.整個窗口內容本質上是關于AccessibilityWindowInfo和AccessibilityNodeInfo的樹結構,我稱之為內容樹.(類似View Tree,但由不完全相同)

需要注意,該服務可能配置了只檢測了部分事件,而不是全部事件,這就意味著,當內容樹發生變化后,該服務可能并不知道,即該服務無法及時的了解當前的內容樹是否發生了變化.比如說,你的服務只檢測了點擊事件,但是此時界面的輸入焦點已經變化,這樣整個結點樹也發生了變化,但是你的服務卻不知道,此時你在結點中拿到的窗口內容可能已經不是最新的了.因此,如果你想及時的獲知當前窗口的內容,那么就在配置的時候,設置監聽全部事件.

正如上面所提到的,要想獲取窗口內容,在配置AccessibilityService時需設置canRetrieveWindowContent為true.之后,便可以通過一下方法獲取窗口內容:AccessibilityEvent.getSource(),findFocus(int),getWindow()或者getRootInActiveWindow()

7. 服務的生命周期

要理解該中服務的生命周期只需要記住一下三點即可:

該種服務完全由系統管理,并遵循已有的服務周期.

開啟一個服務只能由用戶在設置中打開,而關閉則只能由用戶在設置中關閉或者服務本身通過diableSelf()方法關閉(當然,現在有些第三放軟件也可以強制關閉該類型服務)

系統綁定該服務之后,會調用onServiceConnected()方法,這個方法可以被重寫,在其中,你可以做一些初始化的操作.

8. 檢測服務是否開啟

介紹了一些AccessibilityService的基礎知識之后,再補充一點關于檢測某個服務是否開啟的知識.通常來說大體有一下兩種方法來檢測服務是否啟用:

方法一:借助服務管理器AccessibilityManager來判斷,但是該方法不能檢測app本身開啟的服務.

privatebooleanenabled(Stringname) {? ? ? ? AccessibilityManager am = (AccessibilityManager) getSystemService(Context.ACCESSIBILITY_SERVICE);List serviceInfos = am.getEnabledAccessibilityServiceList(AccessibilityServiceInfo.FEEDBACK_GENERIC);List installedAccessibilityServiceList = am.getInstalledAccessibilityServiceList();? ? ? ? for (AccessibilityServiceInfo info : installedAccessibilityServiceList) {Log.d("MainActivity","all -->"+ info.getId());if(name.equals(info.getId())) {returntrue;? ? ? ? ? ? }? ? ? ? }returnfalse;? ? }

既然談到了AccessibilityManager,那么在這里我們就做個簡單的介紹:

AccessibilityManager是系統級別的服務,用來管理AccessibilityService服務,比如分發事件,查詢系統中服務的狀態等等,更多信息參考官方文檔,常見方法如下:

方法說明

getAccessibilityServiceList()獲取服務列表(api 14之后廢棄,用下面的方法代替)

getInstalledAccessibilityServiceList()獲取已安裝到系統的服務列表

getEnabledAccessibilityServiceList(int feedbackTypeFlags)獲取已啟用的服務列表

isEnabled()判斷服務是否啟用

sendAccessibilityEvent(AccessibilityEvent event)發送事件

方法二:我們知道大部分的系統屬性都在settings中進行設置,比如wifi,藍牙狀態等,而這些信息主要是存儲在settings對應的的數據庫中(system表和serure表),這就意味我們可以通過直接讀取setting設置來判斷相關服務是否開啟:

privatebooleancheckStealFeature1(Stringservice) {intok =0;try{? ? ? ? ? ? ok = Settings.Secure.getInt(getApplicationContext().getContentResolver(), Settings.Secure.ACCESSIBILITY_ENABLED);? ? ? ? }catch(Settings.SettingNotFoundException e) {? ? ? ? }? ? ? ? TextUtils.SimpleStringSplitter ms =newTextUtils.SimpleStringSplitter(':');if(ok ==1) {StringsettingValue = Settings.Secure.getString(getApplicationContext().getContentResolver(), Settings.Secure.ENABLED_ACCESSIBILITY_SERVICES);if(settingValue !=null) {? ? ? ? ? ? ? ? ms.setString(settingValue);while(ms.hasNext()) {StringaccessibilityService = ms.next();if(accessibilityService.equalsIgnoreCase(service)) {returntrue;? ? ? ? ? ? ? ? ? ? }? ? ? ? ? ? ? ? }? ? ? ? ? ? }

實際應用

到現在有關AccessibilityService的一些知識,我們已經講完,下面我們就看它的具體使用,其中典型的應用就是搶紅包插件.

1. 搶紅包插件

先回顧一下搶紅包的的流程:

狀態欄出現"[微信紅包]"的消息提示,點擊進入聊天界面

點擊相應的紅包信息,彈出搶紅包界面

在搶紅包界面點擊"開",打開紅包

在紅包詳情頁面,查看詳情,點擊返回按鈕返回微信聊天界面.

以上是不在微信聊天界面時的流程.如果你所在的微信聊天窗口出現紅包,則不會執行步驟1,而是直接執行2,3,4.如果是在微信好友列表時,收到紅包,則會在列表項中顯示[微信紅包],需要點即該列表項,進入聊天界面,隨后執行2,3,4.為了方便演示,這里我們暫時不考慮好友列表時出現紅包的情況.

明白了搶紅包流程,之后我們通過AccessibilityService獲取通知欄信息及微信聊天窗口界面,繼而通過模擬點擊實現打開紅包,搶紅包等操作.

AccessibilityService配置如下:


typeWindowContentChanged"android:accessibilityFeedbackType="feedbackGeneric"android:accessibilityFlags="flagDefault"android:canRetrieveWindowContent="true"android:notificationTimeout="100"android:packageNames="com.tencent.mm"/>

具體實現代碼如下:

publicclassRobServiceextendsAccessibilityService{? ? @OverridepublicvoidonAccessibilityEvent(AccessibilityEventevent){inteventType =event.getEventType();switch(eventType) {caseAccessibilityEvent.TYPE_NOTIFICATION_STATE_CHANGED:? ? ? ? ? ? ? ? handleNotification(event);break;caseAccessibilityEvent.TYPE_WINDOW_STATE_CHANGED:caseAccessibilityEvent.TYPE_WINDOW_CONTENT_CHANGED:? ? ? ? ? ? ? ? String className =event.getClassName().toString();if(className.equals("com.tencent.mm.ui.LauncherUI")) {? ? ? ? ? ? ? ? ? ? getPacket();? ? ? ? ? ? ? ? }elseif(className.equals("com.tencent.mm.plugin.luckymoney.ui.LuckyMoneyReceiveUI")){? ? ? ? ? ? ? ? ? ? openPacket();? ? ? ? ? ? ? ? }elseif(className.equals("com.tencent.mm.plugin.luckymoney.ui.LuckyMoneyDetailUI")){? ? ? ? ? ? ? ? ? ? close();? ? ? ? ? ? ? ? }break;? ? ? ? }? ? }/**

* 處理通知欄信息

*

* 如果是微信紅包的提示信息,則模擬點擊

*

* @param event

*/privatevoidhandleNotification(AccessibilityEventevent){? ? ? ? List texts =event.getText();if(!texts.isEmpty()) {for(CharSequence text : texts) {? ? ? ? ? ? ? ? String content = text.toString();//如果微信紅包的提示信息,則模擬點擊進入相應的聊天窗口if(content.contains("[微信紅包]")) {if(event.getParcelableData() !=null&&event.getParcelableData() instanceof Notification) {? ? ? ? ? ? ? ? ? ? ? ? Notification notification = (Notification)event.getParcelableData();? ? ? ? ? ? ? ? ? ? ? ? PendingIntent pendingIntent = notification.contentIntent;try{? ? ? ? ? ? ? ? ? ? ? ? ? ? pendingIntent.send();? ? ? ? ? ? ? ? ? ? ? ? }catch(PendingIntent.CanceledException e) {? ? ? ? ? ? ? ? ? ? ? ? ? ? e.printStackTrace();? ? ? ? ? ? ? ? ? ? ? ? }? ? ? ? ? ? ? ? ? ? }? ? ? ? ? ? ? ? }? ? ? ? ? ? }? ? ? ? }? ? }/**

* 關閉紅包詳情界面,實現自動返回聊天窗口

*/@TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR2)privatevoidclose(){? ? ? ? AccessibilityNodeInfo nodeInfo = getRootInActiveWindow();if(nodeInfo !=null) {//為了演示,直接查看了關閉按鈕的idList infos = nodeInfo.findAccessibilityNodeInfosByViewId("@id/ez");? ? ? ? ? ? nodeInfo.recycle();for(AccessibilityNodeInfo item : infos) {? ? ? ? ? ? ? ? item.performAction(AccessibilityNodeInfo.ACTION_CLICK);? ? ? ? ? ? }? ? ? ? }? ? }/**

* 模擬點擊,拆開紅包

*/@TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR2)privatevoidopenPacket(){? ? ? ? AccessibilityNodeInfo nodeInfo = getRootInActiveWindow();if(nodeInfo !=null) {//為了演示,直接查看了紅包控件的idList list = nodeInfo.findAccessibilityNodeInfosByViewId("@id/b9m");? ? ? ? ? ? nodeInfo.recycle();for(AccessibilityNodeInfo item : list) {? ? ? ? ? ? ? ? item.performAction(AccessibilityNodeInfo.ACTION_CLICK);? ? ? ? ? ? }? ? ? ? }? ? }/**

* 模擬點擊,打開搶紅包界面

*/@TargetApi(Build.VERSION_CODES.JELLY_BEAN)privatevoidgetPacket(){? ? ? ? AccessibilityNodeInfo rootNode = getRootInActiveWindow();? ? ? ? AccessibilityNodeInfo node = recycle(rootNode);? ? ? ? node.performAction(AccessibilityNodeInfo.ACTION_CLICK);? ? ? ? AccessibilityNodeInfo parent = node.getParent();while(parent !=null) {if(parent.isClickable()) {? ? ? ? ? ? ? ? parent.performAction(AccessibilityNodeInfo.ACTION_CLICK);break;? ? ? ? ? ? }? ? ? ? ? ? parent = parent.getParent();? ? ? ? }? ? }/**

* 遞歸查找當前聊天窗口中的紅包信息

*

* 聊天窗口中的紅包都存在"領取紅包"一詞,因此可根據該詞查找紅包

*

* @param node

*/publicAccessibilityNodeInforecycle(AccessibilityNodeInfo node){if(node.getChildCount() ==0) {if(node.getText() !=null) {if("領取紅包".equals(node.getText().toString())) {returnnode;? ? ? ? ? ? ? ? }? ? ? ? ? ? }? ? ? ? }else{for(inti =0; i < node.getChildCount(); i++) {if(node.getChild(i) !=null) {? ? ? ? ? ? ? ? ? ? recycle(node.getChild(i));? ? ? ? ? ? ? ? }? ? ? ? ? ? }? ? ? ? }returnnode;? ? }? ? @OverridepublicvoidonInterrupt(){? ? }? ? @OverrideprotectedvoidonServiceConnected(){? ? ? ? super.onServiceConnected();? ? }}

上面的代碼簡單演示了搶紅包的原理,為了方便起見,我直接通過findAccessibilityNodeInfosByViewId()獲取制定id控件.在實際中,這種方法不太可靠,到目前為止,微信已經改過幾次相關控件的id了.

有童鞋問,怎么樣知道該控件的id呢.其實很簡單,android中已經為我們提供了相關的工具:在Android Studio中開啟Android Device Monitor,選擇設備后點擊Dump View Hierarchy for UI Automator,如下:

這里寫圖片描述

稍等片刻之后,便會出現當前設備的窗口,在該窗口中點擊相關控件,便會顯示該控件的屬性.借助該工具,可以幫我們快速的分析界面結構,幫助我們從其他app布局策略中學習

這里寫圖片描述

我們用Dump View Hierarchy for UI Automator分析聊天界面微信紅包信息:

這里寫圖片描述

搶紅包界面:

這里寫圖片描述

2. App自動安裝

講完了微信紅包插件的實現原理,不難發現其本質是根據相關的界面狀態,模擬后續的操作(比如點擊等).

既然這樣,那么我們完全可以利用該服務實現更多的功能,比如apk自動安裝,傳統的安裝過程大概是如下流程:

點擊apk文件,彈出安裝信息界面,在該界面點擊"下一步",然后在點擊"安裝",最后在安裝完成界面點擊"完成".

不難發現,該流程完全可以通過模擬點擊操作完成.現在我們簡單的講一下AccessibilityService在這方面的具體應用:

我們知道系統的安裝程序由PackageInstaller負責,其包名是com.android.packageinstaller,那么我們只需要監聽該package下的安裝信息界面和安裝完成界面,并模擬點擊"下一步","安裝",完成""操作即可實現自動安裝.

AccessibilityService配置如下:

具體實現代碼如下:

publicclassInstallServiceextendsAccessibilityService{? ? @OverridepublicvoidonAccessibilityEvent(AccessibilityEventevent){? ? ? ? Log.d("InstallService",event.toString());? ? ? ? checkInstall(event);? ? }privatevoidcheckInstall(AccessibilityEventevent){? ? ? ? AccessibilityNodeInfo source =event.getSource();if(source !=null) {? ? ? ? ? ? boolean installPage =event.getPackageName().equals("com.android.packageinstaller");if(installPage) {? ? ? ? ? ? ? ? installAPK(event);? ? ? ? ? ? }? ? ? ? }? ? }? ? @TargetApi(Build.VERSION_CODES.JELLY_BEAN)privatevoidinstallAPK(AccessibilityEventevent){? ? ? ? AccessibilityNodeInfo source = getRootInActiveWindow();? ? ? ? List nextInfos = source.findAccessibilityNodeInfosByText("下一步");? ? ? ? nextClick(nextInfos);? ? ? ? List installInfos = source.findAccessibilityNodeInfosByText("安裝");? ? ? ? nextClick(installInfos);? ? ? ? List openInfos = source.findAccessibilityNodeInfosByText("打開");? ? ? ? nextClick(openInfos);? ? ? ? runInBack(event);? ? }privatevoidrunInBack(AccessibilityEventevent){event.getSource().performAction(AccessibilityService.GLOBAL_ACTION_BACK);? ? }privatevoidnextClick(List infos){if(infos !=null)for(AccessibilityNodeInfo info : infos) {if(info.isEnabled() && info.isClickable())? ? ? ? ? ? ? ? ? ? info.performAction(AccessibilityNodeInfo.ACTION_CLICK);? ? ? ? ? ? }? ? }? ? @TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR2)privatebooleancheckTilte(AccessibilityNodeInfo source){? ? ? ? List infos = getRootInActiveWindow().findAccessibilityNodeInfosByViewId("@id/app_name");for(AccessibilityNodeInfo nodeInfo : infos) {if(nodeInfo.getClassName().equals("android.widget.TextView")) {returntrue;? ? ? ? ? ? }? ? ? ? }returnfalse;? ? }? ? @OverridepublicvoidonInterrupt(){? ? }? ? @OverrideprotectedvoidonServiceConnected(){? ? ? ? Log.d("InstallService","auto install apk");? ? }}

3. 檢測前臺服務:

在很多情況下,我們需要檢測自己的app是不是處在前臺,借助該服務同樣也能夠完成該檢測操作.下面,我們就演示一下如何實現:

AccessibilityService配置如下:

具體實現代碼如下:

publicclassDetectionServiceextendsAccessibilityService{privatestaticvolatileString foregroundPackageName ="error";/**? ? * 檢測是否是前臺服務? ? *? ? *@parampackagenName? ? *@return*/publicstaticbooleanisForeground(String packagenName){returnforegroundPackageName.equals(packagenName);? ? }@OverridepublicvoidonAccessibilityEvent(AccessibilityEvent event){if(event.getEventType() == AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED) {? ? ? ? ? ? foregroundPackageName = event.getPackageName().toString();? ? ? ? }? ? }@OverridepublicvoidonInterrupt(){? ? }}

在使用時,需要引導用戶開啟該服務,之后通過調用DetectionService.isForeground()即可.

4. 竊取信息

上面的所有示例演示的都是AccessibilityService在具體應用中發揮的良好作用.但是該服務也存在一定的風險,很多人利用該服務做一些"壞事",比如竊取短信驗證碼,竊取短信內容,想要看看自己女朋友最近在和誰聊QQ,偷偷安裝流氓軟件等.

上面我們了解微信搶紅包插件的原理,那么利用該AccessibilityService編寫相應的反搶紅包插件:通過模擬微信紅包的通知信息,發送虛假的事件通知.不出意外,我們編寫的反搶紅包插件會讓失眠絕大多數的搶紅包插件.這里我就不做深入的解釋,有興趣的同學可以自行研究.

你現在是不是想能否借助該服務直接獲取一些app的密碼呢?凡是EditText中設置inputType為password類型的,都無法獲取其輸入值.除此之外,大多數軟件都針對該中風險做了提前的防范.因此,你想要借助該服務來實現竊取密碼還是比較有難度的,所以,少年覺悟吧.

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 228,505評論 6 533
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 98,556評論 3 418
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 176,463評論 0 376
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,009評論 1 312
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 71,778評論 6 410
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,218評論 1 324
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,281評論 3 441
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,436評論 0 288
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 48,969評論 1 335
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 40,795評論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 42,993評論 1 369
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,537評論 5 359
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,229評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,659評論 0 26
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,917評論 1 286
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,687評論 3 392
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 47,990評論 2 374

推薦閱讀更多精彩內容

  • Spring Cloud為開發人員提供了快速構建分布式系統中一些常見模式的工具(例如配置管理,服務發現,斷路器,智...
    卡卡羅2017閱讀 134,785評論 18 139
  • Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 172,661評論 25 708
  • ¥開啟¥ 【iAPP實現進入界面執行逐一顯】 〖2017-08-25 15:22:14〗 《//首先開一個線程,因...
    小菜c閱讀 6,483評論 0 17
  • 晚風如醉 思念你的心 就像那漲潮的海水 奔騰著 永不退卻 每個夜晚 都是思念你的夜晚 每次,你都會調皮的 悄悄的 ...
    水果沙拉黑閱讀 178評論 0 1
  • 時間管理〔習慣〕: 今早聽得印象最深的一句話是:管理時間的基礎是精力管理(能量――身體的體能,情緒,精神,情...
    曦哈小子閱讀 180評論 0 0