我正在开发一个基于通知的应用程序,为此我需要收听传入的通知。我已经能够收听来电、短信、邮件等。我不知道如何通过代码在 Whatsapp 上收听朋友的 ping 或消息。这真的可以做到吗?如果是这样,怎么做?可以使用辅助功能服务,使用包名称作为“com.whatsapp”吗?
5 回答
我能够使用Accessibility Service做到这一点。使用它,您可以收听通知栏上的所有通知。我通过将包名称添加到 Accessibility Service 来听取应用程序规范service info
,在本例中为com.whatsapp
. 我无法阅读这些消息,但只要有消息到达,我就会收到通知。
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中的代码:
<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>
要拦截通知,需要特殊权限。这是您可以用来打开设置页面的代码,用户必须允许应用程序收听传入的通知。我将此片段放在 MainActivityonCreate
函数中。
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;
}
PS:我不知道或无法解释它为什么/如何工作,因为我从我 1 岁的项目中复制了代码。
旧答案
我在这篇 2 篇文章的帮助下收听了传入的 WhatsApp 消息通知,您可以从这里阅读。
- 配置 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>
serviceconfig.xml
在/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" />
- 创建一个
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
}
}
}
}
- 准备好了。现在您可以根据自己的需要定制服务。
注意:由于无障碍服务能够探索屏幕内容并与之交互,因此用户必须在“设置”>“无障碍”中明确启用服务。更多细节
编辑
要发送对收到通知的回复,请查看此答案。
除非该应用程序的开发者故意共享服务、内容提供者,或故意发送事件的公共广播,或公开自定义广播注册系统,否则 android 中没有合法的方式来监听第三方应用程序的内部工作。在 Android 中设计应用程序隔离有一个非常重要的原因:安全性。
辅助功能事件仅捕获传入的通知事件,而不是在它们更新时。目前,WhatsApp 通知不显示消息,只显示发件人。然后,WhatsApp 应用程序会通过更新添加该消息,该更新无法被无障碍服务捕获。
您只会收到“来自 XXX 的 1 条新消息”之类的内容,但这可能足以满足您的需求。
请参阅以下示例以捕获 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();
}
}
}
并且不要忘记从设置>辅助功能设置权限以访问系统事件。允许来自设置的权限。
检查这个链接