android 通知 灯光,第四章:Android灯光系统(5)-通知灯

上小节我们分析了电池灯的源码,这小节我们将编写通知灯的使用过程。

我们知道,当手机接收到短信的时候,他会发出声音,并且这个通知灯会亮起,那么我们怎么实现呢?一般步骤如下:

1. getSystemService("NOTIFICATION_SERVICE")

2. 构造notfification

(1)类别:该次实现类别为通知等

(2)其他:颜色,OnMS,OffMS。

3. 发出通知

以上是我们自己编写APP的步骤,那么系统一般会会什么呢?如下:

1. 启动通知Service

2. 收到通知之后:

(1)分辨通知类型

(2)执行相应操作

3. 对于通知灯:

(1)获取lightService

(2) 执行执行灯光操作

下面我们先分析一下系统中的源码

源码分析

我们打开源码中lights.h文件,可以看到如下:

#define LIGHT_ID_BACKLIGHT "backlight"

#define LIGHT_ID_KEYBOARD "keyboard"

#define LIGHT_ID_BUTTONS "buttons"

#define LIGHT_ID_BATTERY "battery"

#define LIGHT_ID_NOTIFICATIONS "notifications"

#define LIGHT_ID_ATTENTION "attention"

#define LIGHT_ID_BLUETOOTH "bluetooth"

#define LIGHT_ID_WIFI "wifi"

然后在源码中搜索LIGHT_ID_NOTIFICATIONS(通知灯),然后找到文件NotificationManagerService.java:

mNotificationLight = lights.getLight(LightsManager.LIGHT_ID_NOTIFICATIONS);

和电池灯类似,获得一个对应的Light类型对象,之后所有对通知灯的操作,都是通过mNotificationLight实现,我们还能再改文件中找到一个updateLightsLocked()方法,名字和电池灯中的是一样的,当然内容是不一样的,但是对于通知灯的所有操作都是通过updateLightsLocked()方法实现的,现在我们想知道updateLightsLocked()的调用过程,直接从updateLightsLocked着手是比较困难的。前面提到过,我们编写APP程序时会调用getSystemService(“NOTIFICATION_SERVICE”),那么我们在源码中搜索一下NOTIFICATION_SERVICE,既然有get那么肯定存在类似set的方法,最终我们锁定文件SystemServiceRegistry.java,调用了

registerService(Context.NOTIFICATION_SERVICE, NotificationManager.class,

new CachedServiceFetcher()

在使用getSystemService(“NOTIFICATION_SERVICE”),我们获得的是一个NotificationManager实例化的对象。

既然我们获得了NotificationManager的实例化对象,那么我们应该怎么使用呢?我们打开NotificationManager.java文件,

我们找到notify方法,可知最终调用notifyAsUse方法:

service = getService()

service.enqueueNotificationWithTag()

其中getService的实现在toast.java问价中如下

static private INotificationManager getService() {

if (sService != null) {

return sService;

}

sService = INotificationManager.Stub.asInterface(ServiceManager.getService("notification"));

return sService;

}

那么系统中肯定有其他的地方注册了"notification",我们之前提到过SystemServer.java会注册很多的注册方法,我们在其中搜索notification,可以找到

mSystemServiceManager.startService(NotificationManagerService.class);

我们查看NotificationManagerService.java文件,当这个类被创建的时候,其中onStart()方法会被调用,该方法最后会调用publishBinderService(Context.NOTIFICATION_SERVICE, mService)

protected final void publishBinderService(String name, IBinder service,

boolean allowIsolated) {

ServiceManager.addService(name, service, allowIsolated);

}

根据其传入的参数NOTIFICATION_SERVICE = "notification"进行注册。注册之后我们就可以使用service = getService(),service.enqueueNotificationWithTag(),现在我们回过头来看看enqueueNotificationWithTag()方法:

enqueueNotificationWithTag()

enqueueNotificationInternal()

mHandler.post(new EnqueueNotificationRunnable(userId, r));

EnqueueNotificationRunnable()

run()

buzzBeepBlinkLocked(r);

最后调用了方法buzzBeepBlinkLocked(),这个方法通过参数r分辨通知是震动,还是声音,或者闪光。在该方法内我们可以找到:

if ((notification.flags & Notification.FLAG_SHOW_LIGHTS) != 0 && aboveThreshold

&& ((record.getSuppressedVisualEffects()

& NotificationListenerService.SUPPRESSED_EFFECT_SCREEN_OFF) == 0)) {

mLights.add(key);

updateLightsLocked();

if (mUseAttentionLight) {

mAttentionLight.pulse();

}

blink = true;

}

判断通知是否为闪灯,如果为闪灯,则调用 updateLightsLocked(),这样我们分析的就和之前的连系到一起了。

APP编写

在updateLightsLocked()中我们可以看到:

// Don't flash while we are in a call or screen is on

if (ledNotification == null || mInCall || mScreenOn)

可以知道,当屏幕点亮或者在打电话的时候,我们是没有办法使用通知灯的。只能在黑屏的情况下,我们的通知灯才会起到效果。所以我们在编写APP的时候,需要做以下操作:

1. 设置LCD如果在15秒内没有操作,则进入黑屏状态。

2. 然后我们点击butter按钮,20秒后发送通知。

现在我们编写一个APP程序,

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值