Android Notification實(shí)現(xiàn)動(dòng)態(tài)顯示通話時(shí)間
基于android N MTK釋放的源碼,供大家參考,具體內(nèi)容如下
本文主要講解如何在 IncallUI 的notification 上面不停地更新顯示當(dāng)前已通話多長(zhǎng)時(shí)間,從而達(dá)到和incallUI通話界面上的通話時(shí)間一致。
主要思路
1、我們需要知道通話建立時(shí)的時(shí)間,即call 的狀態(tài)從 INCOMING或者DIALING 轉(zhuǎn)變成ACTIVE的時(shí)候
2、時(shí)間每秒鐘都會(huì)發(fā)生變化,所以我們就需要不停的更新notification的界面,我們這里是不停的創(chuàng)建和notify同一個(gè)notification,已到達(dá)更新時(shí)間的效果
3、我們需要CallTimer線程不停的幫我們計(jì)算時(shí)間,并控制界面的更新
代碼實(shí)現(xiàn)
這里是在源碼incallUI目錄下的StatusBarNotifier.java中修改
....省略部分代碼 //震動(dòng)時(shí)長(zhǎng),這里為不振動(dòng) private static final long[] IN_CALL_VIBRATE_PATTERN_NULL = new long[] {0, 0, 0}; //線程隔多久執(zhí)行一次已ms為單位,這里為1S private static final long CALL_TIME_UPDATE_INTERVAL_MS = 1000; //我們需要獲取一些全局的變量,已到達(dá)不停的創(chuàng)建notification并更新同一個(gè)notification的UI private CallTimer mCallTimer; private Notification.Builder mCopyBuilder; private int mCopyCallState; private ContactCacheEntry mCopyContactInfo; private int mCopyNotificationType; //當(dāng)前notification的ID,通過(guò)這個(gè)ID我們可以一直更新同一個(gè)notification并且只會(huì)彈出一次 private Bitmap mCopyLargeIcon; public StatusBarNotifier(Context context, ContactInfoCache contactInfoCache) { .......省略部分代碼 //StatusBarNotifier初始化的時(shí)候就創(chuàng)建CallTimer對(duì)象,用來(lái)計(jì)算時(shí)間和更新UI mCallTimer = new CallTimer(new Runnable() { @Override public void run() { updateCallTime(); //更新UI的函數(shù) } }); } @Override public void onStateChange(InCallState oldState, InCallState newState, CallList callList) { if (callList.getActiveCall() == null || callList.getActiveCall().getState() != Call.State.ACTIVE){ //當(dāng)通話結(jié)束時(shí)需要取消計(jì)算時(shí)間的線程 mCallTimer.cancel(); } } //系統(tǒng)構(gòu)建notification的方法 private void buildAndSendNotification(Call originalCall, ContactCacheEntry contactInfo) { ....省略部分代碼 else if (callState == Call.State.ACTIVE && !mIsCallUiShown) { //保存一個(gè)公共的變量到全部變量里面,方便后面構(gòu)造新的notification并刷新 copyInfoFromHeadsUpView(builder, callState, contactInfo, notificationType, largeIcon); //下面是計(jì)算顯示的時(shí)間 final long callStart = call.getConnectTimeMillis(); final long duration = System.currentTimeMillis() - callStart; //創(chuàng)建一個(gè)HeadsUpView顯示在notification上面 RemoteViews inCall = createInCallHeadsUpView(duration / 1000, largeIcon); builder.setContent(inCall); builder.setCustomHeadsUpContentView(inCall); //系統(tǒng)原生的方法最后notify通知 fireNotification(builder, callState, contactInfo, notificationType); //開(kāi)始我們的計(jì)時(shí)線程 mCallTimer.start(CALL_TIME_UPDATE_INTERVAL_MS); } .....省略部分代碼 } private RemoteViews createInCallHeadsUpView(Long callDuration, Bitmap contactAvatar) { RemoteViews headsUpView = new RemoteViews(mContext.getPackageName(), R.layout.in_call_headsup); if (null != contactAvatar) { headsUpView.setImageViewBitmap(R.id.in_call_hu_avatar, contactAvatar); } //格式化時(shí)間 String callTimeElapsed = DateUtils.formatElapsedTime(callDuration); headsUpView.setTextViewText(R.id.in_call_hu_elapsedTime, callTimeElapsed); return headsUpView; } /*according the mCallTimer to update time data*/ public void updateCallTime() { Call call = CallList.getInstance().getActiveCall(); final long callStart = call.getConnectTimeMillis(); final long duration = System.currentTimeMillis() - callStart; RemoteViews inCall = createInCallHeadsUpView(duration / 1000, mCopyLargeIcon); mCopyBuilder.setContent(inCall); mCopyBuilder.setCustomHeadsUpContentView(inCall); Notification notification = mCopyBuilder.build(); notification.vibrate = IN_CALL_VIBRATE_PATTERN_NULL; mNotificationManager.notify(mCopyNotificationType, notification); } /*Change local variables to global variables*/ private void copyInfoFromHeadsUpView(Notification.Builder builder, int callState, ContactCacheEntry contactInfo, int notificationType, Bitmap largeIcon){ mCopyBuilder = builder; mCopyCallState = callState; mCopyContactInfo = contactInfo; mCopyNotificationType = notificationType; mCopyLargeIcon = largeIcon; } ........省略部分代碼
CallTimer源碼如下
package com.android.incallui; import com.google.common.base.Preconditions; import android.os.Handler; import android.os.SystemClock; /** * Helper class used to keep track of events requiring regular intervals. */ public class CallTimer extends Handler { private Runnable mInternalCallback; private Runnable mCallback; private long mLastReportedTime; private long mInterval; private boolean mRunning; public CallTimer(Runnable callback) { Preconditions.checkNotNull(callback); mInterval = 0; mLastReportedTime = 0; mRunning = false; mCallback = callback; mInternalCallback = new CallTimerCallback(); } public boolean start(long interval) { if (interval <= 0) { return false; } // cancel any previous timer cancel(); mInterval = interval; mLastReportedTime = SystemClock.uptimeMillis(); mRunning = true; periodicUpdateTimer(); return true; } public void cancel() { removeCallbacks(mInternalCallback); mRunning = false; } private void periodicUpdateTimer() { if (!mRunning) { return; } final long now = SystemClock.uptimeMillis(); long nextReport = mLastReportedTime + mInterval; while (now >= nextReport) { nextReport += mInterval; } postAtTime(mInternalCallback, nextReport); mLastReportedTime = nextReport; // Run the callback mCallback.run(); } private class CallTimerCallback implements Runnable { @Override public void run() { periodicUpdateTimer(); } } }
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
Android React Native原生模塊與JS模塊通信的方法總結(jié)
這篇文章主要介紹了Android React Native原生模塊與JS模塊通信的方法總結(jié)的相關(guān)資料,需要的朋友可以參考下2017-02-02Android DrawerLayout實(shí)現(xiàn)抽屜效果實(shí)例代碼
這篇文章主要介紹了Android DrawerLayout實(shí)現(xiàn)抽屜效果的實(shí)例代碼,非常不錯(cuò),具有參考借鑒價(jià)值,需要的朋友可以參考下2016-12-12EditText限制小數(shù)點(diǎn)前后位數(shù)的實(shí)例
下面小編就為大家?guī)?lái)一篇EditText限制小數(shù)點(diǎn)前后位數(shù)的實(shí)例。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2017-04-04Android 模仿iPhone列表數(shù)據(jù)View刷新動(dòng)畫(huà)詳解
本文主要介紹Android 模仿iPhone列表數(shù)據(jù)view 刷新動(dòng)畫(huà)的資料,這里整理詳細(xì)的資料,并附示例代碼及實(shí)現(xiàn)效果圖,有興趣的小伙伴可以參考下2016-09-09Android studio 解決logcat無(wú)過(guò)濾工具欄的操作
這篇文章主要介紹了Android studio 解決logcat無(wú)過(guò)濾工具欄的操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2020-04-04Android DatePicker和DatePickerDialog基本用法示例
這篇文章主要介紹了Android DatePicker和DatePickerDialog基本用法,實(shí)例分析了DatePicker和DatePickerDialog控件針對(duì)手機(jī)時(shí)間設(shè)置的相關(guān)技巧,需要的朋友可以參考下2016-06-06Android入門(mén)之AlertDialog用法實(shí)例分析
這篇文章主要介紹了Android入門(mén)之AlertDialog用法,對(duì)Android初學(xué)者有很多的借鑒學(xué)習(xí)之處,需要的朋友可以參考下2014-08-08