Delphi 监听安卓(Android)手机通知栏信息

来源:互联网 发布:淘宝汽车超人假机油 编辑:程序博客网 时间:2024/05/21 13:56

Delphi 监听安卓(Android)手机通知栏信息

因为一些业务需要,我们有时候需要知道手机通知栏显示的信息,然后根据这些信息去处理一些相应的业务逻辑。如:自动监听收到的短信验证码,提取后自动填写到我们APP的验证码输入项中,减少使用者查看短信再记忆、再输入验证的过程,提升用户使用体验。除了短信,其他通知栏显示的信息我们可能也会有着其他较为实用的需要。

在使用这项功能前,我们需要了解一些基本知识。

安全问题

因为监听通知栏信息涉及到较为隐私的信息,出于安全考虑,Android并没有提供自动权限设置的功能,也就是只能通过机主以手工去确认是否允许该APP监听通知栏信息。通常多数手机也不能通过“设置”或其他菜单连接的方式找到并打开,他需要在APP中以代码方式打开并设置。
通知栏监听的权限设置
通常设置类似上图,手机不同会有细微差别。

主要开发过程

本文简单记录开发过程。
首先需要实现并注册NotificationListenerService服务。用于监听通知栏信息,其次需要实现对权限的判断与管理,最后是完成服务监听到信息的处理。

NotificationListenerService服务

我在实现过程中尝试过使用delphi来处理,目前暂时没有成功,只好使用JAVA完成服务功能的部分代码,然后通过服务将监听到的数据发送给delphi程序做后续处理。
需要用JAVA实现onNotificationPosted及onNotificationRemoved方法。并通过工具生成JNI单元文件,以便在delphi中可以使用。主要包括:

  [JavaSignature('com/tanqin/nlsapp/NLService')]  JNLService = interface(JNotificationListenerService)  //or JObject // SuperSignature: android/service/notification/NotificationListenerService    ['{F7F3FEFD-FA30-4A7A-97D5-70643997C7F3}']    procedure onNotificationPosted(sbn: JStatusBarNotification); cdecl;    //(Landroid/service/notification/StatusBarNotification;)V    procedure onNotificationRemoved(sbn: JStatusBarNotification); cdecl;    //(Landroid/service/notification/StatusBarNotification;)V  end;  TJNLService = class(TJavaGenericImport<JNLServiceClass,JNLService>)  end;  JLocalBroadcastManagerClass = interface(JObjectClass)    ['{3013CC6D-4E7D-44D9-9F61-E849944E1091}']    {class} function getInstance(P1: JContext): JLocalBroadcastManager; cdecl;    //(Landroid/content/Context;)Landroid/support/v4/content/LocalBroadcastManager;  end;

服务注册

需要在“AndroidManifest.template.xml”文件中增加如下定义,其中android:name=”com.tanqin.nlsapp.NLService”行,指定了监听服务类名称,label用于显示监听服务名字,以便于识别。

        <service android:name="com.tanqin.nlsapp.NLService"             android:label="通知监听"            android:permission="android.permission.BIND_NOTIFICATION_LISTENER_SERVICE">            <intent-filter>                <action android:name="android.service.notification.NotificationListenerService" />            </intent-filter>        </service>   

初始化服务主要代码

  //初始化服务  Fser := TJNLService.JavaClass.init;  FNLS := TJIntent.JavaClass.init(SharedActivityContext,Fser.getClass);  FNLS.setAction(StringToJString    ('android.service.notification.NotificationListenerService'));

判断监听是否授权

只有被授权的APP才能监听通知栏信息。

  //判断通知监听是否被受权  //通知的监听必须有特定的受权,没有这个受权,不能接收通知  //该受权还必须是人工点击确认,这点非常重要  CheckBox1.IsChecked := AnsiContainsText    (JStringToString(TJSettings_Secure.JavaClass.getString    (SharedActivityContext.getContentResolver,    StringToJString('enabled_notification_listeners'))),'com.tanqin.nlsapp');

调用通知监听授权

以下代码及过调用通知监听授权功能,显示内容如上面第一张截图。

var  ji: JIntent;begin  //打开授权管理  //通知的监听必须有特定的授权没有这个授权,不能接收通知  //该授权还必须是人工点击确认,这点非常重要  //这里是启动手动受权确认功能  ji := TJIntent.JavaClass.init    (StringToJString('android.settings.ACTION_NOTIFICATION_LISTENER_SETTINGS'));  SharedActivityContext.startActivity(ji);end;

启动监听服务

启动监听服务前,先判断是否授权,如果没有授权则调用授权功能。

var  vENL: Boolean;begin  //开户服务前判断通知监听是否被受权  vENL := AnsiContainsText(JStringToString(TJSettings_Secure.JavaClass.getString    (SharedActivityContext.getContentResolver,    StringToJString('enabled_notification_listeners'))),'com.tanqin.nlsapp');  CheckBox1.IsChecked := vENL;  if vENL then  begin    //打开通知监听服务    SharedActivityContext.startService(FNLS);    CheckBox2.IsChecked := True;  end  else  begin    //转受权处理   {无受权,不能使用}  end;end;

APP完成后的演示

该APP演示了通过监听获取通知栏通知信息的程序包名(用于识别通知发送者)、通知标题、通知内容、通知时间、提交或清除事件。

下图是已经连续运行四天的监听截图。
已连续运行4天的监听程序

后续

该APP通过调整,可指定监听某些特定通知内容。

欢迎大家光临本人小店 :https://shop63778938.taobao.com/