Open In App

How to Create an Accessibility Service in Android with Example?

Last Updated : 26 Oct, 2021
Improve
Improve
Like Article
Like
Save
Share
Report

Accessibility service is like a magic wand provided by the Android Framework. Although the sole purpose of the Accessibility service is to provide differently-abled an ease to access to their device, it can also be used to implement some functionalities that can help any user in his day-to-day phone usage. It is highly recommended that you should first go through this Accessibility Service in Android article before proceeding with this one.

1.  Creating the service class

Firstly create a regular class, extend the class with AccessibilityService class and override the mandatory methods. An accessibility service can either be used in a regular project or can be developed as a standalone project.

Java




/*package whatever //do not write package name here */
import android.accessibilityservice.AccessibilityService;
import android.view.accessibility.AccessibilityEvent;
  
public class MyService extends AccessibilityService {
...
    @Override
    public void onAccessibilityEvent(AccessibilityEvent event) {
    }
  
      @Override
    public void onInterrupt() {
  
    }
...
}


 
 

2. Manifest declarations and permissions

 

To be considered as an accessibility service by the Android framework, applications that offer accessibility services must include specific declarations in their application manifests. The permission required for the Accessibility service is not the same as the regular ones. Like any other service, we need to declare it in the Manifest under the application element. In order to differentiate this service from other regular services, we must also include an accessibility service intent filter. Within the service, we need to declare permission to ensure that only the system can bind to it. The label attribute in service is the text that would appear at the time user would explicitly turn on the service through the device settings. This is generally either your app name or the service name.

 

XML




<application>
    <service android:name=".MyService"
        android:permission="android.permission.BIND_ACCESSIBILITY_SERVICE"
        android:label="@string/accessibility_service_label">
      <intent-filter>
        <action android:name="android.accessibilityservice.AccessibilityService" />
      </intent-filter>
    </service>
</application>


 
 

3. Accessibility service configuration

 

There are mainly two methods of configuring the service.

 

Step 1: First by creating an XML config file and declaring and defining all the required attributes. Create a new android resource directory, XML, by right-clicking on the res folder. Now in the XML folder create accessibility_service_config.xml

 

XML




<accessibility-service xmlns:android="http://schemas.android.com/apk/res/android"
    android:description="@string/accessibility_service_description"
    android:packageNames="com.example.android.sampleapp1,com.example.android.sampleapp2"
    android:accessibilityEventTypes="typeAllMask"
    android:accessibilityFlags="flagDefault"
    android:accessibilityFeedbackType="feedbackSpoken"
    android:notificationTimeout="100"
    android:canRetrieveWindowContent="true"
    android:settingsActivity="com.example.android.accessibility.ServiceSettingsActivity"
/>


 
 

This code defines the kinds of events that our application can react to, the types of input that the application may offer, and the specific packages which this application can listen to like if you want your application to only manage events that arise from a particular application, or get an event in a particular time frame, retrieve window contents, etc. In this method, we must reference the XML config file in our manifest’s service tag, by adding <meta-data> tag inside it.

 

XML




<service android:name=".MyService">
  ...
  <meta-data
    android:name="android.accessibilityservice"
    android:resource="@xml/accessibility_service_config" />
</service>


 
 

Step 2: The second is by dynamically setting up the attributes using setServiceInfo(AccessibilityServiceInfo) method in the onServiceConnected method.

 

Java




@Override
public void onServiceConnected() {
    // pass the typeof events you want your service to listen to
      // other will not be handledby this service
    info.eventTypes = AccessibilityEvent.TYPE_VIEW_CLICKED |
            AccessibilityEvent.TYPE_VIEW_FOCUSED;
  
    // In case you want your service to work only with a particular application
    //or when that application is in foreground, you should specify those applications package
    //names here, otherwise the service would listen events from all the applications
    info.packageNames = new String[]
            {"com.example.android.myFirstApp", "com.example.android.mySecondApp"};
  
    // Set the type of feedback your service will provide.
    info.feedbackType = AccessibilityServiceInfo.FEEDBACK_SPOKEN;
    // the notification timeout is the time interval after which the service would
      // listen from the system. Anything happening between that interval won't be
      // captured by the service
    info.notificationTimeout = 100;
  
      // finally set the serviceInfo
    this.setServiceInfo(info);
  
}


 
 

Now, since we have successfully instantiated the Accessibility service let’s have an example to understand it’s working.

 

Example

 

In this example let us make a service that listens for the key events of the device, i.e. when the user presses the volume up and down key, our service would receive the callback and perform any specific task.

 

Step 1: Create a New Project

 

To create a new project in Android Studio please refer to How to Create/Start a New Project in Android Studio. Note that select Java as the programming language.

 

Step 2: Create accessibility_service_config.xml

 

Create a new layout resource file and name the file as accessibility_service_config. Below is the code for the accessibility_service_config.xml file. 

 

XML




<?xml version="1.0" encoding="utf-8"?>
<accessibility-service xmlns:android="http://schemas.android.com/apk/res/android"
    android:packageNames=""
    android:accessibilityEventTypes="typeAllMask"
    android:accessibilityFlags="flagRequestFilterKeyEvents"
    android:accessibilityFeedbackType="feedbackSpoken"
    android:notificationTimeout="100"
    android:canRetrieveWindowContent="true"
    android:canRequestFilterKeyEvents="true"
    android:settingsActivity="com.example.android.accessibility.ServiceSettingsActivity"
    />


 
 

Step 3: Create MyService class

 

Create a java class in Android Studio and name the class as MyService. Below is the code for the MyService.java file. 

 

Java




import android.accessibilityservice.AccessibilityService;
import android.util.Log;
import android.view.KeyEvent;
import android.view.accessibility.AccessibilityEvent;
import android.widget.Toast;
  
public class MyService extends AccessibilityService {
    @Override
    public void onAccessibilityEvent(AccessibilityEvent accessibilityEvent) {
    }
  
    @Override
    public void onInterrupt() {
  
    }
  
    @Override
    protected boolean onKeyEvent(KeyEvent event) {
  
        int action = event.getAction();
        int keyCode = event.getKeyCode();
        // the service listens for both pressing and releasing the key
        // so the below code executes twice, i.e. you would encounter two Toasts
        // in order to avoid this, we wrap the code inside an if statement
        // which executes only when the key is released
        if (action == KeyEvent.ACTION_UP) {
            if (keyCode == KeyEvent.KEYCODE_VOLUME_UP) {
                Log.d("Check", "KeyUp");
                Toast.makeText(this, "KeyUp", Toast.LENGTH_SHORT).show();
            } else if (keyCode == KeyEvent.KEYCODE_VOLUME_DOWN) {
                Log.d("Check", "KeyDown");
                Toast.makeText(this, "KeyDown", Toast.LENGTH_SHORT).show();
            }
        }
            return super.onKeyEvent(event);
    }
}


Step 4: Working with the AndroidManifest.xml file

Below is the code for the AndroidManifest.xml file. 

XML




<?xml version="1.0" encoding="utf-8"?>
    package="com.raghav.gfgkeyevent">
  
    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/Theme.GFGKeyEvent">
        <activity android:name=".MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
  
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
  
        <service android:name=".MyService"
            android:permission="android.permission.BIND_ACCESSIBILITY_SERVICE"
            android:label="">
            <intent-filter>
                <action android:name="android.accessibilityservice.AccessibilityService" />
            </intent-filter>
  
            <meta-data
                android:name="android.accessibilityservice"
                android:resource="@xml/accessibility_service_config" />
        </service>
  
    </application>
  
</manifest>


 
 

Step 5: Working with the MainActivity.java file

 

Go to the MainActivity.java file and refer to the following code. Below is the code for the MainActivity.java file. Comments are added inside the code to understand the code in more detail.

 

Java




import androidx.appcompat.app.AppCompatActivity;
  
import android.content.Intent;
import android.os.Bundle;
import android.provider.Settings;
import android.widget.Toast;
  
public class MainActivity extends AppCompatActivity {
  
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
  
        if(!checkAccessibilityPermission()){
            Toast.makeText(MainActivity.this, "Permission denied", Toast.LENGTH_SHORT).show();
        }
    }
  
    // method to check is the user has permitted the accessibility permission
    // if not then prompt user to the system's Settings activity
    public boolean checkAccessibilityPermission () {
        int accessEnabled = 0;
        try {
            accessEnabled = Settings.Secure.getInt(this.getContentResolver(), Settings.Secure.ACCESSIBILITY_ENABLED);
        } catch (Settings.SettingNotFoundException e) {
            e.printStackTrace();
        }
        if (accessEnabled == 0) {
            // if not construct intent to request permission
            Intent intent = new Intent(Settings.ACTION_ACCESSIBILITY_SETTINGS);
            intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
            // request permission via start activity for result
            startActivity(intent);
            return false;
        } else {
            return true;
        }
    }
}


 
 



Like Article
Suggest improvement
Previous
Next
Share your thoughts in the comments

Similar Reads