1

I am new to this part of android, and here I aim to use alarm manager to run a code snippet every 2 minute which will poll a server (using the website's api) and based on the returned JSON generate notification. After a looking up the web I thought one of the best option in my case will be using intent service and android.

Manifest of Services and Recievers

<service
    android:name=".NotifyService"
    android:enabled="true"
    android:exported="false" >
</service>
<receiver
    android:name=".TheReceiver"
    android:enabled="true"
    android:exported="true" >
</receiver>
<receiver
    android:name=".OnOffReceiver"
    android:enabled="true"
    android:exported="true" >
    <intent-filter>
        <action android:name="android.intent.action.BOOT_COMPLETED"/>
    </intent-filter>
</receiver>

Part in the flash screen activity where I call the intent service which is responsible for polling for notification:

Intent msgIntent = new Intent(this, NotifyService.class);
    startService(msgIntent);

The receiver to start the alarm on device start:

public class OnOffReceiver extends BroadcastReceiver
{
    private AlarmManager alarmMgr;
    private PendingIntent alarmIntent;
    public OnOffReceiver(){}
    @Override
    public void onReceive(Context context, Intent intent)
    {
        Intent service = new Intent(context, NotifyService.class);
        service.setAction(NotifyService.CREATE);
        context.startService(service);
    }
} 

The IntentService Class

public class NotifyService extends IntentService
{
    public NotifyService()
    {
        super("NotifyService");
    }
    public static final int STATUS_RUNNING = 0;
    public static final int STATUS_FINISHED = 1;
    public static final int STATUS_ERROR = 2;

    @Override
    protected void onHandleIntent(Intent intent)
    {
        if (intent != null)
        {
            final String action = intent.getAction();
        }
        StartStuff();
    }

    public void StartStuff()
    {
        Intent intent = new Intent(this, TheReceiver.class);
        PendingIntent pend_intent = PendingIntent.getBroadcast(this, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
        AlarmManager alarmManager = (AlarmManager) getSystemService(ALARM_SERVICE);
        alarmManager.setInexactRepeating(AlarmManager.ELAPSED_REALTIME_WAKEUP,1200,1200, pend_intent); 
     //1200ms to make it easier to test
    }

}

The receiver class which sets notification, for testing pupose I am not doing any network related work here just making a simple notification to check if the app is running in all situations

public class TheReceiver extends BroadcastReceiver
{
    public TheReceiver(){}
    @Override
    public void onReceive(Context context, Intent intent)
    {
         Toast.makeText(context, " Success ", Toast.LENGTH_SHORT).show();
         Log.d("Notification", "The Receiver Successful");
        showNotification(context);

    }
    private void showNotification(Context context)
    {         
        NotificationCompat.Builder mBuilder =
            new NotificationCompat.Builder(context).setContentTitle("My notification").setContentText("Hello World!");
        mBuilder.setDefaults(Notification.DEFAULT_SOUND);
        mBuilder.setAutoCancel(true);
        NotificationManager mNotificationManager =
            (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
        mNotificationManager.notify(1, mBuilder.build());

    }  
} 

However the notification come only when the app is running or in the recent apps tray. It does not start notifying when the phone reboots, nor does it notify after the app is removes from the recent apps tray.

The app needs Notify users like other apps (like gmail, whatsapp) do, even if they are swiped out of the recent apps tray. Timeliness and punctuality are not very big issue as delay up to 5 to 10 minutes are tolerable. (I intend to poll ever 2 minutes though.)

Where am I going wrong? Also, is there a better way to go about the problem?

sky
  • 81
  • 1
  • 6

2 Answers2

7

To keep a receiver active after closing the app is to use

android:process=":remote"

in the manifest file for the receiver that needs to be kept alive.

 <receiver
        android:name=".TheAlarmReceiver"
        android:process=":remote">
 </receiver>

in the manifest for the receiver (TheReceiver in this case) that we need to keep active after the app closes.

P.S. : I also changed the way I use IntentsService and AlarmManager for the application, as my previous(above) implementation is not a very good way to go around it.

sky
  • 81
  • 1
  • 6
  • is it working now? If you swipe off the app, does you Broadcast Receiver get called? – n.arrow001 Sep 29 '15 at 05:58
  • Yes. In the current implementation the FlashScreen sets alarm. Then (after every time the alarm sets off) the broadcast receiver (onReceive) executes the IntentService , and all the remaining work is done there. All Logs from the Intent Service continue even after the app is removed from the recent apps, or the device is sleeping. – sky Sep 29 '15 at 06:30
  • This is not working my case. I have followed All the steps. – Maaz Patel Mar 10 '17 at 06:25
1

If an App is killed from recent apps or from "force stop" it won't restart by itself. The user has to start the app again in order to make it run again. There is no way to prevent this. It's just the way android works.

However there is a way to make your app run oon boot. Check out this link.

Community
  • 1
  • 1
Robin Dijkhof
  • 18,665
  • 11
  • 65
  • 116
  • but then how do apps like gmail or the weather app perform the same feature ? Also the boot link didn't give the desired result. Should I be trying a different approach ? – sky Sep 27 '15 at 20:25
  • They don't perform the same feature. Try to remove WhatsApp from the recent app list. You will see you won't receive messages without restarting the app or reboot your phone. The boot link should work. – Robin Dijkhof Sep 28 '15 at 12:18
  • If a sticky `Service` is running, it'll be killed when the user swipes its app out of recents, but then it will be restarted a few seconds later. (On KitKat, anyway.) – Kevin Krumwiede Sep 29 '15 at 05:14
  • What I initially thought was the issue was wrong, the problem is not services stopping but rather it is the receiver not receiving broadcasts. – sky Sep 29 '15 at 06:33
  • If I'm not mistaken some manufacturer of the phone give permission for apps like Whatsapp, Facebook, and some popular apps to be able to autostart by default. – lutfianasari Jun 14 '17 at 01:07