0

I'm developing an app where the app has OTP phone call for setting the user pin. So what i'm going to is to set automaticly the phone number i got from phone call to textview. The problem is PhoneStateReceiver class which extend BroadcastReceiver not working on Pie but working on Oreo.

It's work perfectly fine on my Oreo phone but not with Pie phone, there is no error i got, except on Pie the onReceive at PhoneStateReceiver is not called.

public class PhoneStateReceiver extends BroadcastReceiver {

    @Override
    public void onReceive(Context context, Intent intent) {
        final String action = intent.getAction();

        if (action.equals(TelephonyManager.ACTION_PHONE_STATE_CHANGED)) {
            String state = intent.getStringExtra(TelephonyManager.EXTRA_STATE);
            String incomingNumber = intent.getStringExtra(TelephonyManager.EXTRA_INCOMING_NUMBER);

            if((state.equals(TelephonyManager.EXTRA_STATE_RINGING))){
                Toast.makeText(context,"Received State",Toast.LENGTH_SHORT).show();
            }

            if ((state.equals(TelephonyManager.EXTRA_STATE_OFFHOOK))){
                Intent local = new Intent();
                local.setAction("service.to.activity.transfer");
                local.setAction("android.intent.action.PHONE_STATE");
                local.setAction("android.intent.action.NEW_OUTGOING_CALL");
                local.putExtra("number", incomingNumber);
                context.sendBroadcast(local);

            }
            if (state.equals(TelephonyManager.EXTRA_STATE_IDLE)){
                Intent local = new Intent();
                local.setAction("service.to.activity.transfer");
                local.setAction("android.intent.action.PHONE_STATE");
                local.setAction("android.intent.action.NEW_OUTGOING_CALL");
                local.putExtra("number", incomingNumber);
                context.sendBroadcast(local);

            }
        }
    }

}

This is my Manifest.xml

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

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

    <application
        android:name=".modules.App"
        android:allowBackup="false"
        android:icon="@mipmap/ic_launcher_square"
        android:label="@string/app_name"
        android:networkSecurityConfig="@xml/network_security_config"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/AppTheme"
        tools:replace="android:allowBackup">

        <receiver android:name=".utils.phoneutil.PhoneStateReceiver">
            <intent-filter>

                <action android:name="android.intent.action.PHONE_STATE" />
            </intent-filter>

        </receiver>

    </application>

</manifest>

This is how i handle the register receiver on my Activity

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

        getNumberPhone();

    }

    public void getNumberPhone(){

        IntentFilter filter = new IntentFilter();
        filter.addAction("service.to.activity.transfer");
        BroadcastReceiver updateUIReciver = new BroadcastReceiver() {
            @Override
            public void onReceive(Context context, Intent intent) {

            //UI update here
            if (intent != null){
                String message = intent.getStringExtra("number");

                if(message != null){
                    if(message.length() == DIGITLENGTH){
                        String asubstring = message.substring(1, message.length());
                        pin1.setText(""+asubstring.charAt(0));
                        pin2.setText(""+asubstring.charAt(1));
                        pin3.setText(""+asubstring.charAt(2));
                        pin4.setText(""+asubstring.charAt(3));
                    }

                }
            }
            }
        };
        registerReceiver(updateUIReciver, filter);

    }

It's work perfectly fine on my Oreo phone but not with Pie phone, there is no error i got, except on Pie the onReceive at PhoneStateReceiver is not called. Please help me to fix this

  • Have you checked [this](https://developer.android.com/about/versions/pie/android-9.0-changes-all)? – Piyush Aug 22 '19 at 07:30

1 Answers1

0

Add READ_CALL_LOG permission in manifest as below and also take runtime permission:

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

As per Android doc:

Restricted access to call logs

Android 9 introduces the CALL_LOG permission group and moves the READ_CALL_LOG, WRITE_CALL_LOG, and PROCESS_OUTGOING_CALLS permissions into this group. In previous versions of Android, these permissions were located in the PHONE permission group.

Restricted access to phone numbers Apps running on Android 9 cannot read phone numbers or phone state without first acquiring the READ_CALL_LOG permission, in addition to the other permissions that your app's use cases require.

Phone numbers associated with incoming and outgoing calls are visible in the phone state broadcast, such as for incoming and outgoing calls and are accessible from the PhoneStateListener class. Without the READ_CALL_LOG permission, however, the phone number field that's provided in PHONE_STATE_CHANGED broadcasts and through PhoneStateListener is empty.

To read phone numbers from phone state, update your app to request the necessary permissions based on your use case:

To read numbers from the PHONE_STATE intent action, you need both the READ_CALL_LOG permission and the READ_PHONE_STATE permission. To read numbers from onCallStateChanged(), you need the READ_CALL_LOG permission only. You don't need the READ_PHONE_STATE permission.

Check full documentation here.

Kabir
  • 852
  • 7
  • 11
  • am i still need BroadcastReceiver if i'm using READ_CALL_LOG, or it's using different kind of method? because i'm trying use this method, but it's not working https://stackoverflow.com/a/21237242/7908440. Can you explain more using broadcastreceiver method or other method. Thank you :) – Natasya Angelia Aug 22 '19 at 08:22
  • READ_CALL_LOG permission,is just permission for security in android pie,you cant read phone state without this permission in pie version.if you take runtime permisssion and your code is properp,then you will get perfect result. – Kabir Aug 22 '19 at 09:07
  • Android doc mention:Phone numbers associated with incoming and outgoing calls are visible in the phone state broadcast, such as for incoming and outgoing calls and are accessible from the PhoneStateListener class. Without the READ_CALL_LOG permission, however, the phone number field that's provided in PHONE_STATE_CHANGED broadcasts and through PhoneStateListener is empty. – Kabir Aug 22 '19 at 09:08