Resuelva el problema de la falta de sonido de fondo en el audio y vídeo de Agora Sound Network

Prefacio: este artículo presentará los métodos de procesamiento de las plataformas Android e iOS.

1. Cuando la aplicación vuelve al fondo en versiones superiores de Android, el sistema limitará las actividades en segundo plano de la aplicación para ahorrar energía. Por lo tanto, necesitamos abrir un servicio en primer plano y enviar notificaciones permanentes a la barra de tareas en el servicio en primer plano. asegúrese de que la aplicación vuelva al fondo. Sus actividades no estarán restringidas.

El código de servicio de recepción es el siguiente:

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
    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }

    private final String notificationId = "app_keep_live";
    private final String notificationName = "audio_and_video_call";

    @Override
    public void onCreate() {
        super.onCreate();
        NotificationManager notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
        //创建NotificationChannel
        if (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());
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        return super.onStartCommand(intent, flags, startId);
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
    }

    @Override
    public void onTaskRemoved(Intent rootIntent) {
        super.onTaskRemoved(rootIntent);
        //stop service
        this.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() {
        //获取启动Activity
        Intent msgIntent = getApplicationContext().getPackageManager().getLaunchIntentForPackage(getPackageName());
        PendingIntent pendingIntent = PendingIntent.getActivity(
                getApplicationContext(),
                1,
                msgIntent,
                PendingIntent.FLAG_UPDATE_CURRENT);
        return pendingIntent;
    }
}

No olvide declarar el Servicio en AndroidManifest.xml

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

Luego debe abrir y cerrar el servicio de primer plano respectivamente en la conexión de audio y video de Shengwang y colgar. La devolución de llamada aquí usa el método de escritura EaseCallKit. Si no usa la biblioteca de interfaz de usuario de EaseCallKit, puede conectarse y colgar en EaseVideoCallActivity usted mismo Devolución de llamada para abrir y cerrar el servicio en primer plano.

  public void addCallkitListener() {
        callKitListener = new EaseCallKitListener() {
            @Override
            public void onInviteUsers(Context context, String userId[], JSONObject ext) {
            }

            @Override
            public 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();
            }

            @Override
            public void onGenerateToken(String userId, String channelName, String appKey, EaseCallKitTokenCallback callback) {
                EMLog.d(TAG, "onGenerateToken userId:" + userId + " channelName:" + channelName + " appKey:" + appKey);
                //获取声网Token
                getAgoraToken(userId, channelName, callback);
               //创建服务开启任务栏通知(此处为了模拟,最好将openBarNotify()方法放在获取成功声网token后调用)
                openBarNotify();
            }

            @Override
            public void onReceivedCall(EaseCallType callType, String fromUserId, JSONObject ext) {
                EMLog.d(TAG, "onRecivedCall" + callType.name() + " fromUserId:" + fromUserId);
            }

            @Override
            public void onCallError(EaseCallKit.EaseCallError type, int errorCode, String description) {
                EMLog.d(TAG, "onCallError");
            }

            @Override
            public void onInViteCallMessageSent() {
//                LiveDataBus.get().with(DemoConstant.MESSAGE_CHANGE_CHANGE).postValue(new EaseEvent(DemoConstant.MESSAGE_CHANGE_CHANGE, EaseEvent.TYPE.MESSAGE));
            }

            @Override
            public 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启动service
            startForegroundService(keepAppIntent);
        } else {
            startService(keepAppIntent);
        }
    }

    private void stopBarNotify(){
        if (keepAppIntent != null) {
            stopService(keepAppIntent);
        }
    }


2. Si iOS quiere reproducir sonidos en segundo plano, debe agregar una aplicación que reproduzca audio o transmita audio/video usando permisos de AirPlay.

1. Busque la opción Modos de fondo requeridos en Info.plist y agregue La aplicación reproduce audio o transmite audio/video usando AirPlay.

2. Firma y capacidades -> Modos de fondo -> Audio, AirPlay e imagen en imagen

3. Implemente el método proxy applicationDidEnterBackground en AppDelegate.m

- (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. Debido a que la aplicación reproduce audio o transmite audio/video usando permisos de AirPlay, solo puede ser utilizada por aplicaciones con reproducción de música y escenarios de llamadas de audio y video, por lo que debe describir claramente cómo usar este escenario en los comentarios durante la revisión. La revisión falla, puede simplemente cargar el video grabado como un archivo adjunto y luego esperar a que Apple lo revise nuevamente. Si no hay problemas con el video grabado, simplemente espere y espere a que pase la revisión, ¡buena suerte!

Supongo que te gusta

Origin blog.csdn.net/c_furong/article/details/130584370
Recomendado
Clasificación