收听传入的 Whatsapp 消息/通知

问题描述 投票:0回答:5

我正在开发一个基于通知的应用程序,为此我需要收听传入的通知。我已经能够收听来电、短信、邮件等。我不知道如何通过代码收听 Whatsapp 上朋友的 ping 或消息。这真的可以做到吗?如果是这样,如何? Accessibility Service 可以用于此吗,使用包名称作为“com.whatsapp”?

android android-intent android-notifications android-notification-bar android-broadcast
5个回答
20
投票

我能够使用 Accessibility Service 做到这一点。使用它,您可以收听通知栏上的所有通知。我通过将包名称添加到辅助功能服务

service info
来收听应用程序规范,在本例中为
com.whatsapp
。我无法阅读消息,但每当消息到达时我都会收到通知。


12
投票

2020 年 8 月 11 日更新

您可以使用

NotificationListenerService
收听通知并获取内容。

这是 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);
    }
}

要启用该服务,请将以下代码片段插入 AndroidManifest.xml 上的

<application>
标记中:

<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>

要拦截通知,您需要申请特殊权限。这是您可以用来打开设置页面的代码,用户必须在该页面中允许应用程序收听传入的通知。在我的项目中,我把它放在

MainActivity.onCreate
方法中。

startActivity(new Intent(ACTION_NOTIFICATION_LISTENER_SETTINGS))

如果需要检查通知监听权限是否被授予使用以下代码片段:

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;
}

旧答案

我在这篇 2 篇文章的帮助下收听了传入的 WhatsApp 消息通知,您可以从here阅读它。

  1. 配置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. /xml/
    目录中创建一个名为 serviceconfig.xml 的新文件。
<!-- 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. 创建一个新的
    MyAccessibilityService
    类,它扩展了
    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. 准备好了。现在您可以根据需要定制服务。

注意:由于辅助功能服务能够探索屏幕内容并与之交互,因此用户必须在设置 > 辅助功能中明确启用服务。 更多详情

注意

发送对收到通知的回复查看这个答案。


5
投票

除非该应用程序的开发人员有意共享服务、内容提供者,或有意发送事件的公共广播,或公开自定义广播注册系统,否则 android 中没有合法的方式来收听第三方应用程序的内部工作。 Android 中设计应用程序隔离有一个非常重要的原因:security.


3
投票

可访问性事件仅捕获传入的通知事件,而不是在它们更新时。目前,WhatsApp 通知不显示消息,只显示发件人。然后,WhatsApp 应用程序会添加该消息并进行更新,无障碍服务无法捕获该更新。

您只会看到类似“来自 XXX 的 1 条新消息”之类的内容,但这可能足以满足您的需求。


2
投票

请参阅以下示例以获取 whatsapp 通知:

public class Notifier extends AccessibilityService {


@Override
public void onCreate(){
    //Toast.makeText(this,"Oncreate", Toast.LENGTH_LONG).show();

}

@Override
protected void onServiceConnected() {
    // Set the type of events that this service wants to listen to.  Others
    // won't be passed to this service.
    Toast.makeText(this,"Service connected", Toast.LENGTH_LONG).show();
    AccessibilityServiceInfo info = new AccessibilityServiceInfo();
    info.feedbackType = AccessibilityServiceInfo.FEEDBACK_ALL_MASK;;
    info.eventTypes = AccessibilityEvent.TYPE_NOTIFICATION_STATE_CHANGED ;

    // If you only want this service to work with specific applications, set their
    // package names here.  Otherwise, when the service is activated, it will listen
    // to events from all applications.
    info.packageNames = new String[] {"com.whatsapp"};
    info.notificationTimeout = 100;

    setServiceInfo(info);

}

@Override
public void onAccessibilityEvent(AccessibilityEvent event) {

    if(event.getEventType() == AccessibilityEvent.TYPE_NOTIFICATION_STATE_CHANGED) {

            Toast.makeText(this,"Notification Catched", Toast.LENGTH_LONG).show();
        }

    }
}

并且不要忘记从设置>辅助功能中设置权限以访问系统事件。允许设置权限。

检查这个链接

无障碍服务未启动

© www.soinside.com 2019 - 2024. All rights reserved.