Search code examples
androidbroadcastreceiverandroid-serviceandroid-broadcastreceiver

How to keep alive my BroadcastReceiver


Currently I'm developing a call blocker application like Truecaller.

What I needed

I want to detect the incoming calls even my app is removed from the recent apps list.

Manifest.xml code

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

My broadcast receiver code

@Override
public void onReceive(Context context, Intent intent) {
  //my call blocking code
}

My problem

My BroadcastReceiver wont work in the background as if I removed from the recent apps list.

My full manifest code here

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

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

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

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

<application
    android:allowBackup="true"
    android:enabled="true"
    android:icon="@mipmap/ic_launcher"
    android:label="@string/app_name"
    android:supportsRtl="true"
    android:theme="@style/AppTheme">
    <receiver
        android:name=".PhoneStateReceiver"
        android:enabled="true"
        android:exported="true"
        android:process=":anotherProcess">
        <intent-filter android:priority="1000">
            <action android:name="android.intent.action.PHONE_STATE" />
        </intent-filter>
    </receiver>
    <activity
        android:name=".MainActivity"
        android:label="@string/app_name"
        android:theme="@style/AppTheme.NoActionBar">
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />

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

</manifest>

Should I use service or anything else?

Update:

With Suraj answer I tried this tags in my receiver

    android:enabled="true"
    android:exported="true"
    android:process=":anotherProcess"

it works on kitkat.. but not works on lollipop..

Updated question:

Incase If not possible to keep alive broadcast receiver How can I detect incoming calls even my app is closed?

anybody give detailed answer..


Solution

  • Here we are notifying receiver from service.

    So make a service class as

        public class MyService extends Service {
        @Nullable
        @Override
        public IBinder onBind(Intent intent) {
            return null;
        }
    
        @Override
        public int onStartCommand(Intent intent, int flags, int startId) {
            new CountDownTimer(100000,4000)
            {
                @Override
                public void onTick(long millisUntilFinished) {
                    sendBroadcast(new Intent("fromservice"));
    
                }
    
                @Override
                public void onFinish() {
    
                }
            }.start();
            return START_STICKY;
        }
    }
    

    Now make a receiver as

        public class MyReceiver extends WakefulBroadcastReceiver {
            @Override
            public void onReceive(final Context context, Intent intent) {
    
                Toast.makeText(context, "inside receiver", Toast.LENGTH_SHORT).show();
            }
        }
    

    now start the service from main activity

        public class MainActivity extends AppCompatActivity {
    
            @Override
            protected void onCreate(Bundle savedInstanceState) {
                super.onCreate(savedInstanceState);
                setContentView(R.layout.activity_main);
                startService(new Intent(this,MyService.class));
    
            }
        }
    

    Declare receiver and service in manifest as follows

     <receiver android:name=".MyReceiver"
            android:process=":jk"
            android:enabled="true"
            android:exported="true">
            <intent-filter>
                <action android:name="fromservice"/>
            </intent-filter>
        </receiver>
        <service android:name=".MyService"
    android:process=":ff"
    android:enabled="true"
    android:exported="true" />
    

    Add the following permission to your manifest. This is used for preventing cpu to sleep.

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

    What is count down timer ?

    Count down timer can be understood like a iteration which has to methods

    onTick() and onFinish()

    onTick() is called many times after an interval (time duration) as given in CountDownTimer constructor.

    onFinish() is called at last(only once) when the longTimeInFuture has aarived.