diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index a83950c3..433eca19 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -235,11 +235,14 @@
+ android:name=".services.MyCallService"
+ android:permission="android.permission.BIND_INCALL_SERVICE">
+
+
-
+
diff --git a/app/src/main/kotlin/com/simplemobiletools/contacts/pro/activities/DialerActivity.kt b/app/src/main/kotlin/com/simplemobiletools/contacts/pro/activities/DialerActivity.kt
index 198a39b9..918d60c0 100644
--- a/app/src/main/kotlin/com/simplemobiletools/contacts/pro/activities/DialerActivity.kt
+++ b/app/src/main/kotlin/com/simplemobiletools/contacts/pro/activities/DialerActivity.kt
@@ -1,7 +1,9 @@
package com.simplemobiletools.contacts.pro.activities
+import android.content.BroadcastReceiver
import android.content.Context
import android.content.Intent
+import android.content.IntentFilter
import android.hardware.Sensor
import android.hardware.SensorEvent
import android.hardware.SensorEventListener
@@ -9,17 +11,23 @@ import android.hardware.SensorManager
import android.net.Uri
import android.os.Bundle
import android.os.PowerManager
+import androidx.localbroadcastmanager.content.LocalBroadcastManager
import com.simplemobiletools.commons.extensions.beGone
+import com.simplemobiletools.commons.extensions.beVisibleIf
import com.simplemobiletools.commons.extensions.toast
import com.simplemobiletools.commons.extensions.updateTextColors
import com.simplemobiletools.contacts.pro.R
-import com.simplemobiletools.contacts.pro.helpers.ContactsHelper
+import com.simplemobiletools.contacts.pro.helpers.*
import com.simplemobiletools.contacts.pro.models.Contact
+import com.simplemobiletools.contacts.pro.models.GsmCall
+import com.simplemobiletools.contacts.pro.objects.CallManager
import kotlinx.android.synthetic.main.activity_dialer.*
+// incoming call handling inspired by https://github.com/mbarrben/android_dialer_replacement
class DialerActivity : SimpleActivity(), SensorEventListener {
private val SENSOR_SENSITIVITY = 4
private var number = ""
+ private var isIncomingCall = false
private var sensorManager: SensorManager? = null
private var proximity: Sensor? = null
private var proximityWakeLock: PowerManager.WakeLock? = null
@@ -27,16 +35,22 @@ class DialerActivity : SimpleActivity(), SensorEventListener {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_dialer)
- dialer_hangup_button.setOnClickListener { finish() }
initProximityWakeLock()
+ LocalBroadcastManager.getInstance(applicationContext).registerReceiver(messageReceiver, IntentFilter(DIALER_INTENT_FILTER))
if (intent.action == Intent.ACTION_CALL && intent.data != null && intent.dataString?.contains("tel:") == true) {
number = Uri.decode(intent.dataString).substringAfter("tel:")
+ initViews()
ContactsHelper(this).getContactWithNumber(number) {
runOnUiThread {
updateCallee(it)
}
}
+ } else if (intent.action == INCOMING_CALL && intent.extras?.containsKey(CALLER_NUMBER) == true && intent.extras?.containsKey(CALL_STATUS) == true) {
+ isIncomingCall = true
+ number = intent.getStringExtra(CALLER_NUMBER)
+ initViews()
+ updateUI(intent.getSerializableExtra(CALL_STATUS) as GsmCall.Status)
} else {
toast(R.string.unknown_error_occurred)
finish()
@@ -54,6 +68,14 @@ class DialerActivity : SimpleActivity(), SensorEventListener {
sensorManager!!.unregisterListener(this)
}
+ private val messageReceiver = object : BroadcastReceiver() {
+ override fun onReceive(context: Context, intent: Intent) {
+ if (intent.extras?.containsKey(CALL_STATUS) == true) {
+ updateUI(intent.getSerializableExtra(CALL_STATUS) as GsmCall.Status)
+ }
+ }
+ }
+
private fun initProximityWakeLock() {
sensorManager = getSystemService(Context.SENSOR_SERVICE) as SensorManager
proximity = sensorManager!!.getDefaultSensor(Sensor.TYPE_PROXIMITY)
@@ -65,6 +87,22 @@ class DialerActivity : SimpleActivity(), SensorEventListener {
}
}
+ private fun initViews() {
+ dialer_hangup_button.setOnClickListener { CallManager.declineCall() }
+ dialer_incoming_accept.setOnClickListener { CallManager.acceptCall() }
+ dialer_incoming_decline.setOnClickListener { CallManager.declineCall() }
+
+ dialer_hangup_button.beVisibleIf(!isIncomingCall)
+ dialer_incoming_decline.beVisibleIf(isIncomingCall)
+ dialer_incoming_accept.beVisibleIf(isIncomingCall)
+
+ calling_label.setText(if (isIncomingCall) R.string.incoming_call else R.string.calling)
+ }
+
+ private fun updateUI(status: GsmCall.Status) {
+
+ }
+
private fun updateCallee(contact: Contact?) {
if (contact != null) {
callee_big_name_number.text = contact.getNameToDisplay()
diff --git a/app/src/main/kotlin/com/simplemobiletools/contacts/pro/extensions/Int.kt b/app/src/main/kotlin/com/simplemobiletools/contacts/pro/extensions/Int.kt
new file mode 100644
index 00000000..a150ed86
--- /dev/null
+++ b/app/src/main/kotlin/com/simplemobiletools/contacts/pro/extensions/Int.kt
@@ -0,0 +1,13 @@
+package com.simplemobiletools.contacts.pro.extensions
+
+import android.telecom.Call
+import com.simplemobiletools.contacts.pro.models.GsmCall
+
+fun Int.toGsmCallStatus() = when (this) {
+ Call.STATE_ACTIVE -> GsmCall.Status.ACTIVE
+ Call.STATE_RINGING -> GsmCall.Status.RINGING
+ Call.STATE_CONNECTING -> GsmCall.Status.CONNECTING
+ Call.STATE_DIALING -> GsmCall.Status.DIALING
+ Call.STATE_DISCONNECTED -> GsmCall.Status.DISCONNECTED
+ else -> GsmCall.Status.UNKNOWN
+}
diff --git a/app/src/main/kotlin/com/simplemobiletools/contacts/pro/helpers/Constants.kt b/app/src/main/kotlin/com/simplemobiletools/contacts/pro/helpers/Constants.kt
index e3b294e7..7f51f50a 100644
--- a/app/src/main/kotlin/com/simplemobiletools/contacts/pro/helpers/Constants.kt
+++ b/app/src/main/kotlin/com/simplemobiletools/contacts/pro/helpers/Constants.kt
@@ -33,6 +33,12 @@ const val FIRST_GROUP_ID = 10000L
const val KEY_PHONE = "phone"
const val KEY_NAME = "name"
+// Dialer
+const val INCOMING_CALL = "incoming_call"
+const val CALLER_NUMBER = "caller_number"
+const val CALL_STATUS = "call_status"
+const val DIALER_INTENT_FILTER = "dialer_intent_filter"
+
const val LOCATION_CONTACTS_TAB = 0
const val LOCATION_FAVORITES_TAB = 1
const val LOCATION_RECENTS_TAB = 2
diff --git a/app/src/main/kotlin/com/simplemobiletools/contacts/pro/helpers/MyConnectionService.kt b/app/src/main/kotlin/com/simplemobiletools/contacts/pro/helpers/MyConnectionService.kt
deleted file mode 100644
index 466b2a9f..00000000
--- a/app/src/main/kotlin/com/simplemobiletools/contacts/pro/helpers/MyConnectionService.kt
+++ /dev/null
@@ -1,10 +0,0 @@
-package com.simplemobiletools.contacts.pro.helpers
-
-import android.annotation.TargetApi
-import android.os.Build
-import android.telecom.ConnectionService
-
-@TargetApi(Build.VERSION_CODES.M)
-class MyConnectionService : ConnectionService() {
-
-}
diff --git a/app/src/main/kotlin/com/simplemobiletools/contacts/pro/models/GsmCall.kt b/app/src/main/kotlin/com/simplemobiletools/contacts/pro/models/GsmCall.kt
new file mode 100644
index 00000000..db23b0e0
--- /dev/null
+++ b/app/src/main/kotlin/com/simplemobiletools/contacts/pro/models/GsmCall.kt
@@ -0,0 +1,13 @@
+package com.simplemobiletools.contacts.pro.models
+
+data class GsmCall(val status: GsmCall.Status) {
+
+ enum class Status {
+ CONNECTING,
+ DIALING,
+ RINGING,
+ ACTIVE,
+ DISCONNECTED,
+ UNKNOWN
+ }
+}
diff --git a/app/src/main/kotlin/com/simplemobiletools/contacts/pro/objects/CallManager.kt b/app/src/main/kotlin/com/simplemobiletools/contacts/pro/objects/CallManager.kt
new file mode 100644
index 00000000..d6f095f7
--- /dev/null
+++ b/app/src/main/kotlin/com/simplemobiletools/contacts/pro/objects/CallManager.kt
@@ -0,0 +1,29 @@
+package com.simplemobiletools.contacts.pro.objects
+
+import android.annotation.TargetApi
+import android.os.Build
+import android.telecom.Call
+
+@TargetApi(Build.VERSION_CODES.M)
+object CallManager {
+ private var currentCall: Call? = null
+
+ fun updateCall(call: Call?) {
+ currentCall = call
+ }
+
+ fun declineCall() {
+ currentCall?.apply {
+ when (state) {
+ Call.STATE_RINGING -> reject(false, "")
+ else -> disconnect()
+ }
+ }
+ }
+
+ fun acceptCall() {
+ currentCall?.apply {
+ answer(details.videoState)
+ }
+ }
+}
diff --git a/app/src/main/kotlin/com/simplemobiletools/contacts/pro/services/MyCallService.kt b/app/src/main/kotlin/com/simplemobiletools/contacts/pro/services/MyCallService.kt
new file mode 100644
index 00000000..2c2da69a
--- /dev/null
+++ b/app/src/main/kotlin/com/simplemobiletools/contacts/pro/services/MyCallService.kt
@@ -0,0 +1,59 @@
+package com.simplemobiletools.contacts.pro.services
+
+import android.annotation.TargetApi
+import android.content.Intent
+import android.os.Build
+import android.telecom.Call
+import android.telecom.InCallService
+import androidx.localbroadcastmanager.content.LocalBroadcastManager
+import com.simplemobiletools.contacts.pro.activities.DialerActivity
+import com.simplemobiletools.contacts.pro.extensions.toGsmCallStatus
+import com.simplemobiletools.contacts.pro.helpers.CALLER_NUMBER
+import com.simplemobiletools.contacts.pro.helpers.CALL_STATUS
+import com.simplemobiletools.contacts.pro.helpers.DIALER_INTENT_FILTER
+import com.simplemobiletools.contacts.pro.helpers.INCOMING_CALL
+import com.simplemobiletools.contacts.pro.objects.CallManager
+
+@TargetApi(Build.VERSION_CODES.M)
+class MyCallService : InCallService() {
+
+ override fun onCallAdded(call: Call) {
+ super.onCallAdded(call)
+ call.registerCallback(callCallback)
+
+ val handle = call.details.handle.toString()
+ val callerNumber = if (handle.contains("tel:")) {
+ handle.substringAfter("tel:")
+ } else {
+ handle
+ }
+
+ Intent(this, DialerActivity::class.java).apply {
+ action = INCOMING_CALL
+ putExtra(CALL_STATUS, call.state.toGsmCallStatus())
+ putExtra(CALLER_NUMBER, callerNumber)
+ startActivity(this)
+ }
+ CallManager.updateCall(call)
+ }
+
+ override fun onCallRemoved(call: Call) {
+ super.onCallRemoved(call)
+ call.unregisterCallback(callCallback)
+ CallManager.updateCall(null)
+ }
+
+ private val callCallback = object : Call.Callback() {
+ override fun onStateChanged(call: Call, state: Int) {
+ CallManager.updateCall(call)
+ sendCallToActivity(call)
+ }
+ }
+
+ private fun sendCallToActivity(call: Call) {
+ Intent(DIALER_INTENT_FILTER).apply {
+ putExtra(CALL_STATUS, call.state.toGsmCallStatus())
+ LocalBroadcastManager.getInstance(applicationContext).sendBroadcast(this)
+ }
+ }
+}
diff --git a/app/src/main/res/drawable/circle_green_background.xml b/app/src/main/res/drawable/circle_green_background.xml
new file mode 100644
index 00000000..03bb39d3
--- /dev/null
+++ b/app/src/main/res/drawable/circle_green_background.xml
@@ -0,0 +1,9 @@
+
+
+
+
+
+
diff --git a/app/src/main/res/layout/activity_dialer.xml b/app/src/main/res/layout/activity_dialer.xml
index e035d95b..1d17779a 100644
--- a/app/src/main/res/layout/activity_dialer.xml
+++ b/app/src/main/res/layout/activity_dialer.xml
@@ -56,8 +56,37 @@
android:elevation="@dimen/medium_margin"
android:padding="@dimen/activity_margin"
android:src="@drawable/ic_phone_down"
+ android:visibility="gone"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"/>
+
+
+
+
diff --git a/app/src/main/res/values-az/strings.xml b/app/src/main/res/values-az/strings.xml
index 1d27d83b..7958fd38 100644
--- a/app/src/main/res/values-az/strings.xml
+++ b/app/src/main/res/values-az/strings.xml
@@ -112,6 +112,7 @@
Dialer
Calling…
+ Incoming call from…
Göstərmək üçün sahəni seç
diff --git a/app/src/main/res/values-de/strings.xml b/app/src/main/res/values-de/strings.xml
index f6ffaba7..08869b0c 100644
--- a/app/src/main/res/values-de/strings.xml
+++ b/app/src/main/res/values-de/strings.xml
@@ -112,6 +112,7 @@
Dialer
Calling…
+ Incoming call from…
Sichtbare Felder auswählen
diff --git a/app/src/main/res/values-el/strings.xml b/app/src/main/res/values-el/strings.xml
index f9d413a0..d99f3629 100644
--- a/app/src/main/res/values-el/strings.xml
+++ b/app/src/main/res/values-el/strings.xml
@@ -112,6 +112,7 @@
Dialer
Calling…
+ Incoming call from…
Επιλογή εμφάνισης πεδίων
diff --git a/app/src/main/res/values-eu/strings.xml b/app/src/main/res/values-eu/strings.xml
index 85c5989c..49da5f48 100644
--- a/app/src/main/res/values-eu/strings.xml
+++ b/app/src/main/res/values-eu/strings.xml
@@ -112,6 +112,7 @@
Dialer
Calling…
+ Incoming call from…
Hautatu erakusteko eremuak
diff --git a/app/src/main/res/values-fr/strings.xml b/app/src/main/res/values-fr/strings.xml
index 087f2daa..dbdee9fe 100644
--- a/app/src/main/res/values-fr/strings.xml
+++ b/app/src/main/res/values-fr/strings.xml
@@ -112,6 +112,7 @@
Dialer
Calling…
+ Incoming call from…
Sélectionner les champs à afficher
diff --git a/app/src/main/res/values-hr/strings.xml b/app/src/main/res/values-hr/strings.xml
index 2f0ff891..96a71cdf 100644
--- a/app/src/main/res/values-hr/strings.xml
+++ b/app/src/main/res/values-hr/strings.xml
@@ -112,6 +112,7 @@
Dialer
Calling…
+ Incoming call from…
Odaberi polja za prikaz
diff --git a/app/src/main/res/values-it/strings.xml b/app/src/main/res/values-it/strings.xml
index 76da5916..98ee80f9 100644
--- a/app/src/main/res/values-it/strings.xml
+++ b/app/src/main/res/values-it/strings.xml
@@ -112,6 +112,7 @@
Compositore
Chiamata in corso…
+ Incoming call from…
Seleziona i campi da mostrare
diff --git a/app/src/main/res/values-ja/strings.xml b/app/src/main/res/values-ja/strings.xml
index 91655c43..9a321697 100644
--- a/app/src/main/res/values-ja/strings.xml
+++ b/app/src/main/res/values-ja/strings.xml
@@ -112,6 +112,7 @@
Dialer
Calling…
+ Incoming call from…
表示する項目を選択
diff --git a/app/src/main/res/values-ko-rKR/strings.xml b/app/src/main/res/values-ko-rKR/strings.xml
index a361e143..c34cba44 100644
--- a/app/src/main/res/values-ko-rKR/strings.xml
+++ b/app/src/main/res/values-ko-rKR/strings.xml
@@ -112,6 +112,7 @@
Dialer
Calling…
+ Incoming call from…
Select fields to show
diff --git a/app/src/main/res/values-lt/strings.xml b/app/src/main/res/values-lt/strings.xml
index bfaa436a..907d262e 100644
--- a/app/src/main/res/values-lt/strings.xml
+++ b/app/src/main/res/values-lt/strings.xml
@@ -112,6 +112,7 @@
Dialer
Calling…
+ Incoming call from…
Pasirinkti rodomus laukelius
diff --git a/app/src/main/res/values-pt/strings.xml b/app/src/main/res/values-pt/strings.xml
index f541237c..c01cfded 100644
--- a/app/src/main/res/values-pt/strings.xml
+++ b/app/src/main/res/values-pt/strings.xml
@@ -112,6 +112,7 @@
Dialer
Calling…
+ Incoming call from…
Selecione os campos a mostrar
diff --git a/app/src/main/res/values-ru/strings.xml b/app/src/main/res/values-ru/strings.xml
index 9d8ff4d2..b673b8a9 100644
--- a/app/src/main/res/values-ru/strings.xml
+++ b/app/src/main/res/values-ru/strings.xml
@@ -112,6 +112,7 @@
Dialer
Calling…
+ Incoming call from…
Выберите отображаемые поля
diff --git a/app/src/main/res/values-sk/strings.xml b/app/src/main/res/values-sk/strings.xml
index 212ef231..bc15ab4a 100644
--- a/app/src/main/res/values-sk/strings.xml
+++ b/app/src/main/res/values-sk/strings.xml
@@ -111,7 +111,8 @@
Telefón
- Vytáčanie…
+ Vytáča sa…
+ Prichádzajúci hovor od…
Zvoľte polia na zobrazenie
diff --git a/app/src/main/res/values-sv/strings.xml b/app/src/main/res/values-sv/strings.xml
index 2ce100b4..6851d4f6 100644
--- a/app/src/main/res/values-sv/strings.xml
+++ b/app/src/main/res/values-sv/strings.xml
@@ -112,6 +112,7 @@
Dialer
Calling…
+ Incoming call from…
Välj vilka fält som ska visas
diff --git a/app/src/main/res/values-tr/strings.xml b/app/src/main/res/values-tr/strings.xml
index 87b43ed8..32ca04e4 100644
--- a/app/src/main/res/values-tr/strings.xml
+++ b/app/src/main/res/values-tr/strings.xml
@@ -112,6 +112,7 @@
Dialer
Calling…
+ Incoming call from…
Görüntülenecek alanları seç
diff --git a/app/src/main/res/values-zh-rTW/strings.xml b/app/src/main/res/values-zh-rTW/strings.xml
index a23a8f37..08af0c67 100644
--- a/app/src/main/res/values-zh-rTW/strings.xml
+++ b/app/src/main/res/values-zh-rTW/strings.xml
@@ -112,6 +112,7 @@
Dialer
Calling…
+ Incoming call from…
選擇要顯示的欄位
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index fed5e3ff..fa3ff8e6 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -112,6 +112,7 @@
Dialer
Calling…
+ Incoming call from…
Select fields to show