Scheduling with AlarmManager not working
<p>I'm new in Android development and I have a strange problem: I need to build an app that looks at all my calls, messages and mobile internet traffic to take track of consumes. I made an observer for the calls and one for the messages and till now it's all working perfect. I made a class that retrives data about my internet traffic (not an observer) and I need to schedule this class at regular periods, so I did this: I registered a reciver in the manifest and the reciver class is the following:</p>

<pre><code>public class ServiceStarter extends BroadcastReceiver {
    @Override
    public void onReceive(Context context, Intent intent) {
        Log.i("ServiceStarter.onReceive", "DetenctionService non attivo, lo lancio...");
        context.startService(new Intent(context, DetectionSevice.class));
    }
}
</code></pre>

<p>Now the class DetectionService that causes the problem:</p>

<pre><code>public class DetectionSevice extends Service {
    @SuppressWarnings("unused")
    private static SQLiteDatabase dbInstance;

    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }

    @Override
    public void onCreate() {        
        super.onCreate();
        ContentResolver resolver = this.getApplicationContext().getContentResolver();
        TelephonyManager tm = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE);
        dbInstance = HabbleDB.getDBInstance(getApplicationContext());
        // The calls observer
        resolver.registerContentObserver(android.provider.CallLog.Calls.CONTENT_URI, true, new CallLogObserver(getContentResolver(), tm, getApplicationContext()));
        Log.i("DetectionService.onCreate", "Observer chiamate attivato");
        // The messages observer
        resolver.registerContentObserver(MessageLogObserver.uriConversation, true, new MessageLogObserver(resolver, tm, getApplicationContext()));
        Log.i("DetectionService.onCreate", "Observer messaggi attivato");
        //data intent for scheduling
        PendingIntent pi;
        AlarmManager am = (AlarmManager)getSystemService(Context.ALARM_SERVICE);
        long nextDate;
        Intent saveData = new Intent(this, DataSaver.class);
        pi = PendingIntent.getService(this, 1234567, saveData, PendingIntent.FLAG_CANCEL_CURRENT);
        nextDate = System.currentTimeMillis() + DataSaver.DELAY;
        am.setRepeating(AlarmManager.RTC_WAKEUP, nextDate, DataSaver.DELAY, pi);
        Log.i("DetectionService.onCreate", "Scheduler per la raccolta dati attivato");
        SharedPreferenceManager.setLongPreference(this, SharedPreferenceManager.NEXT_DATA_SAVE, nextDate);
        //Sender data intent for scheduling
        Intent intent = new Intent(this, SelectAndSend.class);  
        pi = PendingIntent.getService(this, 1234578, intent, PendingIntent.FLAG_CANCEL_CURRENT);
        nextDate = System.currentTimeMillis()+SelectAndSend.DELAY;
        am.setRepeating(AlarmManager.RTC_WAKEUP, nextDate, SelectAndSend.DELAY, pi);
        Log.i("DetectionService.onCreate", "Scheduler per l'invio dati registrato");
        SharedPreferenceManager.setLongPreference(this, SharedPreferenceManager.NEXT_SCHEDULE, nextDate);
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        super.onStartCommand(intent, flags, startId);
        return Service.START_STICKY;
    }
}
</code></pre>

<p>At the end the class that should be launched by the scheduler:</p>

<pre><code>public class DataSaver extends IntentService {
    private static final boolean tsSupported = (TrafficStats.getTotalRxBytes() == TrafficStats.UNSUPPORTED) ? false : true;
    private static final Format FORMATTER = new java.text.SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    private TelephonyManager manager;
    private Context context = getApplicationContext();
    private long totalApps, total3g;
    private SparseArray&lt;String&gt; apps = new SparseArray&lt;String&gt;();
    private PowerManager.WakeLock wl;
    private Handler mHandler = new Handler(Looper.getMainLooper());
    public static final int DELAY = 1 * 60 * 1000;

    public DataSaver() {
        super("DataSaverService");
        setIntentRedelivery(true);
    }

    @SuppressWarnings("deprecation")
    @Override
    public void onCreate() {
        super.onCreate();
        PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE);
        wl = pm.newWakeLock(PowerManager.FULL_WAKE_LOCK, "DataSaverService");
        wl.acquire();
        initializeMinDataID();
        Log.i("DataSaver", "DataSaver created");
    }

    @Override
    protected void onHandleIntent(Intent intent) {
        run();
        long nextDate = System.currentTimeMillis() + DataSaver.DELAY;
        SharedPreferenceManager.setLongPreference(this, SharedPreferenceManager.NEXT_DATA_SAVE, nextDate);
        wl.release();
    }

    public void run() {
        mHandler.post(new Runnable() {
            public void run() {
                int i, uid;
                long base3g, baseApps;
                //Recupero gli UID solo delle app che effettivamente hanno generato traffico
                File dir = new File("/proc/uid_stat/");
                String[] children = dir.list();
                if (children != null) {
                    PackageManager pm = context.getPackageManager();
                    for (i = 0; i &lt; children.length; i++) {
                        uid = Integer.parseInt(children[i]);
                        if ((uid &gt;= 0 &amp;&amp; uid &lt; 2000) || (uid &gt;= 10000)) {
                            apps.put(uid, pm.getNameForUid(uid));
                        }
                    }
                }
                baseApps = SharedPreferenceManager.getLongPreference(context, SharedPreferenceManager.LAST_APPS_DATA);
                base3g = SharedPreferenceManager.getLongPreference(context, SharedPreferenceManager.LAST_3G_DATA);
                totalApps = 0;
                total3g = 0;
                //Se TrafficStats è supportato
                if(tsSupported) {
                    total3g += TrafficStats.getMobileRxBytes() + TrafficStats.getMobileTxBytes();
                    if(total3g &lt; base3g) {
                        Log.e("DataSaver.run", "total3g è minore di base3g!");
                        SharedPreferenceManager.setLongPreference(context, SharedPreferenceManager.LAST_3G_DATA, total3g);
                        return;
                    }
                    if(apps.size() &gt; 0) {
                        for(i = 0; i &lt; apps.size(); i++) {
                            totalApps += TrafficStats.getUidRxBytes(apps.keyAt(i)) + TrafficStats.getUidTxBytes(apps.keyAt(i));
                        }
                    }
                    if(totalApps &lt; baseApps) {
                        Log.e("DataLogObserver.saveDataInformation", "totalApps è minore di baseApps!");
                        SharedPreferenceManager.setLongPreference(context, SharedPreferenceManager.LAST_APPS_DATA, totalApps);
                        return;
                    }
                } else {//Se TrafficStats non è supportato
                    Toast toast = Toast.makeText(context, "Impossibile recuperare alcuni dati. Device non supportato.", Toast.LENGTH_SHORT);
                    toast.show();
                    Log.w("DataSaver.initializeMinDataID", "Il device non supporta TrafficStats!");
                    return;
                }
                Date savedTime = new Date();
                DataBean bean = new DataBean();
                String mcc = manager.getNetworkOperator().substring(0, 3);
                String mnc = manager.getNetworkOperator().substring(3);
                AppDataBean appBean;
                bean.serial = manager.getSubscriberId();
                bean.mcc = mcc;
                bean.mnc = mnc;
                bean.total3gAmount = total3g - base3g;
                bean.from = FORMATTER.format(savedTime);
                if(apps.size() &gt; 0) {
                    for(i = 0; i &lt; apps.size(); i++) {
                        appBean = new AppDataBean();
                        appBean.uid = apps.keyAt(i);
                        appBean.name = apps.valueAt(i);
                        appBean.appAmount = TrafficStats.getUidRxBytes(appBean.uid) + TrafficStats.getUidTxBytes(appBean.uid);
                        appBean.from = FORMATTER.format(savedTime);
                        if(!HabbleDB.insertAppData(appBean)) Log.e("DataLogObserver.saveDataInformation", "Errore nell'inserimento dei dati per l'applicazione " + apps.valueAt(i));
                    }
                }
                if(HabbleDB.insertData(bean)) //se l'inserimento è andato a buon fine, aggiorno anche LAST_3G_DATA
                    SharedPreferenceManager.setLongPreference(context, SharedPreferenceManager.LAST_3G_DATA, total3g);
                else Log.e("DataLogObserver.saveDataInformation", "Errore nell'inserimento dei dati 3g");
            }
        });
    }

    private void initializeMinDataID() {
        totalApps = 0;
        total3g = 0;
        //Se TrafficStats è supportato
        if(tsSupported) {
            if(apps.size() &gt; 0) {
                for(int i = 0; i &lt; apps.size(); i++) {
                    totalApps += TrafficStats.getUidRxBytes(apps.keyAt(i)) + TrafficStats.getUidTxBytes(apps.keyAt(i));
                }
            }
            total3g += TrafficStats.getMobileRxBytes() + TrafficStats.getMobileTxBytes();
        } else {//Se TrafficStats non è supportato
            Toast toast = Toast.makeText(context, "Impossibile recuperare alcuni dati. Device non supportato.", Toast.LENGTH_SHORT);
            toast.show();
            Log.w("DataSaver.initializeMinDataID", "Il device non supporta TrafficStats!");
            return;
        }
        long min = SharedPreferenceManager.getLongPreference(context, SharedPreferenceManager.LAST_3G_DATA);
        if(min == 0 || min &gt; total3g) SharedPreferenceManager.setLongPreference(context, SharedPreferenceManager.LAST_3G_DATA, total3g);
        min = SharedPreferenceManager.getLongPreference(context, SharedPreferenceManager.LAST_APPS_DATA);
        if(min == 0 || min &gt; totalApps) SharedPreferenceManager.setLongPreference(context, SharedPreferenceManager.LAST_APPS_DATA, totalApps);
    }
}
</code></pre>

<p>When I launch the application the two observer are working good, but seems that only the data sender class (SelectAndSend) is scheduled, the class DataSaver doesn't log nothing just from the application start and seems like it doesn't exist in the application.</p>

<p>Someone can help me pls?</p>

<p>P.S.: Sorry about my bad english, I hope to been clear.</p>

<p>[EDIT 2013-05-27]:
I tried to modify the DetectionService.onCreate() in this way:</p>

<pre><code>        ...
        PendingIntent pi, pi2;
        AlarmManager am = (AlarmManager)getSystemService(Context.ALARM_SERVICE);
        AlarmManager am2 = (AlarmManager)getSystemService(Context.ALARM_SERVICE);
        long nextDate;

        ComponentName cn = new ComponentName(this, DataSaver.class);
        Intent saveData = new Intent().setClass(this, DataSaver.class).setComponent(cn);

        pi = PendingIntent.getService(this, 1234567, saveData, PendingIntent.FLAG_UPDATE_CURRENT);
        nextDate = System.currentTimeMillis() + DataSaver.DELAY;
        am.setInexactRepeating(AlarmManager.RTC_WAKEUP, nextDate, DataSaver.DELAY, pi);
        Log.i("DetectionService.onCreate", "Scheduler per la raccolta dati attivato");
        SharedPreferenceManager.setLongPreference(this, SharedPreferenceManager.NEXT_DATA_SAVE, nextDate);
        //aggiungo l'intent per l'invio dei dati all'alarm manager
        Intent intent = new Intent(this, SelectAndSend.class);  
        pi2 = PendingIntent.getService(this, 1234578, intent, PendingIntent.FLAG_CANCEL_CURRENT);
        nextDate = System.currentTimeMillis() + SelectAndSend.DELAY;
        am2.setRepeating(AlarmManager.RTC_WAKEUP, nextDate, SelectAndSend.DELAY, pi2);
        Log.i("DetectionService.onCreate", "Scheduler per l'invio dati registrato");
        SharedPreferenceManager.setLongPreference(this, SharedPreferenceManager.NEXT_SCHEDULE, nextDate);
</code></pre>

<p>As you can see I force a ComponentName object and the specified class in the Intent, but I have no response, yet.
I really need help, I'm going crazy!!!</p>
