【问题标题】:Start service on boot and repeat在启动时启动服务并重复
【发布时间】:2016-01-09 02:02:34
【问题描述】:

我正在尝试做某种自动 GoogleDrive 备份(上传文件)计时器,但我无法设置具体时间,即使我设置为 5 秒(测试目的,它只是每 1 分钟运行一次)并且当用户重新启动手机,它只运行一次(警报没有被调用=/,所以应用程序必须在启动后打开一次)

清单配置:

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

<application...>

 <receiver
            android:name=".Tools.AutoBackupAlarmBroadCast"
            android:process=":remote" >

            <intent-filter>
                <action android:name="android.intent.action.BOOT_COMPLETED" />
            </intent-filter>
        </receiver>

        <service
            android:name=".Tools.AutoBackupService"
            android:exported="false" />


</application>

还有这个 WakeBroadCast:

public class AutoBackupBootStarter extends WakefulBroadcastReceiver {
    @Override
    public void onReceive(Context context, Intent intent) {
        Intent startServiceIntent = new Intent(context, AutoBackupService.class);
        context.startService(startServiceIntent);
    }
}

确保在启动时调用 AutoBackupAlarm,但它只发生一次,我需要它来启动触发器以在用户设置的时间重复(将从共享首选项中获取)

服务:

自动备份服务:

public class AutoBackupService extends IntentService {
    /**
     * Creates an IntentService.  Invoked by your subclass's constructor.
     *
     */
    public AutoBackupService() {
        super("AutoBackup");
    }

    @Override
    protected void onHandleIntent(Intent intent) {
        WakefulBroadcastReceiver.completeWakefulIntent(intent);
//HERE i must start the Async to make the GoogleDrive Backup
//the next doubt will be how can i get sharedpreferences and activity to pass to the async from HERE?

        Log.d("BACKUP", "AutoBackupLogTest");
    }
}

广播

public class AutoBackupAlarmBroadCast extends BroadcastReceiver {
    public static final int REQUEST_CODE = 12345;
    @Override
    public void onReceive(Context context, Intent intent) {
        Intent i = new Intent(context, AutoBackupService.class);
        i.putExtra("foo", "bar");
        context.startService(i);
    }
}

在 onCreate 上调用的 AlarmFunction 几乎可以按我的意愿工作,它不能像下面的时间那样每 5 秒重复一次,它只显示每 1 分钟一次

   public void scheduleAlarm() {
        // Construct an intent that will execute the AlarmReceiver
        Intent intent = new Intent(getApplicationContext(), AutoBackupAlarmBroadCast.class);
        // Create a PendingIntent to be triggered when the alarm goes off
        final PendingIntent pIntent = PendingIntent.getBroadcast(this, AutoBackupAlarmBroadCast.REQUEST_CODE,
                intent, PendingIntent.FLAG_UPDATE_CURRENT);
        // Setup periodic alarm every 5 seconds
        long firstMillis = System.currentTimeMillis(); // alarm is set right away
        AlarmManager alarm = (AlarmManager) this.getSystemService(Context.ALARM_SERVICE);
        // First parameter is the type: ELAPSED_REALTIME, ELAPSED_REALTIME_WAKEUP, RTC_WAKEUP
        // Interval can be INTERVAL_FIFTEEN_MINUTES, INTERVAL_HALF_HOUR, INTERVAL_HOUR, INTERVAL_DAY
        alarm.setInexactRepeating(AlarmManager.RTC_WAKEUP, firstMillis,
                1 * 5 * 1000, pIntent);
    }

【问题讨论】:

  • AFAIK setInexactRepeating() 如果您在 Lollipop 或更高版本上测试应用程序,则不保证以固定的时间间隔发出警报/触发。

标签: android alarm


【解决方案1】:

尝试以下代码在特定时间间隔后重复任务

    boolean alarmUp = (PendingIntent.getBroadcast(this, 444, new Intent(this, AlarmReceiver.class), PendingIntent.FLAG_NO_CREATE) != null);

    if(!alarmUp){

        AlarmManager alarmManager = (AlarmManager)this.getSystemService(Context.ALARM_SERVICE);
        Intent DataSyncIntent = new Intent(this, AlarmReceiver.class);
        PendingIntent pendingIntent = PendingIntent.getBroadcast(this, 444, DataSyncIntent, 0);

        alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, SystemClock.elapsedRealtime(),
                15 * 60000, // 60000 = 1 minute,
                pendingIntent);

    }

【讨论】: