Becoming the CallScreeningService on API >= 24

537 views Asked by At

I want to become the CallScreeningService on API >= 24. This should be doable as the function was implemented in 24, however the recommended usage in the docs uses RoleManager (which is implemented in 29).

I tried using the methods here and here however I cannot seem to set up my custom service class or my MainActivity.java. I try to run the service, which either fails and does nothing or crashes my app. I am still novice to Android app development (but moderately experienced with Java), so beginner friendly replies are appreciated. I did get the method in the developer.android docs to work, however it again uses >=29.

What should I write to set up my custom screening service class and MainActivity.java (at least just for onCreate())? This is what I have so far:

Manifest

        <service android:name="com.example.myapp.MyCallScreeningService"
            android:permission="android.permission.BIND_SCREENING_SERVICE">
            <intent-filter>
                <action android:name="android.telecom.CallScreeningService"/>
            </intent-filter>
        </service>

MyCallScreeningService.java

public class MyCallScreeningService extends CallScreeningService {
    @Override
    public void onScreenCall(Call.Details details) {
            CallResponse.Builder response = new CallResponse.Builder();
            response.setDisallowCall(false);
            response.setRejectCall(false);
            response.setSkipCallLog(false);
            response.setSkipNotification(false);
            respondToCall(details, response.build());
    }
}

If you choose to post code or code resources, please do so in Java. I am not familiar with Kotlin.

Edit: Adding this:

public class MyCallScreeningService extends CallScreeningService {
                              .
                              .
                              .

    private MyCallScreeningBinder mCallScreeningBinder = new 
    MyCallScreeningBinder();
    private IBinder iBinder = new MyCallScreeningBinder();

    public class MyCallScreeningBinder extends Binder {
        MyCallScreeningService getService() {
            return MyCallScreeningService.this;
        }
    }
                              .
                              .
                              .

and (in my MainActivity):

    MyCallScreeningService mCallScreeningService;
    boolean bound = false;

    ServiceConnection mServiceConnection = new ServiceConnection() {
        @Override
      //line 20 below
        public void onServiceConnected(ComponentName name, IBinder service) {
      //line 20 above
            MyCallScreeningService.MyCallScreeningBinder callScreeningBinder = (MyCallScreeningService.MyCallScreeningBinder)service;
            mCallScreeningService = callScreeningBinder.getService();
            bound = true;
        }

        @Override
        public void onServiceDisconnected(ComponentName name) {
            bound = false;
        }
    };

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        
        Intent intent = new Intent(this,MyCallScreeningService.class);
        bindService(intent, mServiceConnection, Context.BIND_AUTO_CREATE);

    }

yields the following exception

java.lang.ClassCastException: android.telecom.CallScreeningService$CallScreeningBinder cannot be cast to com.example.myapp.MyCallScreeningService$MyCallScreeningBinder

at com.example.callscreen.MainActivity$1.onServiceConnected(MainActivity.java:20)

MainActivity.java line 20 is indicated by comment blocks in the last code block. I am not sure how the compiler pulls the Android system CallScreeningBinder from my MyCallScreeningService class. I feel like if I can fix this (ie. make my onServiceConnected recognize my MyCallScreeningBinder), I will have my the service bind correctly, however I am not sure how to do this.

1

There are 1 answers

0
LM_IT On

Before 29 you cannot without implementing a full dialer app, from 29 you don't need to use neither Intent or bindservice just what you already added in your Manifest plus the rolerequest RoleManager.ROLE_CALL_SCREENING (Beware that if you have an Eventbus importing RoleManager can crash it in .register for api < 29. Is avoidable by putting .register in an inner class of main class) here's a very similar question, hope it helps!