• 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
  • 相关阅读:
    POJ2376 Cleaning Shifts
    百度首页图标
    NOIP2016换教室
    CH3803扑克牌
    【POJ2723】Get Luffy Out
    【USACO13DEC】 最优挤奶
    【SP2916】Can you answer these queries V
    【线段树】各种模板集合
    【SCOI2013】摩托车交易
    【CF1174D】 Ehab and the Expected XOR Problem
  • 原文地址:https://www.cnblogs.com/hellokitty2/p/10819962.html
Copyright © 2020-2023  润新知