Listen to incoming Whatsapp messages/notifications

I was able to do this using Accessibility Service . Using this, you can listen to all notification on the notification bar. I listened to application-specification by adding the package name to the Accessibility Service service info , which in this case was com.whatsapp. I couldn't read the messages, but I get notified whenever a message arrives.


Aug 11, 2020 Update

You can use NotificationListenerService to listen for notifications and get contents.

Here's example implementation in Java:

public class NotificationListener extends NotificationListenerService {

    private static final String TAG = "NotificationListener";
    private static final String WA_PACKAGE = "com.whatsapp";

    @Override
    public void onListenerConnected() {
        Log.i(TAG, "Notification Listener connected");
    }

    @Override
    public void onNotificationPosted(StatusBarNotification sbn) {
        if (!sbn.getPackageName().equals(WA_PACKAGE)) return;

        Notification notification = sbn.getNotification();
        Bundle bundle = notification.extras;

        String from = bundle.getString(NotificationCompat.EXTRA_TITLE);
        String message = bundle.getString(NotificationCompat.EXTRA_TEXT);

        Log.i(TAG, "From: " + from);
        Log.i(TAG, "Message: " + message);
    }
}

To enable the service insert the following code snippet into <application> tag on AndroidManifest.xml:

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

To intercept notifications, you need to request a special permission. Here's the code which you can use to open settings page where user have to allow the app to listen to incoming notifications. On my project I placed it in MainActivity.onCreate method.

startActivity(new Intent(ACTION_NOTIFICATION_LISTENER_SETTINGS))

If you need to check whether or not the notification listener permission is granted using the following code snippet:

private boolean isNotificationServiceEnabled(){
    String pkgName = getPackageName();
    final String flat = Settings.Secure.getString(getContentResolver(),
            ENABLED_NOTIFICATION_LISTENERS);
    if (!TextUtils.isEmpty(flat)) {
        final String[] names = flat.split(":");
        for (String name: names) {
            final ComponentName cn = ComponentName.unflattenFromString(name);
            if (cn != null) {
                if (TextUtils.equals(pkgName, cn.getPackageName())) {
                    return true;
                }
            }
        }
    }
    return false;
}

Old answer

I listened to incoming WhatsApp message notifications with the help of this 2 parted article which you can read it from here.

  1. Configure AndroidManifest.xml
<!-- AndroidManifest.xml -->
<service
    android:name=".MyAccessibilityService"
    android:enabled="true"
    android:exported="true"
    android:label="My application"
    android:permission="android.permission.BIND_ACCESSIBILITY_SERVICE">
    <intent-filter>
        <action android:name="android.accessibilityservice.AccessibilityService" />
    </intent-filter>

    <meta-data
        android:name="android.accessibilityservice"
        android:resource="@xml/serviceconfig" />
</service>
  1. Create a new file called serviceconfig.xml in /xml/ directory.
<!-- serviceconfig.xml -->
<accessibility-service
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:accessibilityEventTypes="typeAllMask"
    android:accessibilityFeedbackType="feedbackAllMask"
    android:accessibilityFlags="flagDefault"
    android:canRequestEnhancedWebAccessibility="true"
    android:notificationTimeout="100"
    android:packageNames="@null"
    android:canRetrieveWindowContent="true"
    android:canRequestTouchExplorationMode="true"  />
  1. Create a new MyAccessibilityService class which extends AccessibilityService.
@Override
protected void onServiceConnected() {
        System.out.println("onServiceConnected");
        AccessibilityServiceInfo info = new AccessibilityServiceInfo();
        info.eventTypes = AccessibilityEvent.TYPE_NOTIFICATION_STATE_CHANGED;
        info.feedbackType = AccessibilityServiceInfo.FEEDBACK_ALL_MASK;
        info.notificationTimeout = 100;
        info.packageNames = null;
        setServiceInfo(info);
}

@Override
public void onAccessibilityEvent(AccessibilityEvent event) {
    if (event.getEventType() == AccessibilityEvent.TYPE_NOTIFICATION_STATE_CHANGED) {
        if (event.getPackageName().toString().equals("com.whatsapp")){
            StringBuilder message = new StringBuilder();
            if (!event.getText().isEmpty()) {
                for (CharSequence subText : event.getText()) {
                    message.append(subText);
                }

                // Message from +12345678

            }
        }
    }
}
  1. It's ready. Now you can customize the service for your needs.

Note: Because accessibility services are able to explore and interact with on-screen content, a user has to explicitly enable services in Settings > Accessibility. More details

Note

To send replies to received notifications check out this answer.