If you’re developing a DLP or Parent Control solution,
chances are, you want as much user data from apps as possible. However, most of
the time gathering such data can be fairly difficult. While you can try to
reverse engineer iOS app or Android app, this method often proves difficult and
time-consuming, while results are not guaranteed.
For Android particularly, most of the time apps store their data in a Sandbox (which is the default and most secure option) where other apps cannot access it. If a developer decides not to store data in another easily accessible area (such as memory card), and not to provide an API for accessing the data, then getting it without root can be very hard.
This means that there is seemingly no way to get Skype, Viber, or KIK messages, or a browser history, which can be extremely frustrating if your solution depends on such data. However, there is actually a fairly elegant solution allowing to get user data on Android without root and without that much of a hassle. And we will cover this solution down the line.
Idea behind a solution
The gist of the idea is very simple – each active page has a layout three that we can parse and get all the data we want. This will correctly work with the latest Android N and previous versions all the way back to and include 4.3.
The catch, though, is that to get clean and readable data without any junk in it, you would need to learn how each app you decided to target structures data while displaying it on screen.\
Now, let’s go straight to business. Android features a service and an API specifically designed to help developers create apps for people with disabilities. It is called Accessibility Service.
This service has a high level of access and can:
· Get screen state change events, allowing it to know when new information is displayed on the screen or when layout changes
· Fully read all displayed content on an active screen.
Thus, what we need to do is to create our own Accessibility Service, that will get all the data from the screen and monitor it for changes. Then this service can parse data and save bits and pieces that we need, such as URLs or Skype messages, etc.
So, to start, first we create a service class in Java. Next, we need to declare our new service as an AccessibilityService in the manifest, while also setting a config file.
Next, we need to create a configuration file where we will store parameters for our service.
The attributes, mentioned above, are fairly important, because they allow us to specify what kind of data we expect to receive:
· android:accessibilityEventTypes - this attribute ensures that we will receive any and all accessibility events. It may seem a little bit excessive, but it is better to have more data than to miss something important.
· android:accessibilityFlags – this attribute allows us to receive all the data on screen regardless of its type. This includes things like insignificant View and element id among others.
· android:canRetrieveWindowContent – this is the most important thing on our list. This attribute provides us with the layout three that we need to get all the data.
Now the only thing that we need to do is to make an inheritance from AccessibilityService in Java. The system uses onAccessibilityEvent to store the View tree in the parameters, thus, we need to implement it, as well as onInterrupt, which can be left empty.
And now what’s left is a piece of cake. AccessibilityEvent is received in onAccessibilityEven parameter, and to get the name of an app that started it we use getPackageName, and then use getEventType to find out what exactly happened. This data is then used to help us find what we need by filtering the results.
Next, we can go through the full tree (by using getSource, getChild, and getChildCount), and gather all kinds of data, such as class, id, and text (by using getClassName, getViewidResourceName, and getText). The text is what will get us our data, such as instant messages content and browsing history.
Thus, the main challenge of this approach is the fact that you need to go through various tree nodes and filter them based on info you have, such as class name, and id. This process is very dependent on your target application – data from one may be easier to filter than from the other.
Pros and Cons of the approach
Probably the main advantage of this approach is that it is simple and reliable, and doesn’t require root. Accessibility Service also stays enabled after reboot, meaning you don’t need to pester your users more than once.
Also, in theory, this approach allows not only to gather data, but also control user action, such as prohibiting to change certain settings and maybe even control user screen.
But what’s more important, is that this approach uses a public API provided by Google, which means that any apps using it are most likely good to go with regards to Google Play. In fact, there are several apps on it right now that use this exact method to gather data.
At the same time, the main shortfall of this method is the fact that it heavily utilizes the way applications store their data. This means that you need an individual approach to each target app, and if the way an app displays its data is ever updated, you also will need to update your parser. Moreover, you need to write a separate logic for storing data to counter such things as random screen scrolls or chat window switching.
Another non-obvious disadvantage is the fact that this method, depending on the amount of data and performance of the device can severely affect battery life. To counter this, you need to make sure to carefully filter target apps for monitoring and set generous time intervals between receiving events.
It is also worth noting that for the solution to work, Accessibility Service needs to be explicitly enabled by the user, although, as mentioned above, they need to do it only once.
Finally, as a conclusion, it is worth nothing that accessing private user data without their consent is illegal and can result in a lawsuit. The method described above was designed with legitimate purposes in mind, and needs to be used very carefully with full respect of the law and users’ privacy. Be careful, but don’t be afraid to experiment and create innovative and useful solutions.