Question

I'm new to Android development. I am trying to develop a widget with a button that toggles whether the device automatically answers incoming calls.

I started by created a class that extends AppWidgetProvider. I'm using SharedPreferences to store the state of the widget button. In the OnReceive(Context, Intent) method, I am using an intent to start an IntentService that registers a BroadcastReceiver to listen for changes the phone state. However, I can't seem to figure out how to unregister the BroadcastReceiver when the widget has been toggled off -- my code continues to monitor the phone state no matter the state of the widget button. Is it possible? Or is there another way that I can stop the PhoneStateListener?

Thanks.

UPDATE: Here are the revisions to the code

Manifest: I put the BroadcastReceiver with the android.intent.action.PHONE_STATE intent-filter in the manifest

In the AppWidgetProvider:

ComponentName componentName = new ComponentName(context, PhoneStateBroadcastReceiver.class);

//use to enable the broadcast receiver
packageManager.setComponentEnabledSetting(componentName, 
                        PackageManager.COMPONENT_ENABLED_STATE_ENABLED, PackageManager.DONT_KILL_APP);

//use to disable the broadcast receiver
packageManager.setComponentEnabledSetting(componentName, 
                        PackageManager.COMPONENT_ENABLED_STATE_DISABLED, PackageManager.DONT_KILL_APP);

In the BroadcastReceiver:

@Override
public void onReceive(Context context, Intent intent) {

    //check call state
    TelephonyManager tm = (TelephonyManager)context.getSystemService(Context.TELEPHONY_SERVICE);
    if(tm.getCallState()==TelephonyManager.CALL_STATE_RINGING){
        try{

            //wait 2 seconds then answer the call
            Thread.sleep(2000);
            Class c = Class.forName(tm.getClass().getName());
            Method m = c.getDeclaredMethod("getITelephony");
            m.setAccessible(true);
            ITelephony telephony = (ITelephony)m.invoke(tm);
            telephony.silenceRinger();
            telephony.answerRingingCall();

        } catch(Exception e){}
    }

}

Don't need a PhoneStateListener...

Bummer that this won't work on 2.3+

Was it helpful?

Solution

I am using an intent to start an IntentService that registers a BroadcastReceiver to listen for changes the phone state

This will not work reliably, as once the IntentService exits, your process may terminate and your BroadcastReceiver will go away. Please put the phone state BroadcastReceiver in your manifest.

However, I can't seem to figure out how to unregister the BroadcastReceiver when the widget has been toggled off

Use PackageManager and setComponentEnabledSetting() to enable or disable the phone state receiver you place in the manifest.

Also, you cannot reliably do anything from a BroadcastReceiver that lives past onReceive(), such as register an event listener, as you are doing here.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top