0

I want my application to work and to listen for incoming Intents even if the activity is closed. What is the best way to do it?

I have a receiver registered on the manifest:

    <receiver
        android:name="com.farawayapp.background.Receiver"
        android:exported="false" >
        <intent-filter>
            <action android:name="android.provider.Telephony.SMS_RECEIVED" />
            <action android:name="android.intent.action.PACKAGE_ADDED" />
            <action android:name="android.net.conn.CONNECTIVITY_CHANGE" />
            <action android:name="android.intent.action.PACKAGE_CHANGED" />
            <action android:name="android.intent.action.PACKAGE_REMOVED" />

            <data android:scheme="package" />
        </intent-filter>
    </receiver>

And the BroadcastReceiver class is:

public class Receiver extends BroadcastReceiver implements Variables {

    CheckConexion cc;

    @Override
    public void onReceive(Context contxt, Intent intent) {

        // Cuando hay un evento, lo diferenciamos y hacemos una acción.

        if (intent.getAction().equals(SMS_RECEIVED)) {
            Sms sms = new Sms(null, contxt);
            sms.uploadNewSms(intent);
        } else if (intent.getAction().equals(Intent.ACTION_BATTERY_CHANGED)) {
            /*
             * try { new PhoneState(contxt).battery(intent.getIntExtra("level",
             * 0)); } catch (JSONException e) { e.printStackTrace(); }
             */// Nothing at the moment
        } else if (intent.getAction().equals(Intent.ACTION_PACKAGE_ADDED)
                || intent.getAction().equals(Intent.ACTION_PACKAGE_CHANGED)
                || intent.getAction().equals(Intent.ACTION_PACKAGE_REMOVED)) {
            Database db = new Database(contxt);
            if (db.open().Preferences(4)) {
                Uri data = intent.getData();
                new ListApps(contxt).import_app(intent, contxt, data,
                        intent.getAction());
            }
            db.close();
        } else if (intent.getAction().equals(
                ConnectivityManager.CONNECTIVITY_ACTION)) {
            cc = new CheckConexion(contxt);

            if (cc.isOnline()) {

                Database db = new Database(contxt);
                db.open();
                if (db.move() == 1) {
                    new UploadOffline(contxt);
                }
                db.close();

            }
        }
    }
}

Thanks...

Nikolai Samteladze
  • 7,699
  • 6
  • 44
  • 70
Marc Ortiz
  • 2,242
  • 5
  • 27
  • 46

1 Answers1

0

If you register a BroadcastReceiver to receive broadcasts then it will be invoked even if user doesn't work with your application at the time (none of your application's activities is in foreground). Although, there are some pitfalls that you probably want to think about:

  1. Most of the intents are not broadcasted when device is asleep. There are only several events that will wake up your device (such as incoming sms, incoming call, pushed notification from Google Cloud Messaging server, etc.). Thus, if want your application to do some work when device is asleep you should consider AlarmManager to set alarms that will regularly invoke your application.

  2. If you want to do some work in background, you probably want to use WakeLock to prevent the device from sleeping (and CPU from turning off). This is a good sample from CommonWare that shows how to use WakeLock and provides you with nice library to ease your life: https://github.com/commonsguy/cwac-wakeful. Although, you should be careful with WakeLock because it can drain battery.

Nikolai Samteladze
  • 7,699
  • 6
  • 44
  • 70