Android灯光系统(5)——通知灯分析实验

一、通知灯系统学习

1.运行init进程创建SystemServer

2.启动LightsService
startCoreServices()  //SystemServer.java
    mSystemServiceManager.startService(LightsService.class);

3.创建NotificationManagerService获得通知灯
startOtherServices() //SystemServer.java
    mSystemServiceManager.startService(NotificationManagerService.class);
        NotificationManagerService() //构造函数
        NotificationManagerService.onStart() //服务的入口函数
            LightsManager lights = getLocalService(LightsManager.class);
            mNotificationLight = lights.getLight(LightsManager.LIGHT_ID_NOTIFICATIONS);
            publishBinderService(Context.NOTIFICATION_SERVICE, mService);
            publishLocalService(NotificationManagerInternal.class, mInternalService);

二、App对通知灯的使用

1.每个APP都有一个 ContextImpl 上下文对象,ContextImpl中的静态代码块注册了一些系统服务

ContextImpl.java: 
static {
    /*
     * 每个类都有这些Service, 也就是说每个类在加载进内存后就有这些service存在了,
     * 就是将一些Service放到HashMap中。
     * getSystemService就是从HashMap中获取Service。
     */
    registerService(NOTIFICATION_SERVICE, new ServiceFetcher() 
        public Object createService(ContextImpl ctx) 
            final Context outerContext = ctx.getOuterContext();
            /*NotificationManager 匿名类*/
            return new NotificationManager(
                new ContextThemeWrapper(outerContext,
                    Resources.selectSystemTheme(0,
                            outerContext.getApplicationInfo().targetSdkVersion,
                            com.android.internal.R.style.Theme_Dialog,
                            com.android.internal.R.style.Theme_Holo_Dialog,
                            com.android.internal.R.style.Theme_DeviceDefault_Dialog,
                            com.android.internal.R.style.Theme_DeviceDefault_Light_Dialog)),
                ctx.mMainThread.getHandler());
        );
};

3.App使用notification的流程

/*1.获得系统服务NOTIFICATION_SERVICE*/
NotificationManager nm = ( NotificationManager ) getSystemService(NOTIFICATION_SERVICE);

/*2.构造Notification*/ 
Notification notif = new Notification();
notif.ledARGB = 0xFFff0000;
notif.flags = Notification.FLAG_SHOW_LIGHTS;
notif.ledOnMS = 100;
notif.ledOffMS = 100; 

/*3.发出通知*/
nm.notify(LED_NOTIFICATION_ID, notif);

内部调用流程如下:
notify()  //NotificationManager.java
    INotificationManager service = getService();
    service.enqueueNotificationWithTag(...);

getService() //NotificationManager.java
    IBinder b = ServiceManager.getService("notification");
    sService = INotificationManager.Stub.asInterface(b);
    return sService;

enqueueNotificationWithTag() //NotificationManagerService.java
    enqueueNotificationInternal(...);
        buzzBeepBlinkLocked(r);

buzzBeepBlinkLocked()  //NotificationManagerService.java
if ((notification.flags & Notification.FLAG_SHOW_LIGHTS) != 0 && canInterrupt) 
  ...
 updateLightsLocked();
  ...

updateLightsLocked() //NotificationManagerService.java
    mNotificationLight.turnOff();
    mNotificationLight.setFlashing(...);


LightsService.java: setLightLocked()
setLight_native(mNativePointer, mId, color, mode, onMS, offMS, brightnessMode);

com_android_server_lights_LightsService.cpp: setLight_native()
devices->lights[light]->set_light(devices->lights[light], &state);

lights.c: set_light_notifications()

三、笔记

1.可只import一个类的静态成员
import static android.service.notification.NotificationListenerService.HINT_HOST_DISABLE_EFFECTS;


四、App示例Demo

package com.app_0002_lightdemo;

import android.os.Handler;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.Button;
import android.app.NotificationManager;
import android.app.Notification;
import android.view.View;

public class MainActivity extends AppCompatActivity {

    private Button mLightButton = null;
    boolean flashing = false;
    final private int LED_NOTIFICATION_ID = 123;

    private Handler mLightHander = new Handler();
    private LightRunnable mLightRunnable = new LightRunnable();

    class LightRunnable implements Runnable {
        @Override
        public void run() {
            if (flashing) {
                FlashingLight();
            } else {
                ClearLED();
            }
        }
    }

    private void FlashingLight()
    {
        /*ContextImpl.java中为每个类都注册了这个服务*/
        NotificationManager nm = ( NotificationManager ) getSystemService( NOTIFICATION_SERVICE );
        Notification notif = new Notification();
        notif.flags = Notification.FLAG_SHOW_LIGHTS;
        notif.ledARGB = 0xFF0000ff;
        notif.ledOnMS = 100;
        notif.ledOffMS = 100;
        /*这个id应该是自己随便定义的,在cancel()中也要用到它*/
        nm.notify(LED_NOTIFICATION_ID, notif);
    }

    private void ClearLED()
    {
        NotificationManager nm = ( NotificationManager ) getSystemService( NOTIFICATION_SERVICE );
        nm.cancel(LED_NOTIFICATION_ID);
    }
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        mLightButton = (Button)findViewById(R.id.button);
        mLightButton.setOnClickListener(new View.OnClickListener() {
            public void onClick(View v) {
                // Perform action on click
                flashing = !flashing;
                if (flashing){
                    mLightButton.setText("Stop Flashing the Light");
                }else {
                    mLightButton.setText("Flashing Light at 20S");
                }
                /*
                 * 设置LCD屏幕为15s后休眠,因为在屏幕亮着的时候是不会进行通知的.
                 * 这里使用消息通知仅仅是为了延期执行了而已。
                 */
                mLightHander.postDelayed(mLightRunnable, 20000);
            }
        });

    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.menu_main, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        // Handle action bar item clicks here. The action bar will
        // automatically handle clicks on the Home/Up button, so long
        // as you specify a parent activity in AndroidManifest.xml.
        int id = item.getItemId();

        //noinspection SimplifiableIfStatement
        if (id == R.id.action_settings) {
            return true;
        }

        return super.onOptionsItemSelected(item);
    }
}
View Code
原文地址:https://www.cnblogs.com/hellokitty2/p/10819962.html