让你监控Android手机的通知栏

2016.6.12更新

最最主要的源码其实就只有下面我提到的这些了,最核心的功能都在上面了,以及可能碰到的坑。

代码已经开源到github,地址:

https://github.com/zhuohui/AndMonitor


原文:


有段时间没写博了,想着还是要写点东西,免得生疏了,正好前段时间做了一个抓取通知栏的功能,期间也走了一些弯路,

通过网上查资料,看Android源码,最终总算解决了监控通知栏的功能。实现的效果如下:



不过在使用通知栏监控之前,首先要进行设置,要让手机允许你监控通知栏,毕竟这是很隐私的操作,不然如果没有这个允许动作,那么Android手机也太危险了,

包括聊天信息,短消息都有可能被监控。设置如下:


在辅助功能这里,开启NotificationMonitor服务。

接下来来讲一下实现方法:

首先写一个类继承AccessibilityService,AccessibilityService辅助服务,可以看官方介绍:

http://developer.android.com/reference/android/accessibilityservice/AccessibilityService.html

这个服务运行在后台,当有定义的的AccessibilityEvent被触发时,则会进行相应的回调函数,通知栏需要使用到的事件是:

AccessibilityEvent.TYPE_NOTIFICATION_STATE_CHANGED
也就是通知栏状态变化事件。

代码如下:

public class NeNotificationService extends AccessibilityService {

	
	@Override
	public void onAccessibilityEvent(AccessibilityEvent event) {
		
		//判断辅助服务触发的事件是否是通知栏改变事件
	    if (event.getEventType() == AccessibilityEvent.TYPE_NOTIFICATION_STATE_CHANGED) 
	    {
	    	
	    		//获取Parcelable对象
	    		Parcelable data = event.getParcelableData();
	    		
	    		//判断是否是Notification对象
				if (data instanceof Notification) {
				
					Notification notification = (Notification) data;
					
					Intent intent = new Intent();
					intent.putExtra("NotifyData", notification);
					intent.putExtra("packageName", event.getPackageName());
					
					intent.setAction(".NeNotificationService");
				
					//进行处理解析通知栏内容的函数
					MainActivity.notifyReceive((String)event.getPackageName(), notification);
				
	    }else
	    {
	    	
	    }
	    
	}
	
	
	/**
	*Service被启动的时候会调用这个API
	*/
	@Override
	protected void onServiceConnected() {

		//设置关心的事件类型
	    AccessibilityServiceInfo info = new AccessibilityServiceInfo();
	    info.eventTypes = AccessibilityEvent.TYPE_NOTIFICATION_STATE_CHANGED |
				AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED | 
				AccessibilityEvent.TYPE_WINDOW_CONTENT_CHANGED;
	    info.feedbackType = AccessibilityServiceInfo.FEEDBACK_GENERIC;
	    info.notificationTimeout = 100;//两个相同事件的超时时间间隔
	    setServiceInfo(info);
	}
}

这个服务类在使用之前肯定是要先被启动的,启动可以放在MainActivity的某个按钮点击时:

//在MainActivity.onCreate里初始化
Intent upservice = new Intent(this, NeNotificationService.class); 

//按钮按下时更新或启动服务
accesscStartNo.setOnClickListener(new View.OnClickListener() {
			
			@Override
			public void onClick(View v) {
				updateServiceStatus(true);
			}
		});

//这里防止多次启动服务,所以先判断服务是否在运行中
private void updateServiceStatus(boolean start)
	{
		boolean bRunning = util.isServiceRunning(this, "com.nis.bcreceiver.NeNotificationService");
		
		//没有Running则启动
		if (start && !bRunning) {
			this.startService(upservice);
		} else if(!start && bRunning) {
			this.stopService(upservice);
		}		
		
	}

//另外需要在AndroidManifest.xml文件中配置
<service android:name="com.nis.bcreceiver.NeNotificationService"
        android:permission="android.permission.BIND_ACCESSIBILITY_SERVICE"
        android:label="NotificationMonitor"
        android:enabled="true"
        android:exported="false">
        <intent-filter>
            <action android:name="android.accessibilityservice.AccessibilityService"/>
        </intent-filter>
         <meta-data
            android:name="android.accessibilityservice"
            android:resource="@xml/accessibilityservice" />
    </service>


这样我们基本完成了Notification的监控和抓取,至于如果你想解析出什么数据,就可以处理这个
notification变量。通过多个程序的测试,发现notification里比较有用的就是contentView,这是一个直接显示在
</pre></p><p>界面上的View,我们只要解析它就可以获取展示的View的标题及文本内容,处理代码如下:</p><p><pre name="code" class="java">  private void AnalyzeView(RemoteViews remoteView, String packName) {

		try {
			//把RemoteView apply后变成当前可以处理的View
			View v1 = remoteView.apply(this, rootLayout);
		
			//然后就是枚举处理这个View的内容
			EnumGroupViews(v1);
			
			//展示出来
			rootLayout.addView(v1);
			
			
		} catch (Exception e) {
			AppLog.e("addToUi excep",e);
		}
		
	}

	private void EnumGroupViews(View v1)
	{
		if(v1 instanceof ViewGroup)
		{
			
			ViewGroup lav = (ViewGroup)v1;
			int lcCnt = lav.getChildCount();
			for(int i = 0; i < lcCnt; i++)
			{
				View c1 = lav.getChildAt(i);
				if(c1 instanceof ViewGroup)
					EnumGroupViews(c1);//递归处理GroupView
				else if(c1 instanceof TextView)
				{
					//TestView则解析里面文本内容
					TextView txt = (TextView)c1;
					String str = txt.getText().toString().trim();
					if(str.length() > 0)
					{
						//这里打印文本内容
					}
					
					AppLog.i( "TextView id:"+ txt.getId() + ".text:" + str);
				}else
				{
					AppLog.w("2 other layout:" + c1.toString());
					
				}
			}
		}
		else {
			AppLog.w("1 other layout:" + v1.toString());
		}
	}

通过这个解析,我们基本上完成了从监控、抓取、解析内容的过程。网上也还有其它一些解析处理的方法,大家也可以参考,以上解析remoteView是本人

在查看其相应源码情况下自己琢磨出来的,而且测试了十几款有推送消息的应用,都可以正常解析其所有内容。



  • 5
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 33
    评论
Android 全局下拉 View 是一种在整个应用程序界面下拉展示特定信息的组件,并且在使用上模仿了手机的下拉通知。这个组件可以让用户在任何界面都可以通过下拉操作来快速查看通知和消息,并且可以自定义展示的内容和样式。 实现这样的全局下拉 View 需要借助 Android 的系统资源和自定义布局,首先要注册一个监听全局下拉动作的触摸事件,当用户在任何界面下拉时,监听器可以捕捉到这个动作,并决定是否展开下拉视图。接着,需要设计一个自定义的下拉通知布局,该布局可以包含通知图标、文字内容和点击事件等元素,并且可以根据实际需求对布局进行自定义样式和内容设置。 在展开下拉通知时,需要根据系统通知的样式和交互逻辑来设置展示内容,并且要确保在下拉通知消失后恢复原本的界面状态。另外,为了让全局下拉 View 能够在任何界面都能响应下拉事件,需要使用 WindowManager 添加这个 View 到整个应用程序窗口的顶层。 最后,为了使仿手机下拉通知的全局下拉 View 更加实用和友好,可以为其添加一些额外的功能,比如实现下拉通知的点击响应、清除通知、展示更多详细信息等。通过这样的相关设计和实现,用户在使用应用程序的过程中就可以方便地查看通知和消息,并且可以更加快速地进行响应和处理。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 33
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值