Android Notification实现动态显示通话时间

基于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;
    }

    /*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();
        }
    }
}

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • Android获取通话时间实例分析

    本文章总结了一段Android获取通话时间程序代码,有需要的朋友可参考一下. 我们知道安卓系统中通话时长应该是归Callog管,所以建议去查查ContactProvider,或者是TelephonyProvider Service测试 可以的通话开始的时候启动Service 记录当前时间A, 然后stopSelf(); 另外在通话结束的时候再次启动一下Service,再次获得当前时间B, 然后把时间A和B进行比较处理 String time = Long.toString(比较后处理的时间) 然

  • Android Notification实现动态显示通话时间

    基于android N MTK释放的源码,供大家参考,具体内容如下 本文主要讲解如何在 IncallUI 的notification 上面不停地更新显示当前已通话多长时间,从而达到和incallUI通话界面上的通话时间一致. 主要思路 1.我们需要知道通话建立时的时间,即call 的状态从 INCOMING或者DIALING 转变成ACTIVE的时候 2.时间每秒钟都会发生变化,所以我们就需要不停的更新notification的界面,我们这里是不停的创建和notify同一个notificatio

  • android自定义Toast设定显示时间

    开发android的同学可能会抱怨Toast设定显示的时长无效,只能是Toast.LENGTH_LONG 或者Toast.LENGTH_SHORT 之一,为了解决这些办法,有多种实现方式: 1.使用定时器,定时调用show()方法. 2.使用CountDownTimer类,也是调用show()方法. 3.使用WindownManager类实现. 本文使用方法三进行实现,难度不大,直接看代码吧. package com.open.toast; import android.content.Cont

  • Android Notification使用教程详解

    目录 前言 正文 一.Android中通知的变化 1. Android 4.1,API 16 2. Android 4.4,API 19 和 20 3. Android 5.0,API 21 4. Android 7.0,API 24 5. Android 8.0,API 26 6. Android 12.0,API 31 二.创建项目 三.显示通知 ① 创建通知渠道 ② 初始化通知 ③ 显示通知 四.通知点击 ① 创建目的Activity ② PendingIntent使用 五.折叠通知 ①

  • 利用线程实现动态显示系统时间

    编写Applet小程序,通过在HTML文档中接收参数, 用不同颜色.字体显示当前的系统时间. import java.awt.*; import java.applet.Applet; import java.util.*; import java.awt.Graphics; public class clock extends Applet implements Runnable //继承Applet类并实现Runnable接口 { Thread clockThread=null; //创建一

  • asp.net 实现动态显示当前时间(不用javascript不考虑开销)

    Default.aspx页面:先拉一个ScriptManager控件到页面,然后拉一个UpdatePanel控件.UpdatePanel里面放一个Label用于显示时间,放一个timer控件用于控制时间的更新.注意Label与Label都要放到UpdatePanel控件里面.最后,timer控件的Interval属性设置为1000,让它每1秒执行一次即更新时间. Default.aspx.cs页面:只需在 protected void Page_Load(object sender, Event

  • Android Notification使用方法详解

    Android  Notification使用详解 Notification 核心代码(链式调用):适用于Android 4.0以上(不兼容低版本) Notification noti = new Notification.Builder(this) .setContentTitle("标题名称") .setContentText("标题里的内容") .setSmallIcon(R.drawable.new_mail) .setLargeIcon(BitmapFac

  • Android Notification.Builder通知案例分享

    随着Android系统的不断升级,相关Notification的用法有很多种,有的方法可能已经被android抛弃了,下面为大家分享一下个人如何实现Android Notification通知小案例源代码,供大家参考. Android Notification.Builder通知小案例,具体代码示例如下: package com.example.day6ke; import android.app.Notification; import android.app.NotificationMana

  • Android Notification使用方法总结

    Android Notification使用方法总结 一. 基本使用 1.构造notification NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(appContext) .setSmallIcon(appContext.getApplicationInfo().icon) .setWhen(System.currentTimeMillis()) .setAutoCancel(true)//当点击通知的

  • Android Notification的多种用法总结

    Android Notification的多种用法总结 我们在用手机的时候,如果来了短信,而我们没有点击查看的话,是不是在手机的最上边的状态栏里有一个短信的小图标提示啊?你是不是也想实现这种功能呢?今天的Notification就是解决这个问题的. 我们也知道Android系统也是在不断升级的,有关Notification的用法也就有很多种,有的方法已经被android抛弃了,现在我实现了三种不同的方法,并适应不同的android版本.现在我就把代码公布出来,我喜欢把解释写在代码中,在这里我就不

随机推荐