Skip to main content
 首页 » 编程设计

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

2022年07月19日25qlqwjy

一、通知灯系统学习

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); 
    } 
}

本文参考链接:https://www.cnblogs.com/hellokitty2/p/10819962.html