added Answer/Reject buttons to heads-up notification

This commit is contained in:
Juha Heinanen
2018-07-16 20:20:44 +03:00
parent d705f9f9e6
commit 19ca0e7cfd
3 changed files with 92 additions and 69 deletions
@@ -27,8 +27,6 @@ class BaresipService: Service() {
internal lateinit var intent: Intent internal lateinit var intent: Intent
internal lateinit var nm: NotificationManager internal lateinit var nm: NotificationManager
internal lateinit var snb: NotificationCompat.Builder internal lateinit var snb: NotificationCompat.Builder
internal lateinit var cnb: NotificationCompat.Builder
internal lateinit var ni: Intent
internal lateinit var npi: PendingIntent internal lateinit var npi: PendingIntent
internal lateinit var nr: BroadcastReceiver internal lateinit var nr: BroadcastReceiver
internal lateinit var wl: PowerManager.WakeLock internal lateinit var wl: PowerManager.WakeLock
@@ -44,9 +42,8 @@ class BaresipService: Service() {
nm = getSystemService(NOTIFICATION_SERVICE) as NotificationManager nm = getSystemService(NOTIFICATION_SERVICE) as NotificationManager
createNotificationChannels() createNotificationChannels()
snb = NotificationCompat.Builder(this, DEFAULT_CHANNEL_ID) snb = NotificationCompat.Builder(this, DEFAULT_CHANNEL_ID)
cnb = NotificationCompat.Builder(this, HIGH_CHANNEL_ID)
ni = Intent(this, MainActivity::class.java) val ni = Intent(this, MainActivity::class.java)
.setAction(Intent.ACTION_MAIN) .setAction(Intent.ACTION_MAIN)
.addCategory(Intent.CATEGORY_LAUNCHER) .addCategory(Intent.CATEGORY_LAUNCHER)
npi = PendingIntent.getActivity(this, 0, ni, 0) npi = PendingIntent.getActivity(this, 0, ni, 0)
@@ -252,51 +249,40 @@ class BaresipService: Service() {
} }
"call incoming" -> { "call incoming" -> {
if (!Utils.isVisible()) { if (!Utils.isVisible()) {
val cnb = NotificationCompat.Builder(this, HIGH_CHANNEL_ID)
cnb.setVisibility(VISIBILITY_PUBLIC) cnb.setVisibility(VISIBILITY_PUBLIC)
.setSmallIcon(R.drawable.ic_stat) .setSmallIcon(R.drawable.ic_stat)
.setContentIntent(npi) .setContentIntent(npi)
.setAutoCancel(true) .setAutoCancel(true)
.setContentText("Call from ${Api.call_peeruri(callp)}")
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O) { if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O) {
cnb.setVibrate(LongArray(0)) cnb.setVibrate(LongArray(0))
.setPriority(Notification.PRIORITY_HIGH) .setPriority(Notification.PRIORITY_HIGH)
} }
val view = RemoteViews(getPackageName(), R.layout.call_notification) /* val view = RemoteViews(getPackageName(), R.layout.call_notification)
view.setTextViewText(R.id.callFrom, "Call from ${Api.call_peeruri(callp)}") view.setTextViewText(R.id.callFrom, "Call from ${Api.call_peeruri(callp)}")
cnb.setContent(view) cnb.setContent(view) */
nm.notify(CALL_NOTIFICATION_ID, cnb.build())
}
/* if (!Utils.isVisible()) {
val cnb = NotificationCompat.Builder(this)
.setSmallIcon(R.drawable.ic_stat)
.setContentIntent(npi)
.setVisibility(VISIBILITY_PUBLIC)
.setPriority(Notification.PRIORITY_HIGH)
.setVibrate(LongArray(0))
val answerIntent = Intent(this, MainActivity::class.java) val answerIntent = Intent(this, MainActivity::class.java)
answerIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK or answerIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK or
Intent.FLAG_ACTIVITY_SINGLE_TOP or Intent.FLAG_ACTIVITY_CLEAR_TOP) Intent.FLAG_ACTIVITY_SINGLE_TOP or Intent.FLAG_ACTIVITY_CLEAR_TOP)
answerIntent.putExtra("action", "answer") answerIntent.putExtra("action", "answer")
answerIntent.putExtra("uap", uap)
answerIntent.putExtra("callp", callp) answerIntent.putExtra("callp", callp)
val answerPendingIntent = PendingIntent.getActivity(this, val answerPendingIntent = PendingIntent.getActivity(this,
0, answerIntent, PendingIntent.FLAG_UPDATE_CURRENT) 0, answerIntent, PendingIntent.FLAG_UPDATE_CURRENT)
val rejectIntent = Intent(this, MainActivity::class.java) val rejectIntent = Intent(this, MainActivity::class.java)
rejectIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK or rejectIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK or
Intent.FLAG_ACTIVITY_SINGLE_TOP or Intent.FLAG_ACTIVITY_CLEAR_TOP) Intent.FLAG_ACTIVITY_SINGLE_TOP)
rejectIntent.putExtra("action", "reject") rejectIntent.putExtra("action", "reject")
rejectIntent.putExtra("uap", uap)
rejectIntent.putExtra("callp", callp) rejectIntent.putExtra("callp", callp)
val rejectPendingIntent = PendingIntent.getActivity(this, val rejectPendingIntent = PendingIntent.getActivity(this,
0, rejectIntent, PendingIntent.FLAG_UPDATE_CURRENT) 1, rejectIntent, PendingIntent.FLAG_UPDATE_CURRENT)
val view = RemoteViews(getPackageName(), R.layout.call_notification) /* view.setOnClickPendingIntent(R.id.answerButton, answerPendingIntent)
view.setTextViewText(R.id.caller, "${Api.call_peeruri(callp)}")
view.setOnClickPendingIntent(R.id.answerButton, answerPendingIntent)
view.setOnClickPendingIntent(R.id.rejectButton, rejectPendingIntent) view.setOnClickPendingIntent(R.id.rejectButton, rejectPendingIntent)
cnb.setCustomBigContentView(view) cnb.setCustomBigContentView(view) */
cnb.setVibrate(LongArray(0)) cnb.addAction(R.drawable.ic_stat, "Answer", answerPendingIntent)
cnb.addAction(R.drawable.ic_stat, "Reject", rejectPendingIntent)
nm.notify(CALL_NOTIFICATION_ID, cnb.build()) nm.notify(CALL_NOTIFICATION_ID, cnb.build())
return }
} */
} }
"call established", "call closed" -> { "call established", "call closed" -> {
nm.cancel(CALL_NOTIFICATION_ID) nm.cancel(CALL_NOTIFICATION_ID)
@@ -97,11 +97,12 @@ class MainActivity : AppCompatActivity() {
arrayOf(Manifest.permission.RECORD_AUDIO), RECORD_AUDIO_PERMISSION) arrayOf(Manifest.permission.RECORD_AUDIO), RECORD_AUDIO_PERMISSION)
} }
aorSpinner = findViewById(R.id.AoRList) as Spinner aorSpinner = findViewById(R.id.AoRList)
uaAdapter = UaSpinnerAdapter(applicationContext, uas, images) uaAdapter = UaSpinnerAdapter(applicationContext, uas, images)
aorSpinner.adapter = uaAdapter aorSpinner.adapter = uaAdapter
aorSpinner.onItemSelectedListener = object : AdapterView.OnItemSelectedListener { aorSpinner.onItemSelectedListener = object : AdapterView.OnItemSelectedListener {
override fun onItemSelected(parent: AdapterView<*>, view: View, position: Int, id: Long) { override fun onItemSelected(parent: AdapterView<*>, view: View, position: Int, id: Long) {
Log.d("Baresip", "aorSpinner selecting $position")
val acc = uas[position].account val acc = uas[position].account
val aor = acc.aor val aor = acc.aor
val ua = uas[position] val ua = uas[position]
@@ -144,14 +145,26 @@ class MainActivity : AppCompatActivity() {
dtmf.visibility = View.INVISIBLE dtmf.visibility = View.INVISIBLE
} }
} }
val `in` = Call.uaCalls(calls, ua, "in")
val view_count = layout.childCount val view_count = layout.childCount
// Log.d("Baresip", "View count is $view_count") // Log.d("Baresip", "View count is $view_count")
if (view_count > 7) if (view_count > 7)
layout.removeViews(7, view_count - 7) layout.removeViews(7, view_count - 7)
for (c in `in`) for (c in Call.uaCalls(calls, ua, "in"))
for (call_index in Call.uaCalls(calls, ua,"in").indices) for (call_index in Call.uaCalls(calls, ua, "in").indices) {
addCallViews(ua, c, (call_index + 1) * 10) val startIndex = (call_index + 1) * 10
addCallViews(ua, c, startIndex)
if (answerCall == c.callp) {
answerCall = ""
val answerButton = layout.findViewById(startIndex + 5) as ImageButton
answerButton.performClick()
}
if (rejectCall == c.callp) {
rejectCall = ""
val rejectButton = layout.findViewById(startIndex + 6) as ImageButton
rejectButton.performClick()
moveTaskToBack(true)
}
}
} }
override fun onNothingSelected(parent: AdapterView<*>) { override fun onNothingSelected(parent: AdapterView<*>) {
@@ -332,16 +345,7 @@ class MainActivity : AppCompatActivity() {
aorSpinner.setSelection(account_index) aorSpinner.setSelection(account_index)
else else
addCallViews(ua, new_call, Call.uaCalls(calls, ua, "in").size * 10) addCallViews(ua, new_call, Call.uaCalls(calls, ua, "in").size * 10)
am.mode = AudioManager.MODE_RINGTONE startRinging()
rt.play()
rtTimer = Timer()
rtTimer!!.scheduleAtFixedRate(object : TimerTask() {
override fun run() {
if (!rt.isPlaying()) {
rt.play()
}
}
}, 1000 * 1, 1000 * 1)
if (Utils.isVisible()) { if (Utils.isVisible()) {
Log.d("Baresip", "Baresip is visible") Log.d("Baresip", "Baresip is visible")
val i = Intent(applicationContext, MainActivity::class.java) val i = Intent(applicationContext, MainActivity::class.java)
@@ -531,11 +535,7 @@ class MainActivity : AppCompatActivity() {
History.aorRemoveHistory(history, aor) History.aorRemoveHistory(history, aor)
history.add(History(aor, call.peerURI, "in", false)) history.add(History(aor, call.peerURI, "in", false))
} }
if (rtTimer != null) { stopRinging()
rtTimer!!.cancel()
rtTimer = null
if (rt.isPlaying) rt.stop()
}
} else { } else {
Log.d("Baresip", "Removing outgoing call $uap/$callp/" + Log.d("Baresip", "Removing outgoing call $uap/$callp/" +
call.peerURI) call.peerURI)
@@ -576,21 +576,13 @@ class MainActivity : AppCompatActivity() {
val action = intent.getStringExtra("action") val action = intent.getStringExtra("action")
Log.d("Baresip", "Got onNewIntent action $action") Log.d("Baresip", "Got onNewIntent action $action")
if (action == null) return if (action == null) return
val uap = intent.getStringExtra("uap")
val callp = intent.getStringExtra("callp") val callp = intent.getStringExtra("callp")
val ua = UserAgent.find(uas, intent.getStringExtra("uap"))!!
val aor = ua.account.aor
val peer_uri = Api.call_peeruri(callp)
when (action) { when (action) {
"answer" -> { "answer" -> {
/* TODO */ answerCall = callp
} }
"reject" -> { "reject" -> {
Log.d("Baresip", "Rejecting incoming call from $peer_uri") rejectCall = callp
ua_hangup(uap, callp, 486, "Busy Here")
if (History.aorHistory(history, aor) > HISTORY_SIZE)
History.aorRemoveHistory(history, aor)
history.add(History(aor, peer_uri, "in", false))
moveTaskToBack(true) moveTaskToBack(true)
} }
} }
@@ -607,6 +599,24 @@ class MainActivity : AppCompatActivity() {
Log.d("Baresip", "Resumed") Log.d("Baresip", "Resumed")
imm.hideSoftInputFromWindow(callee.windowToken, 0) imm.hideSoftInputFromWindow(callee.windowToken, 0)
visible = true visible = true
if ((answerCall != "") && (layout.childCount > 7)) {
answerCall = ""
/* if multiple calls, right answer button needs to be searched */
val answerButton = layout.findViewById(10 + 5) as ImageButton
answerButton.performClick()
}
if ((rejectCall != "") && (layout.childCount > 7)) {
rejectCall = ""
/* if multiple calls, right reject button needs to be searched */
val rejectButton = layout.findViewById(10 + 6) as ImageButton
rejectButton.performClick()
}
}
override fun onAttachedToWindow() {
super.onAttachedToWindow()
Log.d("Baresip", "View count at onAttachedToWindow is ${layout.childCount}")
Toast.makeText(this, "Hi UI is fully loaded", Toast.LENGTH_SHORT).show();
} }
override fun onBackPressed() { override fun onBackPressed() {
@@ -928,9 +938,15 @@ class MainActivity : AppCompatActivity() {
private fun setSecurityButtonTag(button: ImageButton, security: Int) { private fun setSecurityButtonTag(button: ImageButton, security: Int) {
when (security) { when (security) {
R.drawable.box_red -> { button.tag = "red" } R.drawable.box_red -> {
R.drawable.box_yellow -> { button.tag = "yellow" } button.tag = "red"
R.drawable.box_green -> { button.tag = "green" } }
R.drawable.box_yellow -> {
button.tag = "yellow"
}
R.drawable.box_green -> {
button.tag = "green"
}
} }
} }
@@ -942,6 +958,27 @@ class MainActivity : AppCompatActivity() {
button.setImageResource(R.drawable.resume) button.setImageResource(R.drawable.resume)
} }
private fun startRinging() {
am.mode = AudioManager.MODE_RINGTONE
rt.play()
rtTimer = Timer()
rtTimer!!.scheduleAtFixedRate(object : TimerTask() {
override fun run() {
if (!rt.isPlaying()) {
rt.play()
}
}
}, 1000 * 1, 1000 * 1)
}
private fun stopRinging() {
if (rtTimer != null) {
rtTimer!!.cancel()
rtTimer = null
if (rt.isPlaying) rt.stop()
}
}
external fun uag_current(): String external fun uag_current(): String
external fun uag_current_set(uap: String) external fun uag_current_set(uap: String)
external fun ua_connect(uap: String, peer_uri: String): String external fun ua_connect(uap: String, peer_uri: String): String
@@ -961,6 +998,8 @@ class MainActivity : AppCompatActivity() {
internal var calls = ArrayList<Call>() internal var calls = ArrayList<Call>()
var filesPath = "" var filesPath = ""
var visible = true var visible = true
var answerCall = ""
var rejectCall = ""
const val ACCOUNTS_CODE = 1 const val ACCOUNTS_CODE = 1
const val CONTACTS_CODE = 2 const val CONTACTS_CODE = 2
@@ -41,7 +41,6 @@
android:textSize="15dp" android:textSize="15dp"
style = "@android:style/TextAppearance.Medium" /> style = "@android:style/TextAppearance.Medium" />
<!--
<Button android:id="@+id/answerButton" <Button android:id="@+id/answerButton"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
@@ -62,6 +61,5 @@
android:layout_marginStart="20dp" android:layout_marginStart="20dp"
android:layout_gravity="center" android:layout_gravity="center"
android:text="Reject" /> android:text="Reject" />
-->
</RelativeLayout> </RelativeLayout>