Reference to:http://www.infoq.com/cn/articles/android-accessibility-installing?utm_campaign=infoq_content& Utm_source=infoq&utm_medium=feed&utm_term=global
For domestic Android devices, automatic batch installation/update of applications has always been a pain point, before the third-party store typically requires device root and then calls the system's Packagemanagerservice command line for background installation. Recently, pea pods have been the first in the industry to achieve the root-free automatic batch installation function using the Android Accessibility (auxiliary function).
This function realizes the principle is, after the background batch downloads the application, calls the system Packageinstaller, obtains the installation interface the button position, then through accessibility provides the simulation user to click the function, replaces the user automatically clicks Next, until installs the end.
Although technology does not seem particularly difficult, there are still a lot of holes in the implementation, and Pea pod Engineers share some of the technical details and practical experience of the feature.
Android Accessibility API Introduction and calling method
For those who are unable to use Android smartphones for their eyesight, hearing or other physical reasons, Android offers accessibility features and services to help these users operate devices more simply, including text-to-speech, haptic feedback, gesture manipulation, Trackball and handle operation. Developers can build their own accessibility services, which can enhance the usability of the application, such as sound cues, physical feedback, and other optional modes of operation.
With the Android version of the iteration, the accessibility function is also more and more powerful, it can be in real-time access to the current operation of the application window element information, and the ability to interact in two directions, both to obtain the user's input, but also to manipulate the window elements, such as Click button. See the accessibility page of the Android developer website for more information.
Calling the Android Accessibility API requires three steps: Request permission, register service, configure accessibility service Info. The following permissions are required to use the Accessibility API:
<uses-permission android:name= "Android.permission.BIND_ACCESSIBILITY_SERVICE"/>
Sign up for service
<service android:name= "Com.your.AccessibilityImpl.className" android:label= "@string/acc_auto_ Install_service_name " android:permission=" Android.permission.BIND_ACCESSIBILITY_SERVICE " android:enabled= "@bool/enable_accessibility" > <intent-filter> <action android:name= " Android.accessibilityservice.AccessibilityService "/> </intent-filter> <meta-data android: Name= "Android.accessibilityservice" android:resource= "@xml/accessibility_config"/></service>
Configuring accessibility Service Info
<?xml version= "1.0" encoding= "Utf-8"? ><accessibility-Service xmlns:android= "http// Schemas.android.com/apk/res/android " android:description=" @string/acc_description "Android: Accessibilityeventtypes= "Typeallmask" android:accessibilityflags= "Flagdefault" android: Accessibilityfeedbacktype= "Feedbackgeneric" android:notificationtimeout= " Android:canretrievewindowcontent= "true" android:settingsactivity= " Com.your.settingActivity " android:packagenames=" Packagename1,packagename2 "/>
One point to note is that if you explicitly know the package name of the target app when configuring accessibility Service info, be sure to set it using the Packagenames property. To give an example:
In some apps that use a virtual keyboard, this logic often appears
Button Button == (String) button.gettext ();
In general, the getText
return value of a method is an instance of the Java.lang.String
class, and the above code works correctly. However, if Packagenames is not specified after the accessibility service is turned on, the UI of all apps is accessible processed. The expression in this example is that the getText
return value of the method becomes an android.text.SpannableString
instance of the class ( Java.lang.String
and android.text.SpannableString
both implements the java.lang.CharSequence
interface), which in turn causes the target app to crash.
Therefore, it is highly recommended to Accessibility Service
specify the target app's PackageName at the time of registration to reduce the inexplicable crashes of other apps on the phone (you have this logic in your code, and you can call it silently instead toString()
).
Implement Accessibilityservice
Inheritance android.accessibilityservice.AccessibilityService
and overloading onAccessibilityEvent
and onInterrupt
methods:
Public class extends Accessibilityservice { @Override publicvoid onaccessibilityevent ( Accessibilityevent event) {} @Override publicvoid oninterrupt () {}}
Author Xuchuan released on May 28, 2015 | Discussion
- Share to: Weibo Facebook Twitter Youdao Cloud Note email sharing
Read later
My list of reading
For domestic Android devices, automatic batch installation/update of applications has always been a pain point, before the third-party store typically requires device root and then calls the system's Packagemanagerservice command line for background installation. Recently, pea pods have been the first in the industry to achieve the root-free automatic batch installation function using the Android Accessibility (auxiliary function).
This function realizes the principle is, after the background batch downloads the application, calls the system Packageinstaller, obtains the installation interface the button position, then through accessibility provides the simulation user to click the function, replaces the user automatically clicks Next, until installs the end.
Although technology does not seem particularly difficult, there are still a lot of holes in the implementation, and Pea pod Engineers share some of the technical details and practical experience of the feature.
Android Accessibility API Introduction and calling method
For those who are unable to use Android smartphones for their eyesight, hearing or other physical reasons, Android offers accessibility features and services to help these users operate devices more simply, including text-to-speech, haptic feedback, gesture manipulation, Trackball and handle operation. Developers can build their own accessibility services, which can enhance the usability of the application, such as sound cues, physical feedback, and other optional modes of operation.
With the Android version of the iteration, the accessibility function is also more and more powerful, it can be in real-time access to the current operation of the application window element information, and the ability to interact in two directions, both to obtain the user's input, but also to manipulate the window elements, such as Click button. See the accessibility page of the Android developer website for more information.
Calling the Android Accessibility API requires three steps: Request permission, register service, configure accessibility service Info. The following permissions are required to use the Accessibility API:
<uses-permission android:name= "Android.permission.BIND_ACCESSIBILITY_SERVICE"/>
Sign up for service
<service android:name= "Com.your.AccessibilityImpl.className" android:label= "@string/acc_auto_install_ Service_Name " android:permission=" Android.permission.BIND_ACCESSIBILITY_SERVICE " android:enabled=" @ Bool/enable_accessibility "> <intent-filter> <action android:name=" Android.accessibilityservice.AccessibilityService "/> </intent-filter> <meta-data android: Name= "Android.accessibilityservice" android:resource= "@xml/accessibility_config"/></service>
Configuring accessibility Service Info
<?xml version= "1.0" encoding= "Utf-8"? ><accessibility-service xmlns:android= "/http Schemas.android.com/apk/res/android " android:description=" @string/acc_description "Android: Accessibilityeventtypes= "Typeallmask" android:accessibilityflags= "Flagdefault" android: Accessibilityfeedbacktype= "Feedbackgeneric" android:notificationtimeout= "Android" : Canretrievewindowcontent= "true" android:settingsactivity= "com.your.settingActivity" android: packagenames= "Packagename1,packagename2"/>
One point to note is that if you explicitly know the package name of the target app when configuring accessibility Service info, be sure to set it using the Packagenames property. To give an example:
In some apps that use a virtual keyboard, this logic often appears
Button button = (button) Findviewbyid (R.id.button); String num = (string) button.gettext ();
In general, the getText
return value of a method is an instance of the Java.lang.String
class, and the above code works correctly. However, if Packagenames is not specified after the accessibility service is turned on, the UI of all apps is accessible processed. The expression in this example is that the getText
return value of the method becomes an android.text.SpannableString
instance of the class ( Java.lang.String
and android.text.SpannableString
both implements the java.lang.CharSequence
interface), which in turn causes the target app to crash.
Therefore, it is highly recommended to Accessibility Service
specify the target app's PackageName at the time of registration to reduce the inexplicable crashes of other apps on the phone (you have this logic in your code, and you can call it silently instead toString()
).
Implement Accessibilityservice
Inheritance android.accessibilityservice.AccessibilityService
and overloading onAccessibilityEvent
and onInterrupt
methods:
public class Accessibilityimpl extends Accessibilityservice { @Override public void Onaccessibilityevent ( Accessibilityevent event) {} @Override public void Oninterrupt () {}}
Implement the business logic code with onaccessibilityevent and Oninterrupt as the portal.
How to get UI elements
In onAccessibilityEvent
, the instance that was obtained using the method of the parameter event is the getSource
AccessibilityNodeInfo
UI node that triggered the event.
If you need to get other elements on the current interface, you need to get to the root node of the current UI tree and then use it findAccessibilityNodeInfosByText
or findAccessibilityNodeInfosByViewId
retrieve it.
It is important to note that the findAccessibilityNodeInfosByText
logic for determining the UI elements is contains rather than equals, and may be used in a further process based on the specific business logic.
Simulate user clicks
After implementing Accessibilityservice and getting UI elements on the interface, you can use the following code to simulate user clicks:
Nodeinfo.performaction (Accessibilitynodeinfo.action_click);
It is important to note that before triggering an event, you need to determine whether the UI element still exists on the interface. This method can also be used to simulate the user's other actions, or even copy and paste this behavior, specifically refer to Accessibilitynodeinfo.
Reference to:http://stackoverflow.com/questions/18094982/detect-if-my-accessibility-service-is-enabled
Check is Accessibilityservice are swith on
//To Check if service is enabled Private BooleanIsaccessibilitysettingson (Context mcontext) {intaccessibilityenabled = 0; FinalString service = mcontext.getpackagename () + File.separator + mcontext.getpackagename () + ". Accesibility. Myaccesibilityservice "; BooleanAccessibilityfound =false; Try{accessibilityenabled=Settings.Secure.getInt (Mcontext.getapplicationcontext (). Getcontentresolver (), Android.provider.Settings.Secure.ACCESSIBILITY_ENABLED); LOG.V (TAG,"accessibilityenabled =" +accessibilityenabled); } Catch(Exception e) {log.e (TAG,"Error finding setting, default accessibility to not found:" +e.getmessage ()); } textutils.simplestringsplitter Mstringcolonsplitter=NewTextutils.simplestringsplitter (': ')); if(accessibilityenabled = = 1) {log.v (TAG,"***accessibiliy is enabled***-----------------"); String Settingvalue=Settings.Secure.getString (Mcontext.getapplicationcontext (). Getcontentresolver (), Settings.Secure.ENABLED_ACCESSIBILITY_SERVICES); if(Settingvalue! =NULL) {Textutils.simplestringsplitter splitter=Mstringcolonsplitter; Splitter.setstring (Settingvalue); while(Splitter.hasnext ()) {String Accessabilityservice=Splitter.next (); LOG.V (TAG,"--------------> Accessabilityservice::" +Accessabilityservice); if(accessabilityservice.equalsignorecase (service)) {LOG.V (TAG,"We ' ve found the correct setting-accessibility is switched on!"); return true; } } } } Else{log.v (TAG,"***accessibiliy is disabled***"); } returnAccessibilityfound; }
Go to Setting UI:
if (!isaccessibilitysettingson (this)) { startactivity(new Intent ( settings.action_accessibility_settings)); }
[Android Pro] Android 4.1 uses accessibility for root-free automatic batch installation