Skip to content

Instantly share code, notes, and snippets.

@damien5314
Last active April 11, 2018 16:41
Show Gist options
  • Select an option

  • Save damien5314/414032ad7cefac469ef7d0e98a49a282 to your computer and use it in GitHub Desktop.

Select an option

Save damien5314/414032ad7cefac469ef7d0e98a49a282 to your computer and use it in GitHub Desktop.
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
package="ddiehl.no215">
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission android:name="android.permission.CALL_PHONE" />
<uses-permission
android:name="android.permission.MODIFY_PHONE_STATE"
tools:ignore="ProtectedPermissions" />
<application
android:name=".No215App"
android:allowBackup="true"
android:label="@string/app_name"
android:supportsRtl="true"
android:theme="@style/AppTheme"
tools:ignore="AllowBackup,GoogleAppIndexingWarning,MissingApplicationIcon">
<activity android:name=".ui.BlockConfigurationActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<receiver android:name=".call.PhoneCallInterceptor" >
<intent-filter>
<action android:name="android.intent.action.PHONE_STATE" />
</intent-filter>
</receiver>
</application>
</manifest>
package ddiehl.no215.call
import android.content.BroadcastReceiver
import android.content.Context
import android.content.Intent
import android.telephony.PhoneStateListener
import android.telephony.TelephonyManager
import ddiehl.no215.config.BlockConfigurationManager
import timber.log.Timber
/**
* Intercepts phone calls and forwards them to a [PhoneCallHandler].
* Aborts the broadcast if handler returns true.
*/
class PhoneCallInterceptor : BroadcastReceiver() {
override fun onReceive(context: Context, intent: Intent) {
val intentAction = intent.action
if (intentAction != null && intentAction != "") {
//TODO Call getAction and confirm the action matches the expected value
}
try {
val telephony = context.getSystemService(Context.TELEPHONY_SERVICE) as TelephonyManager
val handler = PhoneCallHandler.Impl(
configuration = BlockConfigurationManager.SharedPreferencesImpl(context),
terminator = PhoneCallTerminator.Impl(context),
tracker = BlockedNumberTracker.Impl(context)
)
val phoneListener = MyPhoneStateListener(telephony, handler)
telephony.listen(phoneListener, PhoneStateListener.LISTEN_CALL_STATE)
} catch (e: Exception) {
Timber.e(e)
}
}
private class MyPhoneStateListener(
private val telephonyManager: TelephonyManager,
private val phoneCallHandler: PhoneCallHandler
) : PhoneStateListener() {
override fun onCallStateChanged(state: Int, incomingNumber: String) {
// Make sure to unlisten so we don't get duplicates later
telephonyManager.listen(this, PhoneStateListener.LISTEN_NONE)
if (state == TelephonyManager.CALL_STATE_RINGING) {
phoneCallHandler.handle(incomingNumber)
}
}
}
}
package ddiehl.no215.call
import android.content.Context
import android.telephony.TelephonyManager
import timber.log.Timber
/**
* Responsible for terminating an incoming phone call.
*/
interface PhoneCallTerminator {
fun terminateCall(incomingNumber: String)
/**
* Terminates phone call by calling into the [com.android.internal.telephony.ITelephony] API.
*/
class Impl(context: Context) : PhoneCallTerminator {
private val appContext = context.applicationContext
override fun terminateCall(incomingNumber: String) {
try {
val telephonyManager = appContext.getSystemService(Context.TELEPHONY_SERVICE) as TelephonyManager
val telephonyManagerClass = Class.forName(telephonyManager.javaClass.name)
val getITelephonyMethod = telephonyManagerClass.getDeclaredMethod("getITelephony")
getITelephonyMethod.isAccessible = true
val telephonyService = getITelephonyMethod.invoke(telephonyManager)
val telephonyServiceClass = Class.forName(telephonyService.javaClass.name)
val endCallMethod = telephonyServiceClass.getDeclaredMethod("endCall")
endCallMethod.isAccessible = true
endCallMethod.invoke(telephonyService)
} catch (e: Exception) {
Timber.e(e)
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment