我们计划发布基于 Twilio Voice SDK 的 Android 应用更新。我们的客户想要一种更原生的体验,他们可以直接看到一个屏幕来接受或拒绝调用(就像 Skype/Whatsapp/Viber/Line 等),而不是点击通知,然后点击对话框。此外,这也适用于锁定屏幕。
截至目前,我已成功在我的应用程序中打开一个 Activity 并显示接受或拒绝按钮。当应用程序处于前台或后台时,它都有效。这是实现此目的的代码段。我修改了 VoiceFirebaseMessagingService.java 中的 notify() 方法,以便在调用 onMessageRecived 来通知来电时显示 Activity 。
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
}
现在唯一的问题是,当手机锁定时,此 Activity 会打开并调用 onDestroy(),我无法显示接受和拒绝按钮的屏幕。
我想要的行为是拥有一种机制,即使在锁定屏幕上也可以接听电话,就像我上面提到的应用程序一样。
我知道这是一个与 Android 的工作方式更相关的问题,但是非常感谢你们在这方面的任何帮助。我相信人们会从这次讨论中受益。
最佳答案
我能够通过 this answer 中的步骤进行视频通话.
至于你打开屏幕的代码,请试试我的,如果它适合你,请告诉我。如果不是,您就会知道问题出在其他地方,因为这段代码适用于我测试过的 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();
关于android - VOIP 应用程序(如 Marshmallow 上的 Whatsapp/Viber/Line/Skype)在锁定屏幕上的来电,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46348881/
我想设置一个默认日期,例如实际日期,我该如何设置?还有如何在组合框中设置默认值顺便问一下,date_field_tag和date_field之间有什么区别? 最佳答案 试试这个:将默认日期作为第二个参数传递。youcorrectlysetthedefaultvalueofcomboboxasshowninyourquestion. 关于ruby-on-rails-date_field_tag,如何设置默认日期?[rails上的ruby],我们在StackOverflow上找到一个类似的问
我将我的Rails应用程序部署到OpenShift,它运行良好,但我无法在生产服务器上运行“Rails控制台”。它给了我这个错误。我该如何解决这个问题?我尝试更新rubygems,但它也给出了权限被拒绝的错误,我也无法做到。railsc错误:Warning:You'reusingRubygems1.8.24withSpring.UpgradetoatleastRubygems2.1.0andrun`gempristine--all`forbetterstartupperformance./opt/rh/ruby193/root/usr/share/rubygems/rubygems
我正在尝试从Postgresql表(table1)中获取数据,该表由另一个相关表(property)的字段(table2)过滤。在纯SQL中,我会这样编写查询:SELECT*FROMtable1JOINtable2USING(table2_id)WHEREtable2.propertyLIKE'query%'这工作正常:scope:my_scope,->(query){includes(:table2).where("table2.property":query)}但我真正需要的是使用LIKE运算符进行过滤,而不是严格相等。然而,这是行不通的:scope:my_scope,->(que
最近因为项目需要,需要将Android手机系统自带的某个系统软件反编译并更改里面某个资源,并重新打包,签名生成新的自定义的apk,下面我来介绍一下我的实现过程。APK修改,分为以下几步:反编译解包,修改,重打包,修改签名等步骤。安卓apk修改准备工作1.系统配置好JavaJDK环境变量2.需要root权限的手机(针对系统自带apk,其他软件免root)3.Auto-Sign签名工具4.apktool工具安卓apk修改开始反编译本文拿Android系统里面的Settings.apk做demo,具体如何将apk获取出来在此就不过多介绍了,直接进入主题:按键win+R输入cmd,打开命令窗口,并将路
我有一个.pfx格式的证书,我需要使用ruby提取公共(public)、私有(private)和CA证书。使用shell我可以这样做:#ExtractPublicKey(askforpassword)opensslpkcs12-infile.pfx-outfile_public.pem-clcerts-nokeys#ExtractCertificateAuthorityKey(askforpassword)opensslpkcs12-infile.pfx-outfile_ca.pem-cacerts-nokeys#ExtractPrivateKey(askforpassword)o
我了解instance_eval和class_eval之间的基本区别。我在玩弄时发现的是一些涉及attr_accessor的奇怪东西。这是一个例子:A=Class.newA.class_eval{attr_accessor:x}a=A.newa.x="x"a.x=>"x"#...expectedA.instance_eval{attr_accessor:y}A.y="y"=>NoMethodError:undefinedmethod`y='forA:Classa.y="y"=>"y"#WHATTT?这是怎么回事:instance_eval没有访问我们的A类(对象)然后它实际上将它添加到
我有一个集合选择:此方法的单选按钮是什么?谢谢 最佳答案 Rails3中没有这样的助手。在Rails4中,它是collection_radio_buttons. 关于ruby-on-rails-rails上的ruby:radiobuttonsforcollectionselect,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.com/questions/18525986/
我正在尝试将cucumber项目的用户名和密码置于版本控制之外。有没有办法在命令行上手动将用户名和密码等变量传递给Cucumber脚本?我的备份计划是将它们放在一个YML文件中,然后将该文件添加到gitignore,这样它们就不会被置于版本控制中。 最佳答案 所以,我看到了您对铁皮人的评论,答案是肯定的。cucumberPASSWORD=my_passwordPASSWORD被设置为环境变量,您可以通过将其引用为ENV['PASSWORD']来使用它的值。例如,browser.text_field(:id=>'pwd').setEN
我刚刚迈出了编程的第一步。我刚刚完成了CodeAcademy的另一门类(class)。这次我被要求创建一个小电影目录。这是我的问题:如何在文件中保存/加载带有电影标题和评级的哈希值而不是自己的代码?下面是代码现在的样子(几句葡萄牙语,但您可以忽略它:movies={Memento:3,Primer:4,Ishtar:1}puts"Oquevocêgostariadefazer?"puts"--Digite'add'paraadicionarumfilme."puts"--Digite'update'paraatualizarumfilme."puts"--Digite'display'
我是Ruby新手,并被要求在我们的新项目中使用它。我们还被要求使用Padrino(Sinatra)作为后端/框架。我们被要求使用Rspec进行测试。我一直在寻找可以指导在Padrino上使用RspecforRuby的教程。我得到的主要是引用RoR。但是,我需要RubyonPadrino。请在任何入门/指南/引用/讨论等方面指导我。如有不妥之处请指正。可能是我没有针对我的问题搜索正确的词/短语组合。我正在使用Ruby1.9.3和Padrinov.0.10.6。注意:我还提到了SOquestion,但它没有帮助。 最佳答案 我没用过Pa