0

I have MainActivity which has 5 buttons each of them has intent to service with server. Main has alarmmanager for repeat the connection with the server(service) and i have receiver class so when i close the app or restart the device the service still works so here is my problems.

  1. when I click on any button I activate the service in the service there is httpurlconnection to connect with my server so let say i want the wallpaper to change every 10 min ((it changes in 8 min then in 4 min and sometimes in 10 min ???)).

my code is right but this problems appears to me today (yestarday worked great)

I'm sending Post-Request. My service is about sending Post-request to server and use the response to change the wallpaper inside the service.

private final static int a = 1000*60*5; //5 min
private final static int b = 1000 * 60 * 10; // 10 min
private final static int c = 1000 * 60 * 30; // 30 min
private final static int d = 1000 * 60 * 120; // 2 hours
private final static int e = 1000 * 60 * 360; // 6 hours
private final static int f = 1000*60*1440; // 1 day




  preference = PreferenceManager.getDefaultSharedPreferences(getApplicationContext());
    alarm = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
    alarm.cancel(pintent);
}


@Override
public void onClick(View v) {
    switch (v.getId()) {
        case R.id.btn1: {
            intent = new Intent(MainActivity.this, WallService.class);
            pintent = PendingIntent.getService(MainActivity.this, 0, intent, 0);
            preference.edit().putInt("timeInterval", a).apply();
            alarm.setRepeating(AlarmManager.RTC_WAKEUP, System.currentTimeMillis(), a, pintent);
            startService(intent);
        }
        case R.id.btn2: {
            intent = new Intent(MainActivity.this, WallService.class);
            pintent = PendingIntent.getService(MainActivity.this, 0, intent, 0);

            preference.edit().putInt("timeInterval", b).apply();
            alarm.setRepeating(AlarmManager.RTC_WAKEUP, System.currentTimeMillis(), b, pintent);
            startService(intent);
        }
        case R.id.btn3: {
            intent = new Intent(MainActivity.this, WallService.class);
            pintent = PendingIntent.getService(MainActivity.this, 0, intent, 0);

            preference.edit().putInt("timeInterval", c).apply();
            alarm.setRepeating(AlarmManager.RTC_WAKEUP, System.currentTimeMillis(), c, pintent);
            startService(intent);
        }
        case R.id.btn4: {
            intent = new Intent(MainActivity.this, WallService.class);
            pintent = PendingIntent.getService(MainActivity.this, 0, intent, 0);

            preference.edit().putInt("timeInterval", d).apply();
            alarm.setRepeating(AlarmManager.RTC_WAKEUP, System.currentTimeMillis(), d, pintent);
            startService(intent);
        }
        case R.id.btn5: {
            intent = new Intent(MainActivity.this, WallService.class);
            pintent = PendingIntent.getService(MainActivity.this, 0, intent, 0);

            preference.edit().putInt("timeInterval", e).apply();
            alarm.setRepeating(AlarmManager.RTC_WAKEUP, System.currentTimeMillis(), e, pintent);
            startService(intent);
        }
        case R.id.btn6: {
            intent = new Intent(MainActivity.this, WallService.class);
            pintent = PendingIntent.getService(MainActivity.this, 0, intent, 0);

            preference.edit().putInt("timeInterval", f).apply();
            alarm.setRepeating(AlarmManager.RTC_WAKEUP, System.currentTimeMillis(), f, pintent);
            startService(intent);

        }

    }
}

Manifest

   <uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.SET_WALLPAPER" />
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<uses-permission android:name="android.permission.WAKE_LOCK" />

<application android:allowBackup="true" android:icon="@mipmap/ic_launcher"
    android:label="@string/app_name" android:supportsRtl="true" android:theme="@style/AppTheme">
    <receiver android:name=".BootCompletedIntentReceiver" android:enabled="true"
        android:exported="true">
        <intent-filter>
            <action android:name="android.intent.action.BOOT_COMPLETED" />
        </intent-filter>
    </receiver>

    <service android:name=".WallService" android:enabled="true"
        android:exported="true"></service>

    <activity android:name=".MainActivity">
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />

            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
    </activity>
</application>

1 Answers1

0

From the documentation for setRepeating():

Note: as of API 19, all repeating alarms are inexact. If your application needs precise delivery times then it must use one-time exact alarms, rescheduling each time as described above. Legacy applications whose targetSdkVersion is earlier than API 19 will continue to have all of their alarms, including repeating alarms, treated as exact.


EDIT: Add detailed example

Instead of starting your Service and scheduling a repeating alarm like this:

intent = new Intent(MainActivity.this, WallService.class);
pintent = PendingIntent.getService(MainActivity.this, 0, intent, 0);
preference.edit().putInt("timeInterval", a).apply();
alarm.setRepeating(AlarmManager.RTC_WAKEUP, System.currentTimeMillis(), a, pintent);
startService(intent);

Do this:

intent = new Intent(MainActivity.this, WallService.class);
intent.putExtra("interval", a); // This sets the repeat interval
preference.edit().putInt("timeInterval", a).apply();
startService(intent);

In WallService.onStartCommand():

// define a default interval in case the Intent doesn't have one
int defaultInterval = ...;
int interval = intent.getIntExtra("interval", defaultInterval);
// Make sure that you pass "interval" as the requestCode to
//  PendingIntent.getService() to ensure that the PendingIntent is
//  unique for this interval
PendingIntent pintent = PendingIntent.getService(this, interval, intent, 0);
alarmManager = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
// Set an alarm to start the Service again at the interval
alarmManager.setExact(AlarmManager.RTC_WAKEUP, System.currentTimeMillis() + interval, pintent);
// Here you talk to your server or whatever you want to do every 
//  interval
...
David Wasser
  • 93,459
  • 16
  • 209
  • 274
  • If you need exact timing you should not use `setRepeating()`. Just set an alarm using `setExact()` and when that one triggers, set the next one using `setExact()`. – David Wasser Nov 07 '16 at 11:50
  • setExact i guess will not repeat my intents –  Nov 07 '16 at 12:21
  • because i cant put my a=1000*60*10 inside SETEXACT() –  Nov 07 '16 at 12:48
  • No, you call `setExact()` with `System.currentTimeMillis() + a`. – David Wasser Nov 07 '16 at 15:33
  • i can't write this code just i can replace from setrepeating to setExact() but then i will have error in the parameters –  Nov 08 '16 at 05:19
  • I'm so sorry, I don't understand your comment. Please refer to the Android documentation for `AlarmManager` or search for other solutions to the problem of `setRepeating()` on Stackoverflow. – David Wasser Nov 08 '16 at 09:13
  • what i meant that setrepeating takes 4 parameters but setExact() takes only 3 i can't put the time that i want to repeat –  Nov 08 '16 at 12:27
  • No, you can't reliably set a repeating alarm! If you want a reliable repeating alarm, you need to set the first one. When the first one goes off, you then set the necxt one. When the next one goes off, you set the next one. That's the only way to get reliable exact repeating alarms! – David Wasser Nov 08 '16 at 14:11
  • hmmm then there is not solution because i don't want to something goes off untill the user select another time –  Nov 09 '16 at 05:25
  • I don't understand. If you want a repeating alarm, you get one every X milliseconds. In this case, you just need to schedule the alarms one at a time. There is no difference. – David Wasser Nov 09 '16 at 10:13
  • can u show me with a code please ?? i have 5 timing it's wrong to write code for every 5 min for 24 hours and then for the next 24 hours –  Nov 17 '16 at 05:54
  • See http://stackoverflow.com/questions/34585381/setrepeating-of-alarmmanager-repeats-after-1-minute-no-matter-what-the-time-is/40006651#40006651 – David Wasser Nov 17 '16 at 11:05
  • this will change just after 5 sec and not repeat it –  Nov 17 '16 at 11:19
  • I added an example of what I'm talking about. Hopefully you can understand this now. – David Wasser Nov 17 '16 at 15:23