A memo when the incoming number acquisition using Broadcast Receiver does not work on Android 9/10

Getting the incoming number using BroadcastReceiver didn't work very well, so I'll write a solution.

: checkedered_flag: What you want to do

I want to get the number I received when I received a call.

: pencil2: Receiver to get the status of the phone

First, I searched and tried with the well-written code.

xml:Android.Manifest.xml


<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.callreceivetest">

    <uses-permission android:name="android.permission.READ_PHONE_STATE" />

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">

        <activity android:name=".MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>

    </application>

</manifest>

MainActivity.java


    TextView callinfo;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        callinfo=findViewById(R.id.callinfo);

        //Listener settings
        TelephonyManager telephonyManager = (TelephonyManager)getSystemService(TELEPHONY_SERVICE);
        telephonyManager.listen(mListener, PhoneStateListener.LISTEN_CALL_STATE);

    }

    PhoneStateListener mListener = new PhoneStateListener(){
        @Override
        public void onCallStateChanged(int state, String callNumber) {
            //Log.d(TAG, ":" + state+"-PhoneNumber:"+callNumber);
            switch(state){
                case TelephonyManager.CALL_STATE_IDLE:      //Standby (at the end)
                    Toast.makeText(MainActivity.this, "End call\nCALL_STATE_IDLE", Toast.LENGTH_SHORT).show();
                    break;
                case TelephonyManager.CALL_STATE_RINGING:   //Incoming call*
                    if(callNumber==null){
                        callNumber="";
                    }
                    Toast.makeText(MainActivity.this, "Incoming call\nCALL_STATE_RINGING: " + callNumber, Toast.LENGTH_SHORT).show();
                    callinfo.setText("Incoming call:"+callNumber);
                    break;
                case TelephonyManager.CALL_STATE_OFFHOOK:   //Call
                    Toast.makeText(MainActivity.this, "talking\nCALL_STATE_OFFHOOK", Toast.LENGTH_SHORT).show();
                    break;
            }
        }
    };

When I run this code on an Android 10 emulator, it looks like the image and I can get the phone status, but for some reason I can't get the phone number. 000035.png

: bulb: Cause of not being able to get the phone number

From Android 9/10 (API level 28 or higher), it seems that the permissions required to get a phone number using BroadcastReceiver have changed. Reference site: https://developer.android.com/about/versions/pie/android-9.0-changes-all?hl=ja#restrict-access-phone-numbers This time, we use onCallStateChanged () to get it, so we need ** READ_CALL_LOG (call history) permission in addition to READ_PHONE_STATE (phone) **.

However, the Android Developers site says "READ_PHONE_STATE permission is not required", but without READ_PHONE_STATE, it was not possible to get the phone number in Android 9 and earlier versions. (I actually checked it with an emulator) So, ** you need two permissions, READ_PHONE_STATE and READ_CALL_LOG, to support all versions **.

Revised

xml:Android.Manifest.xml


<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.callreceivetest">

    <uses-permission android:name="android.permission.READ_PHONE_STATE" />
    <uses-permission android:name="android.permission.READ_CALL_LOG"/>

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">

        <activity android:name=".MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>

    </application>

</manifest>

: iphone: Result of changing to "Call history" permission

I was able to get the phone number properly even on Android10! 000033.png

: chains: Reference site

Program: https://storyboard.jp/blog/android_telmanager/

If you want to get a status other than incoming call, in-call, or end of call, it is easy to understand by referring to here. https://qiita.com/syukai/items/d4911590a001d401a028

Recommended Posts

A memo when the incoming number acquisition using Broadcast Receiver does not work on Android 9/10
[Ruby on Rails] When parameter id acquisition does not work
When the form such as Select of Materialize does not work properly
Try using the service on Android Oreo
Does the escape sequence (\) not work? (for Mac)
A memo when fumbling and developing using JavaFX
When @Transactional of Spring Boot does not work
Does not recognize the library when implementing jcaptcha
[Railways] Railways does not work when the RubyMine project root is other than the Rails root directory.
A memo when building a Rails 5.2 development environment using Docker Desktop + WSL2 on Windows 10 Home
[Kotlin] The mapping library by reflection based on Java basically does not work with Kotlin.
[Android Studio] About the matter that the design view is not displayed when using TextClock
A memo when "I do not get a certificate error with a self-signed certificate using Java's Keytool"
"Do not show again" check does not work in the warning dialog when starting applet