Search code examples
androidandroid-broadcastreceiver

Receiver stops when force close


Hello I've made an app with a receiver to listen to incoming calls ,

My problem is that when i close (swipe off from list of apps) the receiver doesn't work anymore.

first thing i tried is the receiver itself defined in the android manifest like so:

<receiver
            android:name=".demo.CallReceiver"
            android:exported="true"
            android:enabled="true">
            <intent-filter android:priority="999">
                <action android:name="android.intent.action.PHONE_STATE"/>
            </intent-filter>
            <intent-filter android:priority="999">
                <action android:name="android.intent.action.NEW_OUTGOING_CALL" />

            </intent-filter>
        </receiver>

This works only when the app is open or in the background .

I looked online and saw this - https://stackoverflow.com/a/46889335/7079340 so i made a Service of my own like so (in the manifest):

<service android:name=".Service.CallService" android:enabled="true"
    android:exported="false"> <intent-filter>
    <action android:name="com.package.name.IRemoteConnection" />
</intent-filter>
</service>

and the class :

public class CallService extends Service {
    private static BroadcastReceiver m_Receiver;

    @Override
    public IBinder onBind(Intent arg0)
    {
        Log.e("SERVICELOG","bind");

        return null;
    }
    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        Log.e("SERVICELOG","start command");

        return START_STICKY;
    }

    @Override
    public void onCreate()
    {
        Log.e("SERVICELOG","create");

        Receiver();
    }

    @Override
    public void onDestroy()
    {
        Log.e("SERVICELOG","destroy");
        try{
            unregisterReceiver(m_Receiver);}catch (Exception e){
            Log.e("SERVICELOG"," "+e.getMessage());

        }

    }

    private void Receiver()
    {
        m_Receiver = new CallReceiver();
    }
}

Started it in the oncreate of my Splashscreen and it prints the logs and it works ! Any way to make this work without a service I'm afraid of battery issues and so on ? Thanks !


Solution

  • Android has had many changes from Marshmallow and above about apps that implicitly listener for broadcast in their manifest. The reasoning for this is because several apps would register for broadcast and a new process would be spun up for all the registered app's broadcast receiver to run in (very expensive) thus causing battery drain. What made this worse, was that users have no control over this behavior because the broadcast receiver couldn't be unregistered. To fix this, the engineering team behind Android, only allows for a select few broadcast to be implicitly registered. One is the Device Boot broadcast intent. By stopping apps from implicitly registering Broadcast's, apps have to be manually launched by the user to listen for intents they'd like to be notified of. This prevent several unnecessary apps from waking up to attempt to handle intent.

    As for your concern, about "battery issues" I would recommend to you to use the preferred pattern of explicitly registering a BroadcastReciever in your Service and just performance tune to get your code to be as performant as possible. Services are definitely not free, but they aren't automatically heavy objects just by having one started and running; plus they do exist for this exact purpose. Just remember to not do unnecessary work in your service and you should be off to the right start.