remove everything related to the custom Dialer, let the system handle it

This commit is contained in:
tibbi 2018-11-29 15:32:53 +01:00
parent 1b9028ba6c
commit 420a523062
21 changed files with 20 additions and 864 deletions

View File

@ -224,9 +224,7 @@
<activity
android:name=".activities.DialerActivity"
android:label="@string/dialer"
android:launchMode="singleTask"
android:showOnLockScreen="true">
android:label="@string/dialer">
<intent-filter>
<action android:name="android.intent.action.CALL"/>
@ -246,32 +244,6 @@
android:resource="@xml/provider_paths"/>
</provider>
<service
android:name=".services.MyIncomingCallService"
android:permission="android.permission.BIND_INCALL_SERVICE">
<meta-data
android:name="android.telecom.IN_CALL_SERVICE_UI"
android:value="true"/>
<intent-filter>
<action android:name="android.telecom.InCallService"/>
</intent-filter>
</service>
<service
android:name=".services.MyOutgoingCallService"
android:exported="true"
android:permission="android.permission.BIND_TELECOM_CONNECTION_SERVICE">
<intent-filter>
<action android:name="android.telecom.ConnectionService"/>
</intent-filter>
</service>
<service
android:name=".services.DialerCallService"
android:exported="false"/>
<activity-alias
android:name=".activities.SplashActivity.Red"
android:enabled="false"

View File

@ -2,188 +2,56 @@ package com.simplemobiletools.contacts.pro.activities
import android.annotation.SuppressLint
import android.annotation.TargetApi
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
import android.hardware.SensorManager
import android.net.Uri
import android.os.Build
import android.os.Bundle
import android.os.Handler
import android.os.PowerManager
import android.telecom.Call
import android.telecom.PhoneAccount
import android.telecom.TelecomManager
import android.view.WindowManager
import androidx.localbroadcastmanager.content.LocalBroadcastManager
import com.simplemobiletools.commons.extensions.*
import com.simplemobiletools.commons.extensions.showErrorToast
import com.simplemobiletools.commons.extensions.toast
import com.simplemobiletools.contacts.pro.R
import com.simplemobiletools.contacts.pro.helpers.*
import com.simplemobiletools.contacts.pro.models.Contact
import com.simplemobiletools.contacts.pro.objects.CallManager
import com.simplemobiletools.contacts.pro.overloads.times
import com.simplemobiletools.contacts.pro.services.DialerCallService
import kotlinx.android.synthetic.main.activity_dialer.*
// incoming call handling inspired by https://github.com/mbarrben/android_dialer_replacement
@TargetApi(Build.VERSION_CODES.M)
class DialerActivity : SimpleActivity(), SensorEventListener {
class DialerActivity : SimpleActivity() {
private val REQUEST_CODE_SET_DEFAULT_DIALER = 1
private val SENSOR_SENSITIVITY = 4
private val DISCONNECT_DELAY = 3000L
private val CALLING_DOT_ANIMATION_DELAY = 500L
private var callNumber = ""
private var callStatus = Call.STATE_NEW
private var isIncomingCall = false
private var isCallActive = false
private var callDuration = 0
private var callingDotsCnt = 0
private var sensorManager: SensorManager? = null
private var proximity: Sensor? = null
private var proximityWakeLock: PowerManager.WakeLock? = null
private var timerHandler = Handler()
private var callingDotsHandler = Handler()
private var callNumber: Uri? = null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_dialer)
initProximityWakeLock()
LocalBroadcastManager.getInstance(applicationContext).registerReceiver(messageReceiver, IntentFilter(DIALER_INTENT_FILTER))
window.apply {
addFlags(WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED)
addFlags(WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON)
addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON)
}
val action = intent.action
val extras = intent.extras
if (extras?.getBoolean(ANSWER_CALL, false) == true) {
callNumber = intent.getStringExtra(CALL_NUMBER)
CallManager.answerCall()
tryFillingOtherParticipantsName()
initViews()
} else if (action == Intent.ACTION_CALL && intent.data != null && intent.dataString?.contains("tel:") == true) {
callNumber = Uri.decode(intent.dataString).substringAfter("tel:")
tryFillingOtherParticipantsName()
if (intent.action == Intent.ACTION_CALL && intent.data != null) {
callNumber = intent.data
// make sure Simple Contacts is the default Phone app before initiating an outgoing call
val telecomManager = getSystemService(Context.TELECOM_SERVICE) as TelecomManager
if (telecomManager.defaultDialerPackage != packageName) {
val intent = Intent(TelecomManager.ACTION_CHANGE_DEFAULT_DIALER).putExtra(TelecomManager.EXTRA_CHANGE_DEFAULT_DIALER_PACKAGE_NAME, packageName)
startActivityForResult(intent, REQUEST_CODE_SET_DEFAULT_DIALER)
} else {
initOutgoingCall()
initViews()
} else if (action == INCOMING_CALL && extras?.containsKey(CALL_NUMBER) == true && extras.containsKey(CALL_STATUS)) {
isIncomingCall = true
callNumber = intent.getStringExtra(CALL_NUMBER)
initViews()
updateUI(intent.getIntExtra(CALL_STATUS, Call.STATE_NEW))
tryFillingOtherParticipantsName()
} else if (action == RESUME_DIALER && extras?.containsKey(CALL_NUMBER) == true && extras.containsKey(CALL_STATUS) && extras.containsKey(IS_INCOMING_CALL)) {
callNumber = intent.getStringExtra(CALL_NUMBER)
callStatus = intent.getIntExtra(CALL_STATUS, Call.STATE_NEW)
isIncomingCall = intent.getBooleanExtra(IS_INCOMING_CALL, false)
updateUI(callStatus)
tryFillingOtherParticipantsName()
initViews()
}
} else {
toast(R.string.unknown_error_occurred)
finish()
}
}
override fun onResume() {
super.onResume()
updateTextColors(dialer_holder)
sensorManager!!.registerListener(this, proximity!!, SensorManager.SENSOR_DELAY_NORMAL)
}
override fun onPause() {
super.onPause()
sensorManager!!.unregisterListener(this)
if (!isCallActive && callStatus != Call.STATE_DISCONNECTED) {
startNotificationService()
}
}
override fun onDestroy() {
super.onDestroy()
timerHandler.removeCallbacksAndMessages(null)
callingDotsHandler.removeCallbacksAndMessages(null)
}
private val messageReceiver = object : BroadcastReceiver() {
override fun onReceive(context: Context, intent: Intent) {
if (intent.extras?.containsKey(CALL_STATUS) == true) {
updateUI(intent.getIntExtra(CALL_STATUS, Call.STATE_NEW))
}
}
}
override fun onBackPressed() {
super.onBackPressed()
if (!isCallActive && !isIncomingCall) {
hangUp()
}
}
// animate the dots after Calling... from 0 to 3
private fun handleDotsAnimation() {
callingDotsHandler.postDelayed({
if (callStatus == Call.STATE_DIALING) {
callingDotsCnt = ++callingDotsCnt % 4
dialer_label_dots.text = ".".times(callingDotsCnt)
handleDotsAnimation()
}
}, CALLING_DOT_ANIMATION_DELAY)
}
private fun initProximityWakeLock() {
sensorManager = getSystemService(Context.SENSOR_SERVICE) as SensorManager
proximity = sensorManager!!.getDefaultSensor(Sensor.TYPE_PROXIMITY)
val powerManager = getSystemService(Context.POWER_SERVICE) as PowerManager
proximityWakeLock = if (powerManager.isWakeLockLevelSupported(PowerManager.PROXIMITY_SCREEN_OFF_WAKE_LOCK)) {
powerManager.newWakeLock(PowerManager.PROXIMITY_SCREEN_OFF_WAKE_LOCK, "SimpleContacts:ProximityWakeLock")
} else {
null
}
}
private fun initViews() {
dialer_hangup_button.setOnClickListener { hangUp() }
dialer_incoming_accept.setOnClickListener { CallManager.answerCall() }
dialer_incoming_decline.setOnClickListener { hangUp() }
dialer_hangup_button.beVisibleIf(!isIncomingCall)
dialer_incoming_decline.beVisibleIf(isIncomingCall)
dialer_incoming_accept.beVisibleIf(isIncomingCall)
dialer_label.setText(if (isIncomingCall) R.string.incoming_call_from else R.string.calling)
if (!isIncomingCall) {
handleDotsAnimation()
}
}
@SuppressLint("MissingPermission")
private fun initOutgoingCall() {
try {
val telecomManager = getSystemService(Context.TELECOM_SERVICE) as TelecomManager
val uri = Uri.fromParts(PhoneAccount.SCHEME_TEL, callNumber, null)
Bundle().apply {
putParcelable(TelecomManager.EXTRA_PHONE_ACCOUNT_HANDLE, telecomManager.getDefaultOutgoingPhoneAccount(PhoneAccount.SCHEME_TEL))
putBoolean(TelecomManager.EXTRA_START_CALL_WITH_VIDEO_STATE, false)
putBoolean(TelecomManager.EXTRA_START_CALL_WITH_SPEAKERPHONE, false)
telecomManager.placeCall(uri, this)
}
callStatus = Call.STATE_DIALING
} catch (e: Exception) {
// only default Phone apps can initiate outgoing calls. So if we got here and Simple Contacts isnt the default phone app, ask the user to set so
if (e is SecurityException) {
val intent = Intent(TelecomManager.ACTION_CHANGE_DEFAULT_DIALER).putExtra(TelecomManager.EXTRA_CHANGE_DEFAULT_DIALER_PACKAGE_NAME, packageName)
startActivityForResult(intent, REQUEST_CODE_SET_DEFAULT_DIALER)
} else {
showErrorToast(e)
telecomManager.placeCall(callNumber, this)
finish()
}
} catch (e: Exception) {
showErrorToast(e)
finish()
}
}
@ -198,118 +66,4 @@ class DialerActivity : SimpleActivity(), SensorEventListener {
}
}
}
private fun startNotificationService() {
Intent(this, DialerCallService::class.java).apply {
putExtra(CALL_NUMBER, callNumber)
putExtra(CALL_STATUS, callStatus)
putExtra(IS_INCOMING_CALL, isIncomingCall)
startService(this)
}
}
private fun stopNotificationService() {
Intent(this, DialerCallService::class.java).apply {
stopService(this)
}
}
private fun hangUp() {
callStatus = Call.STATE_DISCONNECTED
stopNotificationService()
CallManager.declineCall()
finish()
}
private fun tryFillingOtherParticipantsName() {
ContactsHelper(this).getContactWithNumber(callNumber) {
runOnUiThread {
updateOtherParticipant(it)
}
}
}
private fun updateUI(status: Int) {
callStatus = status
when (status) {
Call.STATE_ACTIVE -> statusActive()
Call.STATE_DISCONNECTED -> statusDisconnected()
}
}
private fun statusActive() {
callingDotsHandler.removeCallbacksAndMessages(null)
dialer_label_dots.beGone()
startNotificationService()
isCallActive = true
dialer_call_duration.beVisible()
updateCallDuration()
dialer_label.setText(R.string.ongoing_call)
dialer_hangup_button.beVisible()
dialer_incoming_accept.beGone()
dialer_incoming_decline.beGone()
}
private fun updateCallDuration() {
dialer_call_duration.text = callDuration.getFormattedDuration()
timerHandler.postDelayed({
if (isCallActive) {
callDuration++
updateCallDuration()
}
}, 1000)
}
private fun statusDisconnected() {
callingDotsHandler.removeCallbacksAndMessages(null)
timerHandler.removeCallbacksAndMessages(null)
dialer_label_dots.beGone()
stopNotificationService()
dialer_hangup_button.beGone()
dialer_label.setText(R.string.disconnected)
if (isCallActive) {
dialer_hangup_button.postDelayed({
finish()
}, DISCONNECT_DELAY)
} else {
finish()
}
isCallActive = false
}
private fun updateOtherParticipant(contact: Contact?) {
if (contact != null) {
dialer_big_name_number.text = contact.getNameToDisplay()
dialer_number.text = callNumber
} else {
dialer_big_name_number.text = callNumber
dialer_number.beGone()
}
}
override fun onAccuracyChanged(sensor: Sensor?, accuracy: Int) {}
override fun onSensorChanged(event: SensorEvent) {
if (event.sensor.type == Sensor.TYPE_PROXIMITY) {
if (event.values[0] >= -SENSOR_SENSITIVITY && event.values[0] <= SENSOR_SENSITIVITY) {
turnOffScreen()
} else {
turnOnScreen()
}
}
}
@SuppressLint("WakelockTimeout")
private fun turnOffScreen() {
if (proximityWakeLock?.isHeld == false) {
proximityWakeLock!!.acquire()
}
}
private fun turnOnScreen() {
if (proximityWakeLock?.isHeld == true) {
proximityWakeLock!!.release(PowerManager.RELEASE_FLAG_WAIT_FOR_NO_PROXIMITY)
}
}
}

View File

@ -32,16 +32,6 @@ 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 RESUME_DIALER = "resume_dialer"
const val CALL_NUMBER = "call_number"
const val CALL_STATUS = "call_status"
const val IS_INCOMING_CALL = "is_incoming_call"
const val DIALER_INTENT_FILTER = "dialer_intent_filter"
const val DECLINE_CALL = "decline_call"
const val ANSWER_CALL = "answer_call"
const val LOCATION_CONTACTS_TAB = 0
const val LOCATION_FAVORITES_TAB = 1
const val LOCATION_RECENTS_TAB = 2

View File

@ -93,31 +93,6 @@ class ContactsHelper(val context: Context) {
}.start()
}
fun getContactWithNumber(number: String, callback: (contact: Contact?) -> Unit) {
Thread {
val uri = CommonDataKinds.Phone.CONTENT_URI
val projection = arrayOf(ContactsContract.Data.RAW_CONTACT_ID)
val selection = "${CommonDataKinds.Phone.NUMBER} = ? OR ${CommonDataKinds.Phone.NORMALIZED_NUMBER} = ?"
val selectionArgs = arrayOf(number, number.normalizeNumber())
var cursor: Cursor? = null
try {
cursor = context.contentResolver.query(uri, projection, selection, selectionArgs, null)
if (cursor?.moveToFirst() == true) {
val id = cursor.getIntValue(ContactsContract.Data.RAW_CONTACT_ID)
callback(getContactWithId(id, false))
return@Thread
}
} catch (e: Exception) {
context.showErrorToast(e)
} finally {
cursor?.close()
}
callback(LocalContactsHelper(context).getContactWithNumber(number))
}.start()
}
private fun getContentResolverAccounts(): HashSet<ContactSource> {
val uri = ContactsContract.Data.CONTENT_URI
val projection = arrayOf(

View File

@ -19,15 +19,6 @@ class LocalContactsHelper(val context: Context) {
fun getContactWithId(id: Int) = convertLocalContactToContact(context.contactsDB.getContactWithId(id))
fun getContactWithNumber(number: String): Contact? {
context.contactsDB.getContacts().forEach {
if (it.phoneNumbers.map { it.value }.contains(number)) {
return convertLocalContactToContact(it)
}
}
return null
}
fun insertOrUpdateContact(contact: Contact): Boolean {
val localContact = convertContactToLocalContact(contact)
return context.contactsDB.insertOrUpdate(localContact) > 0

View File

@ -1,33 +0,0 @@
package com.simplemobiletools.contacts.pro.helpers
import android.annotation.TargetApi
import android.content.Context
import android.os.Build
import android.telecom.Connection
import android.telecom.DisconnectCause
@TargetApi(Build.VERSION_CODES.M)
class MyConnection(val context: Context) : Connection() {
override fun onAnswer() {
super.onAnswer()
setActive()
}
override fun onReject() {
super.onReject()
setDisconnected(DisconnectCause(DisconnectCause.REJECTED))
destroy()
}
override fun onAbort() {
super.onAbort()
setDisconnected(DisconnectCause(DisconnectCause.REMOTE))
destroy()
}
override fun onDisconnect() {
super.onDisconnect()
setDisconnected(DisconnectCause(DisconnectCause.CANCELED))
destroy()
}
}

View File

@ -1,29 +0,0 @@
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 answerCall() {
currentCall?.apply {
answer(details.videoState)
}
}
}

View File

@ -1,161 +0,0 @@
package com.simplemobiletools.contacts.pro.services
import android.annotation.TargetApi
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.Handler
import android.telecom.Call
import android.widget.RemoteViews
import androidx.core.app.NotificationCompat
import com.simplemobiletools.commons.extensions.getColoredBitmap
import com.simplemobiletools.commons.extensions.setText
import com.simplemobiletools.commons.extensions.setVisibleIf
import com.simplemobiletools.commons.helpers.isOreoPlus
import com.simplemobiletools.contacts.pro.R
import com.simplemobiletools.contacts.pro.activities.DialerActivity
import com.simplemobiletools.contacts.pro.helpers.*
import com.simplemobiletools.contacts.pro.objects.CallManager
class DialerCallService : Service() {
private val REFRESH_REMINDER_PERIOD = 3000L
private val CALL_NOTIFICATION_ID = 1
private val LAUNCH_DIALER_INTENT_ID = 1
private val DISMISS_CALL_INTENT_ID = 2
private val ANSWER_CALL_INTENT_ID = 3
private var callNumber = ""
private var callStatus = Call.STATE_NEW
private var isIncomingCall = false
private var otherParticipantName: String? = null
private var reminderRefreshHandler = Handler()
override fun onBind(intent: Intent?) = null
override fun onStartCommand(intent: Intent, flags: Int, startId: Int): Int {
super.onStartCommand(intent, flags, startId)
when {
intent.getBooleanExtra(DECLINE_CALL, false) -> {
CallManager.declineCall()
stopForeground(true)
stopSelf()
}
intent.extras?.containsKey(CALL_STATUS) == true -> {
callNumber = intent.getStringExtra(CALL_NUMBER)
callStatus = intent.getIntExtra(CALL_STATUS, Call.STATE_NEW)
isIncomingCall = intent.getBooleanExtra(IS_INCOMING_CALL, false)
getOtherParticipantsName()
}
}
return START_STICKY
}
override fun onDestroy() {
super.onDestroy()
stopForeground(true)
reminderRefreshHandler.removeCallbacksAndMessages(null)
}
private fun getOtherParticipantsName() {
ContactsHelper(this).getContactWithNumber(callNumber) {
otherParticipantName = it?.getNameToDisplay() ?: callNumber
setupNotification()
}
}
@TargetApi(Build.VERSION_CODES.O)
private fun setupNotification() {
val channelId = "call_channel"
if (isOreoPlus()) {
val notificationManager = getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
val name = resources.getString(R.string.app_name)
val importance = if (callStatus == Call.STATE_RINGING) NotificationManager.IMPORTANCE_HIGH else NotificationManager.IMPORTANCE_DEFAULT
NotificationChannel(channelId, name, importance).apply {
enableLights(false)
enableVibration(false)
setSound(null, null)
notificationManager.createNotificationChannel(this)
}
}
val notificationLayout = RemoteViews(packageName, R.layout.incoming_call_notification).apply {
setText(R.id.incoming_call_caller, otherParticipantName!!)
setText(R.id.incoming_call_status, getCallStatusString())
val resources = applicationContext.resources
setImageViewBitmap(R.id.call_decline, resources.getColoredBitmap(R.drawable.ic_phone_down, resources.getColor(R.color.theme_dark_red_primary_color)))
setImageViewBitmap(R.id.call_answer, resources.getColoredBitmap(R.drawable.ic_phone, resources.getColor(R.color.md_green_700)))
setVisibleIf(R.id.call_answer, callStatus == Call.STATE_RINGING)
setOnClickPendingIntent(R.id.call_decline, getDeclineCallIntent())
setOnClickPendingIntent(R.id.call_answer, getAnswerCallIntent())
}
val notification = NotificationCompat.Builder(applicationContext, channelId)
.setSmallIcon(R.drawable.ic_phone)
.setContentIntent(getLaunchDialerIntent())
.setVisibility(NotificationCompat.VISIBILITY_PUBLIC)
.setPriority(NotificationCompat.PRIORITY_MAX)
.setCustomContentView(notificationLayout)
.setCustomHeadsUpContentView(notificationLayout)
.setCustomBigContentView(notificationLayout)
.setOngoing(true)
.setCategory(NotificationCompat.CATEGORY_CALL)
.setChannelId(channelId)
.setSound(null)
.setOnlyAlertOnce(false)
.setUsesChronometer(callStatus == Call.STATE_ACTIVE)
startForeground(CALL_NOTIFICATION_ID, notification.build())
reminderRefreshHandler.postDelayed({
if (callStatus == Call.STATE_RINGING) {
setupNotification()
}
}, REFRESH_REMINDER_PERIOD)
}
private fun getLaunchDialerIntent(): PendingIntent {
val intent = Intent(this, DialerActivity::class.java).apply {
action = RESUME_DIALER
putExtra(CALL_NUMBER, callNumber)
putExtra(CALL_STATUS, callStatus)
putExtra(IS_INCOMING_CALL, isIncomingCall)
}
return PendingIntent.getActivity(this, LAUNCH_DIALER_INTENT_ID, intent, PendingIntent.FLAG_UPDATE_CURRENT)
}
private fun getDeclineCallIntent(): PendingIntent {
Intent(this, DialerCallService::class.java).apply {
putExtra(DECLINE_CALL, true)
return PendingIntent.getService(this@DialerCallService, DISMISS_CALL_INTENT_ID, this, PendingIntent.FLAG_UPDATE_CURRENT)
}
}
private fun getAnswerCallIntent(): PendingIntent {
val intent = Intent(this, DialerActivity::class.java).apply {
action = RESUME_DIALER
putExtra(CALL_NUMBER, callNumber)
putExtra(CALL_STATUS, callStatus)
putExtra(IS_INCOMING_CALL, isIncomingCall)
putExtra(ANSWER_CALL, true)
}
return PendingIntent.getActivity(this, ANSWER_CALL_INTENT_ID, intent, PendingIntent.FLAG_UPDATE_CURRENT)
}
private fun getCallStatusString(): String {
val id = when (callStatus) {
Call.STATE_DIALING -> R.string.calling
Call.STATE_RINGING -> R.string.incoming_call
Call.STATE_ACTIVE -> R.string.ongoing_call
else -> if (isIncomingCall) R.string.incoming_call else R.string.calling
}
return applicationContext.getString(id)
}
}

View File

@ -1,76 +0,0 @@
package com.simplemobiletools.contacts.pro.services
import android.annotation.TargetApi
import android.app.KeyguardManager
import android.content.Context
import android.content.Intent
import android.net.Uri
import android.os.Build
import android.os.Bundle
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.helpers.*
import com.simplemobiletools.contacts.pro.objects.CallManager
@TargetApi(Build.VERSION_CODES.M)
class MyIncomingCallService : InCallService() {
override fun onCallAdded(call: Call) {
super.onCallAdded(call)
call.registerCallback(callCallback)
val handle = Uri.decode(call.details.handle.toString())
val callerNumber = if (handle.contains("tel:")) {
handle.substringAfter("tel:")
} else {
handle
}
val keyguardManager = getSystemService(Context.KEYGUARD_SERVICE) as KeyguardManager
if (keyguardManager.isKeyguardLocked) {
Intent(this, DialerActivity::class.java).apply {
action = RESUME_DIALER
flags = flags or Intent.FLAG_ACTIVITY_NEW_TASK
putExtra(CALL_NUMBER, callerNumber)
putExtra(CALL_STATUS, call.state)
putExtra(IS_INCOMING_CALL, true)
startActivity(this)
}
} else {
Intent(this, DialerCallService::class.java).apply {
putExtra(CALL_STATUS, call.state)
putExtra(CALL_NUMBER, callerNumber)
putExtra(IS_INCOMING_CALL, true)
startService(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)
if (state == Call.STATE_DISCONNECTED) {
Intent(applicationContext, DialerCallService::class.java).apply {
stopService(this)
}
}
}
}
private fun sendCallToActivity(call: Call) {
Intent(DIALER_INTENT_FILTER).apply {
putExtra(CALL_STATUS, call.state)
LocalBroadcastManager.getInstance(applicationContext).sendBroadcast(this)
}
}
}

View File

@ -1,18 +0,0 @@
package com.simplemobiletools.contacts.pro.services
import android.annotation.TargetApi
import android.net.Uri
import android.os.Build
import android.telecom.*
import com.simplemobiletools.contacts.pro.helpers.MyConnection
@TargetApi(Build.VERSION_CODES.M)
class MyOutgoingCallService : ConnectionService() {
override fun onCreateIncomingConnection(connectionManagerPhoneAccount: PhoneAccountHandle, request: ConnectionRequest): Connection {
val connection = MyConnection(applicationContext)
val phoneNumber = request.extras.get(TelecomManager.EXTRA_INCOMING_CALL_ADDRESS) as Uri
connection.setAddress(phoneNumber, TelecomManager.PRESENTATION_ALLOWED)
connection.setRinging()
return connection
}
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 408 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 507 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 722 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 929 B

View File

@ -1,9 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<shape
xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="oval">
<solid
android:color="@color/md_green_700"/>
</shape>

View File

@ -1,9 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<shape
xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="oval">
<solid
android:color="@color/theme_dark_red_primary_color"/>
</shape>

View File

@ -1,11 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<ripple
xmlns:android="http://schemas.android.com/apk/res/android"
android:color="@color/ripple_grey">
<item android:id="@android:id/mask">
<shape android:shape="rectangle">
<solid android:color="@color/ripple_grey"/>
</shape>
</item>
</ripple>

View File

@ -1,118 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/dialer_holder"
android:layout_width="match_parent"
android:layout_height="match_parent">
<com.simplemobiletools.commons.views.MyTextView
android:id="@+id/dialer_label"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/dialer_top_margin"
android:gravity="center_horizontal"
android:text="@string/calling"
android:textSize="@dimen/big_text_size"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"/>
<com.simplemobiletools.commons.views.MyTextView
android:id="@+id/dialer_label_dots"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center_horizontal"
android:textSize="@dimen/big_text_size"
app:layout_constraintBottom_toBottomOf="@+id/dialer_label"
app:layout_constraintStart_toEndOf="@+id/dialer_label"
app:layout_constraintTop_toTopOf="@+id/dialer_label"
tools:text="..."/>
<com.simplemobiletools.commons.views.MyTextView
android:id="@+id/dialer_big_name_number"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/medium_margin"
android:gravity="center_horizontal"
android:paddingLeft="@dimen/activity_margin"
android:paddingRight="@dimen/activity_margin"
android:textSize="@dimen/dialpad_text_size"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/dialer_label"
tools:text="John"/>
<com.simplemobiletools.commons.views.MyTextView
android:id="@+id/dialer_number"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/medium_margin"
android:gravity="center_horizontal"
android:paddingLeft="@dimen/activity_margin"
android:paddingRight="@dimen/activity_margin"
android:textSize="@dimen/big_text_size"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/dialer_big_name_number"
tools:text="123 456 789"/>
<com.simplemobiletools.commons.views.MyTextView
android:id="@+id/dialer_call_duration"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/medium_margin"
android:gravity="center_horizontal"
android:paddingLeft="@dimen/activity_margin"
android:paddingRight="@dimen/activity_margin"
android:textSize="@dimen/big_text_size"
android:visibility="gone"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/dialer_number"
tools:text="00:00"/>
<ImageView
android:id="@+id/dialer_hangup_button"
android:layout_width="@dimen/dialer_hangup_button_size"
android:layout_height="@dimen/dialer_hangup_button_size"
android:layout_marginBottom="@dimen/dialer_bottom_margin"
android:background="@drawable/circle_red_background"
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"/>
<ImageView
android:id="@+id/dialer_incoming_accept"
android:layout_width="@dimen/dialer_hangup_button_size"
android:layout_height="@dimen/dialer_hangup_button_size"
android:layout_marginBottom="@dimen/dialer_bottom_margin"
android:background="@drawable/circle_green_background"
android:elevation="@dimen/medium_margin"
android:padding="@dimen/activity_margin"
android:src="@drawable/ic_phone"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintStart_toEndOf="@+id/dialer_incoming_decline"/>
<ImageView
android:id="@+id/dialer_incoming_decline"
android:layout_width="@dimen/dialer_hangup_button_size"
android:layout_height="@dimen/dialer_hangup_button_size"
android:layout_marginBottom="@dimen/dialer_bottom_margin"
android:background="@drawable/circle_red_background"
android:elevation="@dimen/medium_margin"
android:padding="@dimen/activity_margin"
android:src="@drawable/ic_phone_down"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="@+id/dialer_incoming_accept"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintStart_toStartOf="parent"/>
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@ -1,55 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/call_notification_holder"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:id="@+id/incoming_call_caller"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/normal_margin"
android:paddingLeft="@dimen/activity_margin"
android:textSize="@dimen/bigger_text_size"
android:textStyle="bold"
tools:text="John"/>
<TextView
android:id="@+id/incoming_call_status"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@+id/incoming_call_caller"
android:layout_marginBottom="@dimen/small_margin"
android:paddingLeft="@dimen/activity_margin"
android:textSize="@dimen/normal_text_size"
tools:text="Incoming call"/>
<LinearLayout
android:id="@+id/call_notification_actions"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@+id/incoming_call_status"
android:orientation="horizontal">
<ImageView
android:id="@+id/call_decline"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:background="@drawable/ripple"
android:padding="@dimen/medium_margin"
android:src="@drawable/ic_phone_down"/>
<ImageView
android:id="@+id/call_answer"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:background="@drawable/ripple"
android:padding="@dimen/medium_margin"
android:src="@drawable/ic_phone"/>
</LinearLayout>
</RelativeLayout>

View File

@ -1,4 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<color name="ripple_grey">#55000000</color>
</resources>

View File

@ -7,9 +7,6 @@
<dimen name="contact_item_with_number_height">56dp</dimen>
<dimen name="create_new_contact_height">68dp</dimen>
<dimen name="dialpad_button_size">60dp</dimen>
<dimen name="dialer_hangup_button_size">70dp</dimen>
<dimen name="dialer_top_margin">140dp</dimen>
<dimen name="dialer_bottom_margin">40dp</dimen>
<dimen name="dialpad_text_size">34sp</dimen>
</resources>