解决Agora声网音视频在后台没有声音的问题

前言:本文会介绍 Android 与 iOS 两个平台的处理方式

一、Android高版本在应用退到后台时,系统为了省电会限制应用的后台活动,因此我们需要开启一个前台服务,在前台服务中发送常驻任务栏通知,以此来保证App 退到后台时不会被限制活动.

前台服务代码如下:

package com.notify.test.service;import android.app.Notification;
import android.app.NotificationChannel;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.os.Build;
import android.os.IBinder;import com.notify.test.R;import androidx.annotation.Nullable;/*** desc:解决声网音视频锁屏后听不到声音的问题* (可以配合Application.ActivityLifecycleCallbacks使用)** Created by booyoung* on 2023/9/8 14:46*/
public class KeepAppLifeService extends Service {@Nullable@Overridepublic IBinder onBind(Intent intent) {return null;}private final String notificationId = "app_keep_live";private final String notificationName = "audio_and_video_call";@Overridepublic void onCreate() {super.onCreate();NotificationManager notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);//创建NotificationChannelif (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {NotificationChannel channel = new NotificationChannel(notificationId, notificationName, NotificationManager.IMPORTANCE_HIGH);//不震动channel.enableVibration(false);//静音channel.setSound(null, null);notificationManager.createNotificationChannel(channel);}startForeground(1, getNotification());}@Overridepublic int onStartCommand(Intent intent, int flags, int startId) {return super.onStartCommand(intent, flags, startId);}@Overridepublic void onDestroy() {super.onDestroy();}@Overridepublic void onTaskRemoved(Intent rootIntent) {super.onTaskRemoved(rootIntent);//stop servicethis.stopSelf();}/*** 获取通知(Android8.0后需要)* @return*/private Notification getNotification() {Notification.Builder builder = new Notification.Builder(this).setSmallIcon(R.mipmap.logo).setOngoing(true).setContentTitle("App名称").setContentIntent(getIntent()).setContentText("音视频通话中,轻击以继续");if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {builder.setChannelId(notificationId);}return builder.build();}/*** 点击后,直接打开app* @return*/private PendingIntent getIntent() {//获取启动ActivityIntent msgIntent = getApplicationContext().getPackageManager().getLaunchIntentForPackage(getPackageName());PendingIntent pendingIntent = PendingIntent.getActivity(getApplicationContext(),1,msgIntent,PendingIntent.FLAG_UPDATE_CURRENT);return pendingIntent;}
}

不要忘记在AndroidManifest.xml中声明Service哈

 <service android:name=".service.KeepAppLifeService"android:enabled="true"android:exported="false"android:stopWithTask="true" />

然后接下来就需要在声网音视频接通与挂断分别开启与关闭前台服务了,此处回调使用了EaseCallKit的写法,如果没使用EaseCallKit UI库的可以自己在EaseVideoCallActivity中的接通与挂断回调开启与关闭前台服务

  public void addCallkitListener() {callKitListener = new EaseCallKitListener() {@Overridepublic void onInviteUsers(Context context, String userId[], JSONObject ext) {}@Overridepublic void onEndCallWithReason(EaseCallType callType, String channelName, EaseCallEndReason reason, long callTime) {EMLog.d(TAG, "onEndCallWithReason" + (callType != null ? callType.name() : " callType is null ") + " reason:" + reason + " time:" + callTime);SimpleDateFormat formatter = new SimpleDateFormat("mm:ss");formatter.setTimeZone(TimeZone.getTimeZone("UTC"));String callString = "通话时长";callString += formatter.format(callTime);Toast.makeText(MainActivity.this, callString, Toast.LENGTH_SHORT).show();//关闭任务栏通知stopBarNotify();}@Overridepublic void onGenerateToken(String userId, String channelName, String appKey, EaseCallKitTokenCallback callback) {EMLog.d(TAG, "onGenerateToken userId:" + userId + " channelName:" + channelName + " appKey:" + appKey);//获取声网TokengetAgoraToken(userId, channelName, callback);//创建服务开启任务栏通知(此处为了模拟,最好将openBarNotify()方法放在获取成功声网token后调用)openBarNotify();}@Overridepublic void onReceivedCall(EaseCallType callType, String fromUserId, JSONObject ext) {EMLog.d(TAG, "onRecivedCall" + callType.name() + " fromUserId:" + fromUserId);}@Overridepublic void onCallError(EaseCallKit.EaseCallError type, int errorCode, String description) {EMLog.d(TAG, "onCallError");}@Overridepublic void onInViteCallMessageSent() {
//                LiveDataBus.get().with(DemoConstant.MESSAGE_CHANGE_CHANGE).postValue(new EaseEvent(DemoConstant.MESSAGE_CHANGE_CHANGE, EaseEvent.TYPE.MESSAGE));}@Overridepublic void onRemoteUserJoinChannel(String channelName, String userName, int uid, EaseGetUserAccountCallback callback) {}};EaseCallKit.getInstance().setCallKitListener(callKitListener);}private void openBarNotify(){keepAppIntent = new Intent(this, KeepAppLifeService.class);if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {//android8.0以上通过startForegroundService启动servicestartForegroundService(keepAppIntent);} else {startService(keepAppIntent);}}private void stopBarNotify(){if (keepAppIntent != null) {stopService(keepAppIntent);}}

二、iOS想在后台时播放声音,需要在添加App plays audio or streams audio/video using AirPlay权限

1.Info.plist里找到选项Required background modes 添加App plays audio or streams audio/video using AirPlay

2.在Signing&Capabilities -> Background Modes -> 勾选 Audio,AirPlay, and Picture in Picture

3.在AppDelegate.m中实现applicationDidEnterBackground代理方法

- (void)applicationDidEnterBackground:(UIApplication *)application{//环信已实现了进入后台的处理逻辑,如果要自己处理,可以参考下边注释代码[[EMClient sharedClient] applicationDidEnterBackground:application];
}#if Ease_UIKIT
//    - (void)applicationDidEnterBackground:(NSNotification *)notification {
//        if (!self.config.shouldRemoveExpiredDataWhenEnterBackground) {
//            return;
//        }
//        Class UIApplicationClass = NSClassFromString(@"UIApplication");
//        if(!UIApplicationClass || ![UIApplicationClass respondsToSelector:@selector(sharedApplication)]) {
//            return;
//        }
//        UIApplication *application = [UIApplication performSelector:@selector(sharedApplication)];
//        __block UIBackgroundTaskIdentifier bgTask = [application beginBackgroundTaskWithExpirationHandler:^{
//            // Clean up any unfinished task business by marking where you
//            // stopped or ending the task outright.
//            [application endBackgroundTask:bgTask];
//            bgTask = UIBackgroundTaskInvalid;
//        }];
//
//        // Start the long-running task and return immediately.
//        [self deleteOldFilesWithCompletionBlock:^{
//            [application endBackgroundTask:bgTask];
//            bgTask = UIBackgroundTaskInvalid;
//        }];
//    }
#endif

 4.因为App plays audio or streams audio/video using AirPlay权限只能是音乐播放类与具有音视频通话场景的App使用,所以审核的时候需要在备注描述清楚使用该场景的方式.如果审核失败,可以录制视频在附件上传,然后等待苹果重新审核即可.如果录制的视频没有问题,那就坐等着审核通过了,good luck!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/132714.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

QCustomPlot绘图类详解(大白话)

本文假定你会使用Qt开发&#xff0c;但未接触过QCustomPlot绘图类或者是刚接触。 如何往Qt中引入QCustomPlot 首先&#xff0c;去官网下载最新版本的源码&#xff0c;注意是QCustomPlot.tar.gz这个文件&#xff0c;里面包含源码和示例。实际上&#xff0c;我们只需要qcustompl…

[学习笔记]CS224W(图机器学习) 2022/2023年冬学习笔记

资料&#xff1a; 课程网址 斯坦福CS224W图机器学习、图神经网络、知识图谱【同济子豪兄】 斯坦福大学CS224W图机器学习公开课-同济子豪兄中文精讲 cs224w&#xff08;图机器学习&#xff09;2021冬季课程学习笔记集合 序言 到图神经网络GCN为止的内容参考了斯坦福CS224W图机…

XUbuntu22.04之查找进程号pidof、pgrep总结(一百九十)

简介&#xff1a; CSDN博客专家&#xff0c;专注Android/Linux系统&#xff0c;分享多mic语音方案、音视频、编解码等技术&#xff0c;与大家一起成长&#xff01; 优质专栏&#xff1a;Audio工程师进阶系列【原创干货持续更新中……】&#x1f680; 人生格言&#xff1a; 人生…

【zlm】 webrtc源码讲解

目录 前端WEB 服务器收到请求 服务端的处理 播放 拉流 参考文章 前端WEB 服务器收到请求 POST /index/api/webrtc?applive&streamtest&typeplay HTTP/1.1 HttpSession::onRecvHeaderHttpSession::Handle_Req_POSTHttpSession::Handle_Req_POSTif (totalConte…

雅思学习总结

#【中秋征文】程序人生&#xff0c;中秋共享# 雅思小科普&#xff1a; 1. 什么是雅思考试&#xff1f; 雅思考试是由&#xff1a;英国文化协会、澳洲 IDP 教育集团、剑桥 大学考试委员会举办的英语水平测试。全称翻译成中文是&#xff1a; 国际英语语言测试系统。 2…

数据库直连提示 No suitable driver found for jdbc:postgresql

背景&#xff1a;我在代码里使用直连的方式在数据库中创建数据库等&#xff0c;由于需要适配各个数据库服务所以我分别兼容了mysql、postgresql、oracal等。但是在使用过程中会出现错误&#xff1a; No suitable driver found for jdbc:postgresql 但是我再使用mysql的直连方式…

片上网络(1)概述

前言 NoC&#xff1a;On-Chip Networks&#xff0c;片上网络。 由于多核乃至众核时代的到来&#xff0c;用于连接它们的可扩展、低延迟、大带宽的通信结构变得至关重要。 在核心较少时&#xff0c;总线Bus和矩阵/交叉开关Crossbar是主要的互联结构。总线可以提供较低的传输延迟…

删除安装Google Chrome浏览器时捆绑安装的Google 文档、表格、幻灯片、Gmail、Google 云端硬盘、YouTube网址链接(Mac)

删除安装Google Chrome浏览器时捆绑安装的Google 文档、表格、幻灯片、Gmail、Google 云端硬盘、YouTube网址链接(Mac) Mac mini操作系统&#xff0c;安装完 Google Chrome 浏览器以后&#xff0c;单击 启动台 桌面左下角的“显示应用程序”&#xff0c;我们发现捆绑安装了 Goo…

docker学习:dockerfile和docker-compose

学习如何使用dockerfile 以下内容&#xff0c;部分来自gpt生成&#xff0c;里面的描述可能会出现问题&#xff0c;但代码部分&#xff0c;我都会进行测试。 1. 需求 对于一个docker&#xff0c;例如python&#xff0c;我们需要其在构建成容器时&#xff0c;就有np。有以下两种方…

【项目实战】【已开源】USB2.0 HUB 集线器的制作教程(详细步骤以及电路图解释)

写在前面 本文是一篇关于 USB2.0 HUB 集线器的制作教程&#xff0c;包括详细的步骤以及电路图解释。 本文记录了笔者制作 USB2.0 HUB 集线器的心路历程&#xff0c;希望对你有帮助。 本文以笔记形式呈现&#xff0c;通过搜集互联网多方资料写成&#xff0c;非盈利性质&#xf…

java 单元测试Junit

所谓单元测试&#xff0c;就是针对最小的功能单元&#xff0c;编写测试代码对其进行正确性测试。为了测试更加方便&#xff0c;有一些第三方的公司或者组织提供了很好用的测试框架&#xff0c;给开发者使用。这里介绍一种Junit测试框架。Junit是第三方公司开源出来的&#xff0…

web系统安全设计原则

一、前言 近日&#xff0c;针对西工大网络被攻击&#xff0c;国家计算机病毒应急处理中心和360公司对一款名为“二次约会”的间谍软件进行了技术分析。分析报告显示&#xff0c;该软件是美国国家安全局&#xff08;NSA&#xff09;开发的网络间谍武器。当下&#xff0c;我们发现…

Spring Boot通过lombok提供的Slf4j省略日志的创建操作

上文 Spring Boot将声明日志步骤抽离出来做一个复用类中 我们写了个创建日志的公开类 但这么简单的东西 自然有人会将它写好 lombok已经 提供出了这个工具 首先 我们需要在 pom.xml 中加上这样一段代码 <dependency><groupId>org.projectlombok</groupId>…

Discourse 如何下载备份并恢复本地数据库

进入网站的备份界面&#xff0c;会看到当前所有的备份情况。 单击下载按钮。 需要注意的是&#xff0c;当你下载后&#xff0c;系统将会发送一个链接到你的邮箱地址中。 你可以使用邮箱地址中收到的链接进行数据下载。 下载链接 单击邮件中收到的下载链接地址进行下载。 下载…

线性代数的本质(九)——二次型与合同

文章目录 二次型与合同二次型与标准型二次型的分类度量矩阵与合同 二次型与合同 二次型与标准型 Grant&#xff1a;二次型研究的是二次曲面在不同基下的坐标变换 由解析几何的知识&#xff0c;我们了解到二次函数的一次项和常数项只是对函数图像进行平移&#xff0c;并不会改变…

下载CentOS ISO镜像 (一)

总目录 https://preparedata.blog.csdn.net/article/details/132877836 文章目录 总目录一、下载CentOS 镜像 一、下载CentOS 镜像 官网下载&#xff1a;https://www.centos.org/download/ Centos Linux 和 CentOS Stream 的区别&#xff1a;https://www.centos.org/cl-vs-cs…

AtCoder Beginner Contest 313 C 一个序列同时加一个数和减一个数,直到最大和最小之间相差最大为1(结论可记住)

AtCoder Beginner Contest 313 C 做题链接&#xff1a;AtCoder Beginner Contest 313 问题陈述 给你一个整数序列 A(A1​,A2​,…,AN​)。你可以执行以下操作任意次数&#xff08;可能为零&#xff09;。 选择带有 1≤i,j≤N的整数 i和 j。将Ai​减少 1&#xff0c;将Aj​增…

图扑可视化图表组件之股票数据分析应用

股市是市场经济的必然产物&#xff0c;在一个国家的金融领域之中有着举足轻重的地位。在过去&#xff0c;人们对于市场走势的把握主要依赖于经验和直觉&#xff0c;往往容易受到主观因素的影响&#xff0c;导致决策上出现偏差。如今&#xff0c;通过数据可视化呈现&#xff0c;…

【C++】多态

目录 1. 多态的概念1.1 概念 2. 多态的定义及实现2.1 多态的构成条件2.2 虚函数2.3 虚函数的重写2.3.1 重写的一些特殊情况 2.4 final和override2.5 重载、覆盖(重写)、隐藏(重定义)的对比 3. 抽象类3.1 概念3.2 实现继承与接口继承 4. 多态的原理4.1 虚函数表4.2 多态的原理4.…

入门人工智能 ——自然语言处理介绍,并使用 Python 进行文本情感分析(5)

入门人工智能 ——自然语言处理介绍&#xff0c;并使用 Python 进行文本情感分析&#xff08;5&#xff09;&#xff09; 入门人工智能 ——自然语言处理介绍&#xff0c;并使用 Python 进行文本情感分析介绍自然语言处理的挑战NLP的基本任务NLP的基本技术NLP的应用领域 使用 P…