Facebook messenger accessibility

1.8k views Asked by At

I am writing an accessibility app that helps users navigate on android using a mixture of voice controls and controls provided via external aiding tools. It uses MonkeyTalk Java API to do the heavier work.
To help the user about what is happening we use an accessibility service as well, which reads notification so the user can take action faster.

I've been informed that they get no audio cue when a message arrives on facebook messenger, and checking logs what I see is:

D/NotificationService(2665): package com.facebook.orcaText: []

and event.getText().size() returns 0 (on AccessibilityEvent event).
Right now they have to open the app and get the text read to them, which is 2 voice commands more...
I get all the other notifications correctly. I tried looking for documentation from facebook about their stance on accessibility but I found nothing.
Is there any way to get the text from their notifications?

2

There are 2 answers

4
Vikram On BEST ANSWER

You can try this to see if it works with Facebook messenger notifications. And even if this does work, I would suggest that you wait for a better solution.

From API 19 and above, Notification objects carry bundled extras - the inputs passed to Notification.Builder when the Notification was first created. So, information such as the title, context, summary etc. can be extracted from this Bundle using keys of form Notification.EXTRAS_XXXX. The keys can be found here: Link.

In the overriden onAccessibilityEvent(AccessibilityEvent event) method:

@Override
public void onAccessibilityEvent(AccessibilityEvent event) {
    Parcelable data = event.getParcelableData();

    if (data != null && data instanceof Notification) {
        Log.i("", "We have a notification to parse");

        Notification notification = (Notification) data;

        // For API 19 and above, `Notifications` carry an `extras` bundle with them
        // From this bundle, you can extract info such as:

        //      `EXTRA_TITLE`     -  as supplied to setContentTitle(CharSequence)
        //      `EXTRA_TEXT `     -  as supplied to setContentText(CharSequence)
        //      `EXTRA_INFO_TEXT` -  as supplied to setContentInfo(CharSequence)
        //      ... more at: http://developer.android.com/reference/android/app/Notification.html

        Bundle b = noti.extras;
        Log.i("Notification", "Title: " + b.get(Notification.EXTRA_TITLE));
        Log.i("Notification", "Text: " + b.get(Notification.EXTRA_TEXT));
        Log.i("Notification", "Info Text: " + b.get(Notification.EXTRA_INFO_TEXT));

        /////////////////////////////////////////////////////////////////

        // For API 18 and under:

        // Pass `notification` to a method that parses a Notification object - See link below

        List<String> notificationText = extractTextFromNotification(notification);
        ....
        ....
    }
}

extractTextFromNotification(Notification) can be a method from here: Link. Needless to say that this is a workaround, and will require quite a bit of testing to ensure that it works as required.

2
semsamot On

You may use getActiveNotifications method of NotificationListenerService to get an array of notifications that are visible to current user. The result is an StatusBarNotification array, So you can read the PackageName with getPackageName and if it matches with that you are looking for, then get the notification content from that object (with getNotification)...

You can extend NotificationListenerService class and register it as a service:

<service android:name=".NotificationListener"
      android:label="@string/service_name"
      android:permission="android.permission.BIND_NOTIFICATION_LISTENER_SERVICE">
 <intent-filter>
     <action android:name="android.service.notification.NotificationListenerService" />
 </intent-filter>
</service>

Also you can implement onNotificationPosted method to get notifications and even cancel notifications with cancelNotification method.

An example of using this service: https://github.com/kpbird/NotificationListenerService-Example

Note: User must enable notification permission from "Settings > Security > Notification access". You can open that setting with:

Intent intent=new Intent("android.settings.ACTION_NOTIFICATION_LISTENER_SETTINGS");
startActivity(intent);