IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 移动开发 -> RK3399 MH5000-31模组通话回铃音自制 -> 正文阅读

[移动开发]RK3399 MH5000-31模组通话回铃音自制

平台:RK3399
KERNEL版本:kernel4.4
Android版本:android8.1



前言

RK3399虽然在设计上有预留4G(5G等)模组,但由于自身产品定义,多提供的是优秀的多显方案产品定制,且自身可同时集成千兆百兆网口,模组本身一般不适用于通话,仅提供数据网络支持。
由于项目对通话有硬性要求,固写下该文章对大体通话涉及的修改内容进行记录,仅提供参考,如有错误,还望指出,感谢!


一、为何需要自制回铃音?

在Android平台,移植模组通信主要要完成两件事,其一调通RIL服务,在SDK工作正常情况下(硬件设计不应该存在问题,包括模组供电,SIM卡外围电路设计),识别到SIM卡插入,此时短信,上网基本没有问题。其二语音通话需要单独添加模组的声卡,大多采用PCM数据传输。MH5000-31采用的为NAU88C10,具体应用可参考华为5G模组5000-31语音通话功能调试记录(NAU88C10).md
在完成上述步骤后,通话双方都有声音了,但问题接踵而至。不同运营商情况下,模组这边偶尔听不到振铃的声音,给别人打电话没有嘟嘟声…这还得了,简直没有灵魂了有没有。于是便有了自制一个嘟嘟回铃音的想法。

二、实现步骤

1.寻找铃音并选择合适的播放手段

铃音网上就能找到资源,最好格式为ogg。添加位置如下:
frameworks/base/data/sounds/ringtones,也不局限于这里,可将找到的ogg放在上一级也行,这里更符合目录结构。在frameworks/base/data/sounds内AllAudio.mk添加,命名可自行选择,没有局限性,这里可以预制文件到system/media/audio/ringtones目录下,方便后续上层调用。


  $(LOCAL_PATH)/effects/ogg/camera_focus.ogg:system/media/audio/ui/camera_focus.ogg \
+ $(LOCAL_PATH)/ringtones/ring_beep.ogg:system/media/audio/ringtones/ring_beep.ogg \
  $(LOCAL_PATH)/ringtones/ring_beep.mp3:system/media/audio/ringtones/ring_beep.mp3 \

网上了解了Android音频文件播放方式,主流为MediaPlayer,SoundPool,AudioTrack,AsyncPlayer等,这篇博主写的文章十分不错[Android中播放音乐的几种方式],结合各种播放手段特点,这里选择了SoundPool来实现功能。(https://blog.csdn.net/u013366008/article/details/76577372)

2.定位拨出、接通前状态

上面准备工作做完了,那么接下来就是关键了,如何定位到拨出,振铃,接通这三个状态的代码位置,如何分析这个过程便成了重中之重。想详细了解可以看下这篇文章Android 8.0来电流程分析(一),也有一种别的办法就是看logcat,抓取这三种状态下的上层打印,从LOG中可以发现夹杂着大量的GsmCdmaConnection打印,并持续有GsmCdmaCallTracker,其中会有明确的OFFHOOK,DIALING,IDLE等状态,这部分还需自行百度了解,可以确认到整个通话过程是持续受上层监听的,这些状态值会在通话场景变化后跟随改变,很快找到frameworks/opt/telephony/src/java/com/android/internal/telephony/GsmCdmaConnection.java,很快发现了hangup,onDisconnect,onConnectedInOrOut等接口,这不就是我们要的位置吗。


3.边实验边添加合适调用位置

终于到了添加功能的时候了,首先想的就是导包import android.media.SoundPool;
创建和添加如下:

public class GsmCdmaConnection extends Connection {
    private static final String LOG_TAG = "GsmCdmaConnection";
    private static final boolean DBG = true;
    private static final boolean VDBG = false;

    //***** Instance Variables

+    SoundPool soundPool = new SoundPool(2, AudioManager.STREAM_MUSIC, 0);//类型为STREM_MUSIC
+    int soundId = soundPool.load("/system/media/audio/ringtones/ring_beep.ogg", 0);//load自己添加的音频文件
+    int streamID = 0;

    GsmCdmaCallTracker mOwner;
    GsmCdmaCall mParent;
   // Context mContext;

    boolean mDisconnected;

+    int play_flag = 0;

public boolean
    update (DriverCall dc) {
        GsmCdmaCall newParent;
        boolean changed = false;
        boolean wasConnectingInOrOut = isConnectingInOrOut();
        boolean wasHolding = (getState() == GsmCdmaCall.State.HOLDING);

        newParent = parentFromDCState(dc.state);

	-	if (Phone.DEBUG_PHONE) log("parent= " +mParent +", newParent= " + newParent);
    +   if (Phone.DEBUG_PHONE) log("parent= " +mParent.getClass().getName().toString() +", newParent= " + newParent.getClass().getName().toString());


	+   if(mParent.mState == GsmCdmaCall.State.ALERTING && newParent.mState == GsmCdmaCall.State.ALERTING && (play_flag == 0))
        {
    +          GsmCdmaPhone phone = mOwner.getPhone();
    +          streamID = soundPool.play(soundId, 1, 1, 0, -1, 1);//调用play,参数1,1,0,-1,1
    +          Rlog.d(LOG_TAG, "Player: flag=" + play_flag);
    +          Rlog.d(LOG_TAG, "Player: streamID1=" + streamID);
    +          play_flag = 1;
        }

播放完成后,必须在接通,挂断等情况下停止播放回铃音。

public boolean onDisconnect(int cause) {
        boolean changed = false;

        mCause = cause;

        if (!mDisconnected) {
            doDisconnect();

            if (DBG) Rlog.d(LOG_TAG, "onDisconnect: cause=" + cause);
	
	+ soundPool.stop(streamID);
	...
	}
public void hangup() throws CallStateException {
        if (!mDisconnected) {
	    Rlog.e(RIL.RILJ_LOG_TAG,"hangup liuk 111");
+	    soundPool.stop(streamID);
            mOwner.hangup(this);
        } else {
void
    onConnectedInOrOut() {
        mConnectTime = System.currentTimeMillis();
        mConnectTimeReal = SystemClock.elapsedRealtime();
        mDuration = 0;
        ...
+       play_flag = 0 ;

        if (!mIsIncoming) {
            // outgoing calls only
            processNextPostDialChar();
+	        Rlog.d(LOG_TAG, "Player: streamID2=" + streamID);
+	        soundPool.stop(streamID);
        } else {
            // Only release wake lock for incoming calls, for outgoing calls the wake lock
            // will be released after any pause-dial is completed
            releaseWakeLock();
        }
    }

看代码就能理清大抵的思路,在结束,接通后等接口处停止播放,在状态更新中添加振铃判断来进行播放。

遇到的问题

1.播放音频失败,循环不止,异常等,需要检查soundPool.play里面的参数,理解各值代表的意思,一般采用AudioManager.STREAM_MUSIC。
2.接通后电话后回铃音并没有停止,这里涉及到soundPool.stop的规范,仔细排查发现产生了多个streamID,这里添加了play_flag作为标志,振铃中只允许播放一次音频文件,在接通或者挂断后即onConnectedInOrOut置0。
3.来电禁止播放,在onConnectedInOrOut有mIsIncoming判断,通常下stop。

总结

整体实现需要对通话过程有一定了解,准备工作比较多,实际思路不是很复杂。文中只提供一个参考思路,实际上还需要屏蔽网络侧回铃音,整体还是比较鸡肋的功能,如果能让模组解决这种问题是最好的,这种问题还是模组本身的问题。
适用性问题:项目上通话speaker和播放音频的speaker不同,在播放回铃音录音下不会切到通话speaker,所以网络侧不管有没有回铃音都没有影响,这也是前文提到的,模组通话一般是单独添加一个codec芯片,电路上会区分成两路。

  移动开发 最新文章
Vue3装载axios和element-ui
android adb cmd
【xcode】Xcode常用快捷键与技巧
Android开发中的线程池使用
Java 和 Android 的 Base64
Android 测试文字编码格式
微信小程序支付
安卓权限记录
知乎之自动养号
【Android Jetpack】DataStore
上一篇文章      下一篇文章      查看所有文章
加:2021-10-27 12:56:47  更:2021-10-27 12:56:56 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 0:54:45-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码