Android Notification实现动态显示通话时间
短信预约 -IT技能 免费直播动态提醒
基于android N MTK释放的源码,供大家参考,具体内容如下
本文主要讲解如何在 IncallUI 的notification 上面不停地更新显示当前已通话多长时间,从而达到和incallUI通话界面上的通话时间一致。
主要思路
1、我们需要知道通话建立时的时间,即call 的状态从 INCOMING或者DIALING 转变成ACTIVE的时候
2、时间每秒钟都会发生变化,所以我们就需要不停的更新notification的界面,我们这里是不停的创建和notify同一个notification,已到达更新时间的效果
3、我们需要CallTimer线程不停的帮我们计算时间,并控制界面的更新
代码实现
这里是在源码incallUI目录下的StatusBarNotifier.java中修改
....省略部分代码
//震动时长,这里为不振动
private static final long[] IN_CALL_VIBRATE_PATTERN_NULL = new long[] {0, 0, 0};
//线程隔多久执行一次已ms为单位,这里为1S
private static final long CALL_TIME_UPDATE_INTERVAL_MS = 1000;
//我们需要获取一些全局的变量,已到达不停的创建notification并更新同一个notification的UI
private CallTimer mCallTimer;
private Notification.Builder mCopyBuilder;
private int mCopyCallState;
private ContactCacheEntry mCopyContactInfo;
private int mCopyNotificationType; //当前notification的ID,通过这个ID我们可以一直更新同一个notification并且只会弹出一次
private Bitmap mCopyLargeIcon;
public StatusBarNotifier(Context context, ContactInfoCache contactInfoCache) {
.......省略部分代码
//StatusBarNotifier初始化的时候就创建CallTimer对象,用来计算时间和更新UI
mCallTimer = new CallTimer(new Runnable() {
@Override
public void run() {
updateCallTime(); //更新UI的函数
}
});
}
@Override
public void onStateChange(InCallState oldState, InCallState newState, CallList callList) {
if (callList.getActiveCall() == null || callList.getActiveCall().getState() != Call.State.ACTIVE){
//当通话结束时需要取消计算时间的线程
mCallTimer.cancel();
}
}
//系统构建notification的方法
private void buildAndSendNotification(Call originalCall, ContactCacheEntry contactInfo) {
....省略部分代码
else if (callState == Call.State.ACTIVE && !mIsCallUiShown) {
//保存一个公共的变量到全部变量里面,方便后面构造新的notification并刷新
copyInfoFromHeadsUpView(builder, callState, contactInfo, notificationType, largeIcon);
//下面是计算显示的时间
final long callStart = call.getConnectTimeMillis();
final long duration = System.currentTimeMillis() - callStart;
//创建一个HeadsUpView显示在notification上面
RemoteViews inCall = createInCallHeadsUpView(duration / 1000, largeIcon);
builder.setContent(inCall);
builder.setCustomHeadsUpContentView(inCall);
//系统原生的方法最后notify通知
fireNotification(builder, callState, contactInfo, notificationType);
//开始我们的计时线程
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);
}
//格式化时间
String callTimeElapsed = DateUtils.formatElapsedTime(callDuration);
headsUpView.setTextViewText(R.id.in_call_hu_elapsedTime, callTimeElapsed);
return headsUpView;
}
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);
}
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;
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();
}
}
}
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持编程网。
免责声明:
① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。
② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341