利用NotificationListenerService獲取微信通知消息的頭像和內容

強調下:利用Android原生功能獲取第三方APP通知消息是流氓且不道德的(可能沾上官司),本文只講原理

強調下:利用Android原生功能獲取第三方APP通知消息是流氓且不道德的(可能沾上官司),本文只講原理

強調下:利用Android原生功能獲取第三方APP通知消息是流氓且不道德的(可能沾上官司),本文只講原理

提供一篇靈感文章,寫的很好推薦看看https://blog.csdn.net/Vanswells/article/details/81033280

獲取Android 微信通知有兩條思路,一條是走輔助功能(AccessibilityService),一條是走NotificationListenerService,這裏講第二條路NotificationListenerService。

在App中加入一個類繼承NotificationListenerService,用法類似於AccessibilityService,都是需要開通一個權限,但是開通的權限不同

需要在應用啓動的時候加一個權限判斷,沒有開啓跳轉到對應的Settings界面

private void toggleNotificationListenerService(Context context) {
        PackageManager pm = context.getPackageManager();
        pm.setComponentEnabledSetting(new ComponentName(context, MyNotificationListenerService .class),
                PackageManager.COMPONENT_ENABLED_STATE_DISABLED, PackageManager.DONT_KILL_APP);
 
        pm.setComponentEnabledSetting(new ComponentName(context, MyNotificationListenerService .class),
                PackageManager.COMPONENT_ENABLED_STATE_ENABLED, PackageManager.DONT_KILL_APP);
    }
 
    protected boolean gotoNotificationAccessSetting() {
        try {
            Intent intent = new Intent("android.settings.ACTION_NOTIFICATION_LISTENER_SETTINGS");
            intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
            startActivity(intent);
            return true;
        } catch (ActivityNotFoundException e) {//普通情況下找不到的時候需要再特殊處理找一次
            try {
                Intent intent = new Intent();
                intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                ComponentName cn = new ComponentName("com.android.settings", "com.android.settings.Settings$NotificationAccessSettingsActivity");
                intent.setComponent(cn);
                intent.putExtra(":settings:show_fragment", "NotificationAccessSettings");
                startActivity(intent);
                return true;
            } catch (Exception e1) {
                e1.printStackTrace();
            }
            Toast.makeText(this, "對不起,您的手機暫不支持", Toast.LENGTH_SHORT).show();
            System.out.println("-------------對不起,您的手機暫不支持------------->>");
            e.printStackTrace();
            return false;
        }
    }
 
    public boolean isNotificationListenersEnabled() {
        String pkgName = getPackageName();
        final String flat = Settings.Secure.getString(getContentResolver(), "enabled_notification_listeners");
        System.out.println("-----flat-------->" + flat);
        if (!TextUtils.isEmpty(flat)) {
            final String[] names = flat.split(":");
            for (int i = 0; i < names.length; i++) {
                final ComponentName cn = ComponentName.unflattenFromString(names[i]);
                if (cn != null) {
                    if (TextUtils.equals(pkgName, cn.getPackageName())) {
                        return true;
                    }
                }
            }
        }
        return false;
    }
權限開通以後,在sevices中就可以獲取到我們想要的數據了

import android.app.Notification;
import android.app.PendingIntent;
import android.graphics.Bitmap;
import android.os.Bundle;
import android.service.notification.NotificationListenerService;
import android.service.notification.StatusBarNotification;
 
import org.greenrobot.eventbus.EventBus;
 
 
public class MyNotificationListenerService extends NotificationListenerService {
 
    @Override
    public void onListenerConnected() {
        //當連接成功時調用,一般在開啓監聽後會回調一次該方法
        System.out.println("----------------onListenerConnected--------->");
    }
 
    @Override
    public void onNotificationPosted(StatusBarNotification sbn) {
        //當收到一條消息時回調,sbn裏面帶有這條消息的具體信息
        System.out.println("----------------onNotificationPosted--------->");
        System.out.println("----------------onNotificationPosted----1----->" + sbn.getPackageName());
        Bundle extras = sbn.getNotification().extras;
        String title = extras.getString(Notification.EXTRA_TITLE); //通知title
        String content = extras.getString(Notification.EXTRA_TEXT); //通知內容
        int smallIconId = extras.getInt(Notification.EXTRA_SMALL_ICON); //通知小圖標id
        Bitmap largeIcon =  extras.getParcelable(Notification.EXTRA_LARGE_ICON); //通知的大圖標,注意和獲取小圖標的區別
        PendingIntent pendingIntent = sbn.getNotification().contentIntent; //獲取通知的PendingIntent
        System.out.println("----------------onNotificationPosted----1--1--->" + extras);
        System.out.println("----------------onNotificationPosted----2----->" + title);
        System.out.println("----------------onNotificationPosted----3----->" + content);
        System.out.println("----------------onNotificationPosted----4----->" + smallIconId);
        System.out.println("----------------onNotificationPosted----5----->" + largeIcon);
        System.out.println("----------------onNotificationPosted----6----->" + pendingIntent);
 
        NoticesBean mBean = new NoticesBean();
        mBean.setLargeIcon(largeIcon);
        mBean.setSmallIconId(smallIconId);
        if (title == null || largeIcon == null) {
            return;
        }
        EventBus.getDefault().post(mBean);
    }
 
    @Override
    public void onNotificationRemoved(StatusBarNotification sbn) {
        //當移除一條消息的時候回調,sbn是被移除的消息
        System.out.println("----------------onNotificationRemoved--------->");
    }
}
log就看的很明顯了

title可以用來區分是羣聊還是個人消息,如果是羣聊,title就是羣聊,如果是個人消息,這裏就顯示消息的發送人

content 是通知消息內容,結構是這樣的:[第幾條]發件人: 消息內容

largeIcon:獲取頭像直接用就可以了(個人聊天是可以拿到一個bitmap對象,羣聊獲取的值是null或者是bitmap對象,是null還是bitmap主要取決於title值的內容,如果title值是“羣聊”,那就是null,如果不是羣聊就會有頭像的bitmap對象)

smallIcon:值衡爲0

我加的非空判斷是因爲有時候會有收到一條消息,但是上報兩次,其中第二次是任何數據都沒的,爲了過濾掉無效數據,這裏加個判斷

由於數據是在service中獲取的,我們肯定是要在Activity或者是fragment中修改view,用EventBus傳遞數據就可以,很方便

 

在AndroidManifest.xml配置service

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

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章