当前位置: 首页 > 知识库问答 >
问题:

VOIP应用程序(如Marshmallow上的WhatsApp/Viber/Line/Skype)锁定屏幕上的来电

孔冥夜
2023-03-14

我们计划发布一个基于Twilio语音SDK的Android应用程序的更新。我们的客户想要一种更原生的体验,他们可以直接看到一个屏幕来接受或拒绝呼叫(就像Skype/WhatsApp/Viber/Line等),而不是点击通知然后再点击对话框。此外,这也应该在锁屏上工作。

private void notify(CallInvite callInvite, int notificationId) {
        String callSid = callInvite.getCallSid();

        if (callInvite.getState() == CallInvite.State.PENDING) {
            soundPoolManager.playRinging();

            System.out.println("Disabling keyguard and accquiring wake lock");



            Intent intent = new Intent(this, OnCallActivityNew.class);
            intent.setAction(OnCallActivityNew.ACTION_INCOMING_CALL);
            intent.putExtra(OnCallActivityNew.INCOMING_CALL_NOTIFICATION_ID, notificationId);
            intent.putExtra(OnCallActivityNew.INCOMING_CALL_INVITE, callInvite);
            intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
            intent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
            PendingIntent pendingIntent =
                    PendingIntent.getActivity(this, notificationId, intent, PendingIntent.FLAG_ONE_SHOT);
            /*
             * Pass the notification id and call sid to use as an identifier to cancel the
             * notification later
             */
            Bundle extras = new Bundle();
            extras.putInt(NOTIFICATION_ID_KEY, notificationId);
            extras.putString(CALL_SID_KEY, callSid);

            NotificationCompat.Builder notificationBuilder =
                    new NotificationCompat.Builder(this)
                            .setSmallIcon(R.drawable.ic_call_end_white_24px)
                            .setContentTitle(getString(R.string.app_name))
                            .setContentText(callInvite.getFrom() + " is calling.")
                            .setAutoCancel(true)
                            .setExtras(extras)
                            .setContentIntent(pendingIntent)
                            .setGroup("test_app_notification")
                            .setOngoing(true)
                            .setColor(Color.rgb(214, 10, 37));
            notificationManager.notify(notificationId, notificationBuilder.build());
            intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
            intent.putExtras(extras);
            globalintent =  intent;

            new Handler(Looper.getMainLooper()).postDelayed(new Runnable() {
                @Override
                public void run() {
                    startActivity(globalintent);
                }
            },2000);

        } else {
            SoundPoolManager.getInstance(this).stopRinging();
            if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.M) {
                /*
                 * If the incoming call was cancelled then remove the notification by matching
                 * it with the call sid from the list of notifications in the notification drawer.
                 */
                StatusBarNotification[] activeNotifications = notificationManager.getActiveNotifications();
                for (StatusBarNotification statusBarNotification : activeNotifications) {
                    Notification notification = statusBarNotification.getNotification();
                    Bundle extras = notification.extras;
                    String notificationCallSid = extras.getString(CALL_SID_KEY);

                    if (callSid.equals(notificationCallSid)) {
                        notificationManager.cancel(extras.getInt(NOTIFICATION_ID_KEY));
                    } else {
                        sendCallInviteToActivity(callInvite, notificationId);
                    }
                }
            } else {
                /*
                 * Prior to Android M the notification manager did not provide a list of
                 * active notifications so we lazily clear all the notifications when
                 * receiving a cancelled call.
                 *
                 * In order to properly cancel a notification using
                 * NotificationManager.cancel(notificationId) we should store the call sid &
                 * notification id of any incoming calls using shared preferences or some other form
                 * of persistent storage.
                 */
                notificationManager.cancelAll();
            }
        }
    }

此外,在OnCallActivityNew.java的onCreate()中,我提到了以下代码

@Override
    protected void onCreate(Bundle savedInstanceState) {
        System.out.println("on create of activity is called for oncallactivitynew");

        super.onCreate(savedInstanceState);
        KeyguardManager kgm = (KeyguardManager)getSystemService(Context.KEYGUARD_SERVICE);
        boolean isKeyguardUp = kgm.inKeyguardRestrictedInputMode();
        KeyguardManager.KeyguardLock kgl = kgm.newKeyguardLock("OnCallActivityNew");

        if(isKeyguardUp){
            kgl.disableKeyguard();
            isKeyguardUp = false;
        }

        PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE);
        wl = pm.newWakeLock(PowerManager.FULL_WAKE_LOCK, "My Tag");
        wl.acquire();
        this.getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN |
                        WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD |
                        WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED |
                        WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON,
                WindowManager.LayoutParams.FLAG_FULLSCREEN |
                        WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD |
                        WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED |
                        WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON);

        setContentView(R.layout.activity_on_call);


        coordinatorLayout = (CoordinatorLayout) fin
       ..... ///more code below to add listener to different buttons
}

现在唯一的问题是,当电话被锁定时,这个活动会打开,并且会调用onDestroy()并且我无法显示屏幕来接受和拒绝按钮。

我想要的行为是有一个机制,其中一个可以接受呼叫,甚至在锁屏,就像我上面提到的应用程序。

共有1个答案

毋胜涝
2023-03-14

我能够使视频通话工作与步骤在这个答案。

至于你的代码打开屏幕,请尝试我的,让我知道它是否适用于你。如果没有,您就会知道问题出在其他地方,因为这段代码可以在我测试的android设备上运行:

// These flags ensure that the activity can be launched when the screen is locked.
Window window = getWindow();
window.addFlags(WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED
        | WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON
        | WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);

// to wake up screen
PowerManager pm = (PowerManager) getApplicationContext().getSystemService(Context.POWER_SERVICE);
PowerManager.WakeLock wakeLock = pm.newWakeLock((PowerManager.SCREEN_BRIGHT_WAKE_LOCK | PowerManager.FULL_WAKE_LOCK | PowerManager.ACQUIRE_CAUSES_WAKEUP), "TAG");
wakeLock.acquire();

// to release screen lock
KeyguardManager keyguardManager = (KeyguardManager) getApplicationContext().getSystemService(Context.KEYGUARD_SERVICE);
KeyguardManager.KeyguardLock keyguardLock = keyguardManager.newKeyguardLock("TAG");
keyguardLock.disableKeyguard();
 类似资料: