1. 程式人生 > >Notification呼吸燈設定流程淺析

Notification呼吸燈設定流程淺析

分析平臺Android4.4,

Android 系統架構中:一個manager類對應一個aidl介面,一個manager對應一個底層的服務,notification也是這個架構。

 1.一個普通apk呼叫notification實現呼吸燈燈效,主要是通過在Notification裡面設定效果引數傳入NotificationManagernotify方法 ,通過aidl介面轉換傳入NotificationManagerService

 需要設定如下程式碼:

1.1:獲取NotificationManager:

NotificationManager mNotificationManager=(NotificationManager)this.getSystemService(NOTIFICATION_SERVICE);

1.2:定義一個Notification:

  Notification  mNotification=new Notification();

1.3:設定Notification的各種屬性:

//設定通知在狀態列顯示的圖示

mNotification.icon=R.drawable.icon;          

//當我們點選通知時顯示的內容

mNotification.tickerText="Button1通知內容.....";                           

//通知時發出的預設聲音

mNotification.defaults=Notification.DEFAULT_SOUND;

Android支援三色燈提醒,可以根據不同的場景選擇點亮不同顏色的燈。需要注意的是,只有設定Notification的標誌位為FLAG_SHOW_LIGHTS,才能支援三色燈提醒。建立三色燈提醒的Notification示例如下:

mNotification.flags |= Notification.FLAG_SHOW_LIGHTS;

提醒標誌位(

Notification支援FLAG_SHOW_LIGHTSFLAG_ONGOING_EVENTFLAG_INSISTENTFLAG_ ONLY_ALERT_ONCEFLAG_AUTO_CANCELFLAG_NO_CLEAR

FLAG_FOREGROUND_SERVICE等多種提醒標誌位,其含義分別如下:

FLAG_SHOW_LIGHTS //三色燈提醒

FLAG_ONGOING_EVENT //發起事件

FLAG_INSISTENT //振鈴音將持續到Notification取消或Notification視窗開啟

FLAG_ONLY_ALERT_ONCE //發起Notification後,振鈴音或振動均只執行一次

FLAG_AUTO_CANCEL //使用者單擊後自動消失

FLAG_NO_CLEAR //只有全部清除時,Notification才會清除

FLAG_FOREGROUND_SERVICE //表示正執行的服務)

mNotification.ledARGB = 0xff0000f;//Led顏色

mNotification.ledOnMS = 300;//led亮的時間

mNotification.ledOffMS = 300;;//led滅的時間

//設定通知顯示的引數

PendingIntent m_PendingIntent=PendingIntent.getActivity(NotificationDemo.this, 0, m_Intent, 0);

mNotification.setLatestEventInfo(NotificationDemo.this, "Button1", "Button1通知",m_PendingIntent );

//開始執行這個通知

mNotificationManager.notify(0,mNotification);

將設定好的引數資訊打包到m_Notification中傳入NotificationManager繼續處理

2.在frameworks/base/core/java/android/app/NotificationManager.java中

   static public INotificationManager getService()

    {

        if (sService != null) {

            return sService;

        }

        IBinder b = ServiceManager.getService("notification");

        sService = INotificationManager.Stub.asInterface(b);

        return sService;

}



  public void notify(String tag, int id, Notification notification)

    {

        int[] idOut = new int[1];

        INotificationManager service = getService();

        String pkg = mContext.getPackageName();

        if (notification.sound != null) {

            notification.sound = notification.sound.getCanonicalUri();

            if (StrictMode.vmFileUriExposureEnabled()) {

                notification.sound.checkFileUriExposed("Notification.sound");

            }

        }

        if (localLOGV) Log.v(TAG, pkg + ": notify(" + id + ", " + notification + ")");

        Notification stripped = notification.clone();

        Builder.stripForDelivery(stripped);

        try {

            service.enqueueNotificationWithTag(pkg, mContext.getOpPackageName(), tag, id,

                   stripped, idOut, UserHandle.myUserId());

            if (id != idOut[0]) {

                Log.w(TAG, "notify: id corrupted: sent " + id + ", got back " + idOut[0]);

            }

        } catch (RemoteException e) {

        }

    }

通過aidl介面呼叫到  NotificationManagerService中的enqueueNotificationWithTag方法中,enqueue說明notification的內部維護著一個佇列,接收不同apk傳送的通知請求。

3.在frameworks/base/services/core/java/com/android/server/notification/NotificationManagerService.java中實現了燈效,亮滅時長燈的邏輯控制。

其中定義了MAX_PACKAGE_NOTIFICATIONS = 50,最大可以接收五十個通知

        @Override

        public void enqueueNotificationWithTag(String pkg, String opPkg, String tag, int id,

                Notification notification, int[] idOut, int userId) throws RemoteException {

            enqueueNotificationInternal(pkg, opPkg, Binder.getCallingUid(),

                    Binder.getCallingPid(), tag, id,notification, idOut, userId);

        }

  void enqueueNotificationInternal(final String pkg, final String opPkg, final int callingUid,

            final int callingPid, final String tag, final int id, final Notificationnotification,

            int[] idOut, int incomingUserId) {……….

…………………………..

………………….

}在這裡對mNotificationList通知訊息佇列各條通知的優先順序,聲音進行了相關操作

最後進入updateLightsLocked在其中將設定好的燈效顏色,型別,時間長短寫入LightsService

      mNotificationLight.setFlashing(ledARGB, LightsService.LIGHT_FLASH_TIMED,

                        ledOnMS, ledOffMS);

4.在frameworks/base/services/core/java/com/android/server/lights/LightsService.java中setFlashing方法裡面setLightLocked來實現等效。

所有對燈效的操作都是通過setLightLocked實現。如下

        private void setLightLocked(int color, int mode, int onMS, int offMS, int brightnessMode) {

            if (color != mColor || mode != mMode || onMS != mOnMS || offMS != mOffMS) {

                if (DEBUG) Slog.v(TAG, "setLight #" + mId + ": color=#"

                        + Integer.toHexString(color));

                mColor = color;

                mMode = mode;

                mOnMS = onMS;

                mOffMS = offMS;

                Trace.traceBegin(Trace.TRACE_TAG_POWER, "setLight(" + mId + ", " + color + ")");

                try {

                    setLight_native(mNativePointer, mId, color, mode, onMS, offMS, brightnessMode);

                } finally {

                    Trace.traceEnd(Trace.TRACE_TAG_POWER);

                }

            }

        }



        private int mId;

        private int mColor;

        private int mMode;

        private int mOnMS;

        private int mOffMS;

        private boolean mFlashing;

    }

setLight_native最終呼叫了一個native方法,到JNI層去了。

在frameworks/base/services/core/jni/com_android_server_lights_LightsService.cpp中還是將LED燈顏色,模式,時間寫入state中向下繼續傳遞

static void setLight_native(JNIEnv *env, jobject clazz, jlong ptr,

        jint light, jint colorARGB, jint flashMode, jint onMS, jint offMS, jint brightnessMode)

{

    Devices* devices = (Devices*)ptr;

    light_state_t state;

    if (light < 0 || light >= LIGHT_COUNT || devices->lights[light] == NULL) {

        return ;

    }

    memset(&state, 0, sizeof(light_state_t));

    state.color = colorARGB;

    state.flashMode = flashMode;

    state.flashOnMS = onMS;

    state.flashOffMS = offMS;

    state.brightnessMode = brightnessMode;

    {

        ALOGD_IF_SLOW(50, "Excessive delay setting light");

        devices->lights[light]->set_light(devices->lights[light], &state);

    }

}

最後通過hardwareinterface控制led燈顏色節點實現燈效的具體效果!

相關推薦

Notification呼吸設定流程淺析

分析平臺Android4.4, Android 系統架構中:一個manager類對應一個aidl介面,一個manager對應一個底層的服務,notification也是這個架構。  1.一個普通apk呼叫notification實現呼吸燈燈效,主要是通過在Notifica

Android 呼吸流程分析(一)

一、Android 呼吸燈的使用      在講呼吸燈實現流程之前,我們先看一下如何使用它。      Android提供了呼吸燈的介面,我們可以通過該介面,控制呼吸燈的閃爍頻率和佔空比。具體程式碼如下: package com.example.test; import

Android Notification關閉呼吸、震動和聲音

1. 前言 最近需要實現一個不會開啟呼吸燈、不會震動和沒聲音的通知,查找了很多資料,但沒有一個寫得完整的。東湊湊,西湊湊,自己摸索了幾個小時,找到了一種較可靠的方式。 2. 解決方案 這種方案相容

Android 呼吸流程分析(二)

一、Android呼吸燈Driver實現       1、註冊驅動       程式碼位置:mediatek/kernel/drivers/leds/leds_drv.c 602static struct platform_driver mt65xx_leds_drive

YII數據流程淺析

art model 原生 ews .net area 一個 控制器 href MVC就不解釋,直接上代碼分析數據流程: 數據庫圖: 模型部分介紹: <?php /* * 前兩個方法必須寫 * 繼承自CAct

自定義View的三大流程淺析

目錄   1.自定義View簡介 2.MeasureSpec 1) SpecMode 3.View的工作流程 1) View的measure過程 2)ViewGroup的measure過程 3)layout流程 4)draw流程 1.自定義Vie

Launcher3 Workspace載入流程淺析(基於Aosp P版本)

launcher3 Workspace載入流程淺析 前言 Aosp launcher3原始碼隨著Android大版本的迭代,也在不斷的更新,大體功能變化不大,但卻在不斷的重構和優化程式碼,程式碼的封裝和擴充套件性變得越來越好,作為launcher開發者,也要緊跟步伐去學習,把好的實現

呼吸輪播圖

<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, ini

LED呼吸控制

該方法前提是三方應用必須打入系統應用,並且在應用程式的AndroidManifest.xml中的manifest節點中加入android:sharedUserId="android.uid.system"這個屬性。 static String RED_LED_DEV = "/sys/cl

PWM呼吸

##單個定時器 #include <reg52.h> #include <intrins.h> unsigned char PWM_COUNT; //計數 unsigned int HUXI_COUNT; //佔空比更新時間 unsigned cha

微控制器呼吸程式

呼吸燈 ORG 0000H START: MOV R0,#01H MOV R1,#00H MOV R2,#00H MOV R3,#0FFH LOOP: MOV P1,R2 MOV A,R0 LOOP1: MOV R4,#10 DJN

android關機充電呼吸不亮

最近在適配新機型的過程中遇到一個問題,關機後充電呼吸燈不亮. 剛開始遇到這個問題時,一時束手無策,因為對這關機充電的流程根本不清楚.最後查閱資料和同事交流後發現關鍵充電的程式碼在/system/core/healthd目錄下. 知道程式碼在哪裡後首先來看看main函式(healthd.cpp

基於PWM的呼吸設計(Verilog版)

module Breath_Led(clk,rst,led); input clk,rst; output reg led; reg[19:0] count; reg[19:0] duty_cycle; always @(posedge clk) begin if(!rst) begin

【FAQ資料】MT6328平臺ISINK呼吸模式配置方法

MT6328平臺FAQ資料介紹: 描述: MT6328平臺ISINK呼吸燈模式配置方法 答: MT6328 ISINK 支援呼吸燈模式的話 需要修改檔案alps\kernel-3.10\drivers\misc\mediatek\leds\mt6735\leds.c

FPGA verilog HDL 呼吸呼吸流水實現

專案一:FPGA的呼吸燈實現           專案介紹:呼吸燈,就是想人們呼吸頻率的一種led燈亮滅的一種表現形式。過程是慢慢變亮,然後變亮以後又慢慢變滅的一種過程。很多初學者會認為硬體邏輯語言怎麼能控制電流的高低呢,讓燈有多亮就調多亮,所以覺得不好實現,其實不用擔心,

MyBatis和Spring整合,流程淺析 - 20181208

【面試題】我們在開發mybaits時候,有幾種寫sql語句的方式? 一種是註解、一種是xml檔案、還有一種是@Provider 註解形式:簡單但是不是很靈活,對於動態條件查詢是無法實現的,這時,我們可以使用xml的方式。 xml形式:有xml檔案,且約束嚴格。 @Provider:

玩轉Windows服務系列——服務執行、停止流程淺析

通過研究Windows服務註冊解除安裝的原理,感覺它並沒有什麼特別複雜的東西,Windows服務正在一步步退去它那神祕的面紗,至於是不是美女,大家可要睜大眼睛看清楚了。 接下來研究一下Windows服務的啟動和停止的流程。 啟動流程 啟動時自然是從程式的入口點開始 extern "C" int W

Android6.0 Reset恢復出廠設定流程分析

點選Settings應用中的恢復出廠設定按鈕後流程分析:先使用grep命令搜尋"恢復出廠設定"字串,找到相應的佈局檔案: packages/apps/Settings/res/xml/privacy_settings.xml <PreferenceScree

宇視4G裝置採用GB/T28181協議成功接入EasyGBS國標流媒體平臺的設定流程

經過了多天的除錯對接,終於將宇視的布控球順利接入到了EasyGBS的國標平臺,特地寫一下對接過程中遇到的問題,希望能幫助大家避開一些麻煩: 第一步:電腦連線無線網路IPCWIFI,密碼12345678 第二步:瀏覽器中登入地址:192.168.2.1; 如果找不到裝

Android EventBus事件釋出流程淺析

       如上圖所示,簡而言之,EventBus是一個用於Android/Java的釋出/訂閱事件匯流排,可以簡化元件間的資料傳輸。它的優勢在於解耦事件傳送者和接受者,在Activities、Fragments以及後臺執行緒和主執行緒間的資料傳輸方面表現不錯,避免