Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to keep alive my BroadcastReceiver

Tags:

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..

like image 450
Ranjithkumar Avatar asked Apr 23 '16 19:04

Ranjithkumar


People also ask

What is the life cycle of BroadcastReceiver?

When a broadcast message arrives for the receiver, Android calls its onReceive() method and passes it the Intent object containing the message. The broadcast receiver is considered to be active only while it is executing this method. When onReceive() returns, it is inactive.

What is the life cycle of a BroadcastReceiver in Android?

A BroadcastReciever life cycle ends (ie stop receiving broadcast) when you unregister it. usually you would do this in the onPause/onStop method.

Does broadcast receiver work in background?

A broadcast receiver will always get notified of a broadcast, regardless of the status of your application. It doesn't matter if your application is currently running, in the background or not running at all.

How do I stop BroadcastReceiver?

To stop receiving broadcasts, call unregisterReceiver(android. content. BroadcastReceiver) . Be sure to unregister the receiver when you no longer need it or the context is no longer valid.


2 Answers

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.

like image 105
Suraj Avatar answered Sep 18 '22 21:09

Suraj


You need to create a Service and and register it in manifest. After it you should register your BroadcastReceiver inside the service instead of manifest.

A Service is not stopped, when app is removed from recents, so your receiver will also continue to work. You will even also get a callback via Service#onTaskRemoved when app is removed from recents.

Though you will also need to handle some other cases, when a Service can be stopped.

One case is when android can stop your service when system is low on memory, you can fix it by returning START_STICKY from your onStartCommand method.

Other case is when device is rebooted, you will need to register a broadcast receiver for ACTION_BOOT_COMPLETED in mnifest to fix this. You can restart your service in its onReceive method.

Hope below example code helps-

private BroadcastReceiver mReceiver;  @Override public int onStartCommand(Intent intent, int flags, int startId) {     mReceiver = new BroadcastReceiver() {         @Override         public void onReceive(Context context, Intent intent) {             Log.v(LOG_TAG, "worked");         }     };     registerReceiver(mReceiver,              new IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION));      return START_STICKY; }  @Override public void onDestroy() {     unregisterReceiver(mReceiver);     super.onDestroy() } 
like image 22
Sachin Gupta Avatar answered Sep 20 '22 21:09

Sachin Gupta