-2

I want to do some network job periodically even when app if force closed.

Now it works until it's force closed. What i am missing?

Also if i add to manifest this: android:process=":remote" - it's not triggering onReceive method (like app is force closed), but in logs i found that:

V/AlarmManager: triggered: cmp=com.cryptorulezz.cryptosignals/.Code.Alarm Pkg: com.cryptorulezz.cryptosignals

My code:

public class Alarm extends BroadcastReceiver
{
     @Override
     public void onReceive(Context context, Intent intent)
     {
         PowerManager pm = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
         PowerManager.WakeLock wl = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "");
         wl.acquire();

        // Put here YOUR code.
        Toast.makeText(context, "Alarm !!!!!!!!!!", Toast.LENGTH_LONG).show(); // For example
        System.out.println("ALARM !!!!!!!!!!!!!!!!!!!!");

        wl.release();
    }

public void setAlarm(Context context)
{
    AlarmManager am =(AlarmManager)context.getSystemService(Context.ALARM_SERVICE);
    //Intent i = new Intent(context, Alarm.class);
    Intent i = new Intent("Coinsider.START_ALARM");
    PendingIntent pi = PendingIntent.getBroadcast(context, 0, i, 0);
    am.setRepeating(AlarmManager.RTC_WAKEUP, System.currentTimeMillis(), 1000 * 60 * 1, pi); // Millisec * Second * Minute
}

    public void cancelAlarm(Context context)
    {
        Intent intent = new Intent(context, Alarm.class);
        PendingIntent sender = PendingIntent.getBroadcast(context, 0, intent, 0);
        AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
        alarmManager.cancel(sender);
    }
}

How i set alarm in MainActivity:

Alarm alarm = new Alarm();
alarm.setAlarm(this);

Manifest:

 <receiver android:name=".Code.Alarm" android:exported="false">
        <intent-filter>
            <action android:name="Coinsider.START_ALARM" >
            </action>
        </intent-filter>
    </receiver>
Kuls
  • 2,047
  • 21
  • 39
Vadim
  • 335
  • 3
  • 14

1 Answers1

0

Once the app gets force killed, it won't receive the intent and the intent filter won't be triggered. To overcome this, I suggest a sort of watchDog, that relies on some system events (like android.intent.action.BOOT_COMPLETED), that simply checks if one of your process is alive, and fires it if not. In the manifest, you 'd have something like this:

    <receiver
        android:name="it.angelic.receivers.WatchDogSetupReceiver"
        android:process=":souliss_process">
        <intent-filter>
            <action android:name="android.intent.action.BOOT_COMPLETED"/>
            <action android:name="android.intent.action.USER_PRESENT"/>
        </intent-filter>
    </receiver>

The class WatchDogSetupReceiver would then check if the dog is alive, and fire a new one if needed:

        Intent i = new Intent(ctx, WatchDogEventReceiver.class); // explicit intent
        PendingIntent patTheDog = PendingIntent.getBroadcast(ctx, 0, i, PendingIntent.FLAG_CANCEL_CURRENT);
        alarmManager.setInexactRepeating(AlarmManager.RTC_WAKEUP, now.getTimeInMillis(), 5000,
                patTheDog);

Last, WatchDogEventReceiver would simply do the required un-killable job. It is important that the watchdog stays light, as it will be fired upon every screen on event. This solution is non-optimal, but works even after force-kill:

public class WatchDogEventReceiver extends BroadcastReceiver {


@Override
public void onReceive(final Context ctx, final Intent intent) {
    Log.d(Constants.TAG + ":WatchDog", "WatchDog.onReceive() called, looking for Dataservice:");
    ActivityManager manager = (ActivityManager) ctx.getSystemService(Context.ACTIVITY_SERVICE);
    //Fire Service  
    Intent eventService = new Intent(ctx, YourDamnService.class);
    ctx.startService(eventService);//sempre, ci pensa poi lui


}
Shine
  • 3,788
  • 1
  • 36
  • 59