Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Android Broadcast Receiver not working when the app is killed

Tags:

android

I am trying to display notification in an interval using Broadcast Receiver and timer to display. It works when the app is running but did not work when the app is killed.

Receiver looks like

public class MyReceiver  extends BroadcastReceiver {
    int j;
      public void onReceive(final Context context, Intent intent) {

        // Vibrate the mobile phone
        //Declare the timer
        Timer t = new Timer();

//Set the schedule function and rate
        t.schedule(new TimerTask() {

                       @Override
                       public void run() {
                           Log.d("ME", "Notification started");

                           NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(context);
                           mBuilder.setSmallIcon(R.drawable.ddc);
                           mBuilder.setContentTitle("My notification");
                           mBuilder.setDefaults(Notification.DEFAULT_SOUND);
                           mBuilder.setContentText("Hello World!");

                           NotificationManager mNotificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
                           mNotificationManager.notify(j++, mBuilder.build());

                       }

                   },
                0,
                30000);
    }
}

AndroidManifest.xml Looks like

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

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        <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>

        <receiver  android:name="MyReceiver"
            android:enabled="true"
            android:exported="true"
            >
            <intent-filter>
                <action android:name="com.background.myreceiver" />
                <action android:name="android.intent.action.PHONE_STATE" />
            </intent-filter>
        </receiver>
    </application>

</manifest>

It only displays notification in an interval when app is running. It is not displaying notification when the app is killed. What I am missing?

like image 367
Kabindra Simkhada Avatar asked Oct 17 '22 18:10

Kabindra Simkhada


1 Answers

"when the app is killed" is not a precise statement. I am going to guess that you mean "when you swipe away your app from the overview screen (a.k.a., recent-tasks list)".

Once onReceive() returns, if you do not have an activity in the foreground and you do not have a running service, your process importance will drop to what the documentation refers to as a "cached process". Your process is eligible to be terminated at any point. Once your process is terminated, your Timer goes away. Hence, your code as written will be unreliable, as your process might be terminated within your 30-second window.

Other possibilities include:

  • You are doing something else for "when the app is killed" that behaves like "Force Stop" does on your app's screen in Settings. Normally, that "Force Stop" button is the only way to force-stop an app, but occasionally device manufacturers do something stupid and make force-stop something that happens from other things (e.g., a device-supplied "application manager"). Once your app is force-stopped, your code will never run again, until the user launches your app from the home screen launcher icon or something else on the device uses an explicit Intent to start one of your components.

  • If the device falls asleep, your Timer will not be invoked until the device wakes up again.

like image 116
CommonsWare Avatar answered Oct 21 '22 06:10

CommonsWare