{"id":3891,"date":"2018-02-22T12:30:02","date_gmt":"2018-02-22T12:30:02","guid":{"rendered":"http:\/\/www.nikola-breznjak.com\/blog\/?p=3891"},"modified":"2018-02-22T12:31:28","modified_gmt":"2018-02-22T12:31:28","slug":"make-native-android-app-can-block-phone-calls","status":"publish","type":"post","link":"https:\/\/nikola-breznjak.com\/blog\/android\/make-native-android-app-can-block-phone-calls\/","title":{"rendered":"How to make a native Android app that can block phone calls"},"content":{"rendered":"<h2>TL;DR<\/h2>\n<p>In this post, I&#8217;ll show you step by step how to make a native Android app that can block certain numbers from calling you.<\/p>\n<p>The source code is <a href=\"https:\/\/github.com\/Hitman666\/AndroidCallBlockingTestDemo\">on Github<\/a>.<\/p>\n<p>I hope that my step by step guide that I&#8217;m going to show you here will help you and save you from doing additional research.<\/p>\n<p><em>Of course, since I&#8217;m not a native Android developer in my day to day job, I&#8217;m doing it also for the fact that it will serve me as a good reminder for when I need to deal with a similar situation again.<\/em> Shout out to the rest of you #jackOfAllTrades out there ?<\/p>\n<p>Also, given the statement above; I would appreciate any feedback regarding this code. ?<\/p>\n<h2>!TL;DR<\/h2>\n<p>I&#8217;ve spent a lot of time going through StackOverflow and blog posts in search of this solution. Of all of those, these were helpful:<\/p>\n<ul>\n<li><a href=\"https:\/\/stackoverflow.com\/questions\/15563921\/how-to-detect-incoming-calls-in-an-android-device\/15564021\">How to detect incoming calls on an Android device?<br \/>\n<\/a><\/li>\n<li><a href=\"https:\/\/stackoverflow.com\/questions\/42339534\/cant-answer-incoming-call-in-android-marshmallow-6-0\">Can&#8217;t answer incoming call in android marshmallow 6.0<br \/>\n<\/a><\/li>\n<li><a href=\"https:\/\/stackoverflow.com\/questions\/32635704\/android-permission-doesnt-work-even-if-i-have-declared-it\">Android permission doesn&#8217;t work even if I have declared it<br \/>\n<\/a><\/li>\n<li><a href=\"https:\/\/stackoverflow.com\/questions\/20965702\/end-incoming-call-programmatically\">End incoming call programmatically<br \/>\n<\/a><\/li>\n<li><a href=\"http:\/\/gabesechansoftware.com\/is-the-phone-ringing\/\">Is the phone ringing<\/a><\/li>\n<\/ul>\n<p>But sadly, none of them was straightforward, beginner kind of tutorial. So, after a lot of additional research, I made it work, and here&#8217;s my best attempt at explaining how.<\/p>\n<blockquote><p>\n  As a sidenote: while testing this, the discovery of <a href=\"http:\/\/www.nikola-breznjak.com\/blog\/android\/simulate-incoming-call-sms-emulator-android-studio\/\">how to simulate an incoming call or SMS to an emulator in Android Studio<\/a> was also very helpful.\n<\/p><\/blockquote>\n<h3>Starting a new project<\/h3>\n<p>In Android Studio go to <code>File-&gt;New-&gt;New Project<\/code>, give it a name and a location and click <code>Next<\/code>:<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/i.imgur.com\/4iyIDSJ.png\" alt=\"\" \/><\/p>\n<p>Leave the default option for minimum API level:<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/i.imgur.com\/wBim1w2.png\" alt=\"\" \/><\/p>\n<p>Select an <code>Empty Activity<\/code> template:<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/i.imgur.com\/eLo7Sia.png\" alt=\"\" \/><\/p>\n<p>Leave the name of the activity as is:<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/i.imgur.com\/8M3pwcQ.png\" alt=\"\" \/><\/p>\n<h3>AndroidManifest.xml<\/h3>\n<p>Set the permissions (two <code>uses-permission<\/code> tags) and the <code>receiver<\/code> tags in <code>AndroidManifest.xml<\/code> file:<\/p>\n<pre><code>&lt;?xml version=\"1.0\" encoding=\"utf-8\"?&gt;\n&lt;manifest xmlns:android=\"http:\/\/schemas.android.com\/apk\/res\/android\"\n    package=\"com.example.nikola.callblockingtestdemo\"&gt;\n\n    &lt;uses-permission android:name=\"android.permission.READ_PHONE_STATE\" \/&gt;\n    &lt;uses-permission android:name=\"android.permission.CALL_PHONE\" \/&gt;\n\n    &lt;application\n        android:allowBackup=\"true\"\n        android:icon=\"@mipmap\/ic_launcher\"\n        android:label=\"@string\/app_name\"\n        android:roundIcon=\"@mipmap\/ic_launcher_round\"\n        android:supportsRtl=\"true\"\n        android:theme=\"@style\/AppTheme\"&gt;\n        &lt;activity android:name=\".MainActivity\"&gt;\n            &lt;intent-filter&gt;\n                &lt;action android:name=\"android.intent.action.MAIN\" \/&gt;\n\n                &lt;category android:name=\"android.intent.category.LAUNCHER\" \/&gt;\n            &lt;\/intent-filter&gt;\n        &lt;\/activity&gt;\n\n        &lt;receiver  android:name=\".IncomingCallReceiver\" android:enabled=\"true\" android:exported=\"true\"&gt;\n            &lt;intent-filter&gt;\n                &lt;action android:name=\"android.intent.action.PHONE_STATE\" \/&gt;\n            &lt;\/intent-filter&gt;\n        &lt;\/receiver&gt;\n    &lt;\/application&gt;\n&lt;\/manifest&gt;\n<\/code><\/pre>\n<p>With the <code>READ_PHONE_STATE<\/code> permission we get this (as defined in <a href=\"https:\/\/developer.android.com\/reference\/android\/Manifest.permission.html#READ_PHONE_STATE\">official docs<\/a>):<\/p>\n<blockquote><p>\n  Allows read-only access to phone state, including the phone number of the device, current cellular network information, the status of any ongoing calls, and a list of any PhoneAccounts registered on the device.\n<\/p><\/blockquote>\n<p>With the <code>CALL_PHONE<\/code> permission we get this (as defined in <a href=\"https:\/\/developer.android.com\/reference\/android\/Manifest.permission.html#CALL_PHONE\">official docs<\/a>):<\/p>\n<blockquote><p>\n  Allows an application to initiate a phone call without going through the Dialer user interface for the user to confirm the call.\n<\/p><\/blockquote>\n<p>\u26a0\ufe0f I found that even though not stated here, I need this permission so that I can end the call programmatically.<\/p>\n<p>The <code>receiver<\/code> tag is used to define a class that will handle the broadcast action of <code>android.intent.action.PHONE_STATE<\/code>. Android OS will broadcast this action when, as the name implies, the state of the phone call changes (we get a call, decline a call, are on the call, etc.).<\/p>\n<h3>IncomingCallReceiver.java<\/h3>\n<p>Create a new class (<code>File-&gt;New-&gt;Java Class<\/code>), call it <code>IncomingCallReceiver<\/code> and paste this code in (<em>note: your <code>package<\/code> name will be different than mine!<\/em>):<\/p>\n<pre><code>package com.example.nikola.callblockingtestdemo;\n\nimport android.content.BroadcastReceiver;\nimport android.content.Context;\nimport android.content.Intent;\nimport android.telephony.TelephonyManager;\nimport android.widget.Toast;\nimport java.lang.reflect.Method;\nimport com.android.internal.telephony.ITelephony;\n\npublic class IncomingCallReceiver extends BroadcastReceiver {\n    @Override\n    public void onReceive(Context context, Intent intent) {\n\n        ITelephony telephonyService;\n        try {\n            String state = intent.getStringExtra(TelephonyManager.EXTRA_STATE);\n            String number = intent.getExtras().getString(TelephonyManager.EXTRA_INCOMING_NUMBER);\n\n            if(state.equalsIgnoreCase(TelephonyManager.EXTRA_STATE_RINGING)){\n                TelephonyManager tm = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);\n                try {\n                    Method m = tm.getClass().getDeclaredMethod(\"getITelephony\");\n\n                    m.setAccessible(true);\n                    telephonyService = (ITelephony) m.invoke(tm);\n\n                    if ((number != null)) {\n                        telephonyService.endCall();\n                        Toast.makeText(context, \"Ending the call from: \" + number, Toast.LENGTH_SHORT).show();\n                    }\n\n                } catch (Exception e) {\n                    e.printStackTrace();\n                }\n\n                Toast.makeText(context, \"Ring \" + number, Toast.LENGTH_SHORT).show();\n\n            }\n            if(state.equalsIgnoreCase(TelephonyManager.EXTRA_STATE_OFFHOOK)){\n                Toast.makeText(context, \"Answered \" + number, Toast.LENGTH_SHORT).show();\n            }\n            if(state.equalsIgnoreCase(TelephonyManager.EXTRA_STATE_IDLE)){\n                Toast.makeText(context, \"Idle \"+ number, Toast.LENGTH_SHORT).show();\n            }\n        } catch (Exception e) {\n            e.printStackTrace();\n        }\n    }\n}\n<\/code><\/pre>\n<p>In Android, if we want to &#8216;get&#8217; the data from the <code>BroadcastReceiver<\/code>, we need to inherit the <code>BroadcastReceiver<\/code> class, and we need to override the <code>onReceive<\/code> method. In this method, we&#8217;re using the <code>TelephonyManager<\/code> to get the state of the call, and we&#8217;re using the <code>ITelephony<\/code> interface to end the call.<\/p>\n<p>To be honest, this is where it gets a bit &#8216;weird&#8217;, as to get this <code>ITelephony<\/code> interface, you need to create the <code>ITelephony<\/code> interface.<\/p>\n<h3>ITelephony.java<\/h3>\n<p>To do that, create a new class (<code>File-&gt;New-&gt;Java Class<\/code>), call it <code>ITelephony<\/code> and paste this code in (<em>note: overwrite everything with the below content; yes, even the weird package name<\/em>):<\/p>\n<pre><code>package com.android.internal.telephony;\n\npublic interface ITelephony {\n    boolean endCall();\n    void answerRingingCall();\n    void silenceRinger();\n}\n<\/code><\/pre>\n<p>Android Studio will complain about <code>package com.android.internal.telephony;<\/code> (red squiggly dots under this package name), but that&#8217;s how it has to be set for this to work. I didn&#8217;t find the exact explanation why this has to be included, so if you know, please share it in the comments.<\/p>\n<h3>Requesting permissions at runtime<\/h3>\n<p>This was one thing that was hindering my success in getting this to work!<\/p>\n<p>Namely, after Android 6.0+, even if you have permissions set in the <code>AndroidManifest.xml<\/code> file, you still have to explicitly ask the user for them if they fall under the category of <strong>dangerous<\/strong> permissions. This is the list of such permissions:<\/p>\n<ul>\n<li>ACCESS_COARSE_LOCATION<\/li>\n<li>ACCESS_FINE_LOCATION<\/li>\n<li>ADD_VOICEMAIL<\/li>\n<li>BODY_SENSORS<\/li>\n<li>CALL_PHONE<\/li>\n<li>CAMERA<\/li>\n<li>GET_ACCOUNTS<\/li>\n<li>PROCESS_OUTGOING_CALLS<\/li>\n<li>READ_CALENDAR<\/li>\n<li>READ_CALL_LOG<\/li>\n<li>READ_CELL_BROADCASTS<\/li>\n<li>READ_CONTACTS<\/li>\n<li>READ_EXTERNAL_STORAGE<\/li>\n<li>READ_PHONE_STATE<\/li>\n<li>READ_SMS<\/li>\n<li>RECEIVE_MMS<\/li>\n<li>RECEIVE_SMS<\/li>\n<li>RECEIVE_WAP_PUSH<\/li>\n<li>RECORD_AUDIO<\/li>\n<li>SEND_SMS<\/li>\n<li>USE_SIP<\/li>\n<li>WRITE_CALENDAR<\/li>\n<li>WRITE_CALL_LOG<\/li>\n<li>WRITE_CONTACTS<\/li>\n<li>WRITE_EXTERNAL_STORAGE<\/li>\n<\/ul>\n<p>To ask for such permissions here&#8217;s the code you can use (I used it in <code>MainActivity.java<\/code> in the <code>onCreate<\/code> method):<\/p>\n<pre><code>if (android.os.Build.VERSION.SDK_INT &gt;= android.os.Build.VERSION_CODES.M) {\n    if (checkSelfPermission(Manifest.permission.READ_PHONE_STATE) == PackageManager.PERMISSION_DENIED || checkSelfPermission(Manifest.permission.CALL_PHONE) == PackageManager.PERMISSION_DENIED) {\n        String[] permissions = {Manifest.permission.READ_PHONE_STATE, Manifest.permission.CALL_PHONE};\n        requestPermissions(permissions, PERMISSION_REQUEST_READ_PHONE_STATE);\n    }\n}\n<\/code><\/pre>\n<p>The <code>PERMISSION_REQUEST_READ_PHONE_STATE<\/code> variable is used to determine which permission was asked for in the <code>onRequestPermissionsResult<\/code> method. Of course, if you don&#8217;t need to execute any logic depending on whether or not the user approved the permission, you can leave out this method:<\/p>\n<pre><code>@Override\npublic void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) {\n    switch (requestCode) {\n        case PERMISSION_REQUEST_READ_PHONE_STATE: {\n            if (grantResults.length &gt; 0 &amp;&amp; grantResults[0] == PackageManager.PERMISSION_GRANTED) {\n                Toast.makeText(this, \"Permission granted: \" + PERMISSION_REQUEST_READ_PHONE_STATE, Toast.LENGTH_SHORT).show();\n            } else {\n                Toast.makeText(this, \"Permission NOT granted: \" + PERMISSION_REQUEST_READ_PHONE_STATE, Toast.LENGTH_SHORT).show();\n            }\n\n            return;\n        }\n    }\n}\n<\/code><\/pre>\n<h3>App in action<\/h3>\n<p>This is how the app looks like in action, tested on the emulator and call triggered by using <a href=\"http:\/\/www.nikola-breznjak.com\/blog\/android\/simulate-incoming-call-sms-emulator-android-studio\/\">Android Device Monitor<\/a> in Android Studio:<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/i.imgur.com\/CjU9D4J.gif\" alt=\"\" \/><\/p>\n<h2>Conclusion<\/h2>\n<p>In this post, I showed you how to make a native Android app that can block certain numbers from calling you. I pointed out the blocker that I was facing, and I&#8217;m still searching a solution to hide a native incoming call popup that still sometimes shows up for a brief second before the call gets rejected.<\/p>\n<p>So, if you have any ideas, I&#8217;m open to suggestions ?<\/p>\n<blockquote class=\"twitter-tweet\" data-width=\"550\">\n<p lang=\"en\" dir=\"ltr\">How to make a <a href=\"https:\/\/twitter.com\/hashtag\/native?src=hash&amp;ref_src=twsrc%5Etfw\">#native<\/a> <a href=\"https:\/\/twitter.com\/hashtag\/Android?src=hash&amp;ref_src=twsrc%5Etfw\">#Android<\/a> app that can <a href=\"https:\/\/twitter.com\/hashtag\/block?src=hash&amp;ref_src=twsrc%5Etfw\">#block<\/a> phone <a href=\"https:\/\/twitter.com\/hashtag\/calls?src=hash&amp;ref_src=twsrc%5Etfw\">#calls<\/a> <a href=\"https:\/\/t.co\/NMYvOFlPO8\">https:\/\/t.co\/NMYvOFlPO8<\/a><\/p>\n<p>&mdash; Nikola Bre\u017enjak (@HitmanHR) <a href=\"https:\/\/twitter.com\/HitmanHR\/status\/966651485764444160?ref_src=twsrc%5Etfw\">February 22, 2018<\/a><\/p><\/blockquote>\n<p><script async src=\"https:\/\/platform.twitter.com\/widgets.js\" charset=\"utf-8\"><\/script><\/p>\n","protected":false},"excerpt":{"rendered":"<p>TL;DR In this post, I&#8217;ll show you step by step how to make a native Android app that can block certain numbers from calling you. The source code&hellip;<\/p>\n","protected":false},"author":1,"featured_media":3892,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[57],"tags":[],"class_list":["post-3891","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-android"],"_links":{"self":[{"href":"https:\/\/nikola-breznjak.com\/blog\/wp-json\/wp\/v2\/posts\/3891","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/nikola-breznjak.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/nikola-breznjak.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/nikola-breznjak.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/nikola-breznjak.com\/blog\/wp-json\/wp\/v2\/comments?post=3891"}],"version-history":[{"count":2,"href":"https:\/\/nikola-breznjak.com\/blog\/wp-json\/wp\/v2\/posts\/3891\/revisions"}],"predecessor-version":[{"id":3894,"href":"https:\/\/nikola-breznjak.com\/blog\/wp-json\/wp\/v2\/posts\/3891\/revisions\/3894"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/nikola-breznjak.com\/blog\/wp-json\/wp\/v2\/media\/3892"}],"wp:attachment":[{"href":"https:\/\/nikola-breznjak.com\/blog\/wp-json\/wp\/v2\/media?parent=3891"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/nikola-breznjak.com\/blog\/wp-json\/wp\/v2\/categories?post=3891"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/nikola-breznjak.com\/blog\/wp-json\/wp\/v2\/tags?post=3891"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}