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-02
Android DrawerLayout實(shí)現(xiàn)抽屜效果實(shí)例代碼
這篇文章主要介紹了Android DrawerLayout實(shí)現(xiàn)抽屜效果的實(shí)例代碼,非常不錯(cuò),具有參考借鑒價(jià)值,需要的朋友可以參考下2016-12-12
EditText限制小數(shù)點(diǎn)前后位數(shù)的實(shí)例
下面小編就為大家?guī)?lái)一篇EditText限制小數(shù)點(diǎn)前后位數(shù)的實(shí)例。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2017-04-04
Android 模仿iPhone列表數(shù)據(jù)View刷新動(dòng)畫(huà)詳解
本文主要介紹Android 模仿iPhone列表數(shù)據(jù)view 刷新動(dòng)畫(huà)的資料,這里整理詳細(xì)的資料,并附示例代碼及實(shí)現(xiàn)效果圖,有興趣的小伙伴可以參考下2016-09-09
Android studio 解決logcat無(wú)過(guò)濾工具欄的操作
這篇文章主要介紹了Android studio 解決logcat無(wú)過(guò)濾工具欄的操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2020-04-04
Android DatePicker和DatePickerDialog基本用法示例
這篇文章主要介紹了Android DatePicker和DatePickerDialog基本用法,實(shí)例分析了DatePicker和DatePickerDialog控件針對(duì)手機(jī)時(shí)間設(shè)置的相關(guān)技巧,需要的朋友可以參考下2016-06-06
Android入門(mén)之AlertDialog用法實(shí)例分析
這篇文章主要介紹了Android入門(mén)之AlertDialog用法,對(duì)Android初學(xué)者有很多的借鑒學(xué)習(xí)之處,需要的朋友可以參考下2014-08-08

