Можно ли избежать "повторного кода" для нескольких сигналов тревоги (ранее было: "Несколько сигналов тревоги" = "Несколько получателей загрузки")?

У меня очень тонкий вопрос, который может показаться гротескным для более опытных глаз, чем у меня.

Я реализую 2 различных сигнала тревоги, которые выживают при перезагрузке / выключении и показывают уведомление при срабатывании.
Один представляет собой повторяющееся ежедневное напоминание, а другой - ежемесячное напоминание, которое сбрасывается приложением каждый раз, когда пользователь выполняет задание.
Просто чтобы напомнить ему / ей сделать это снова, когда пройдет месяц.

Теперь все работает просто отлично.
Так в чем проблема?

Ничего, но у меня есть BootReceiver, AlarmReceiver и AlarmService в два раза
Общим является только построитель уведомлений.

Мой вопрос: могу ли я объединить эти элементы и не разбивать их на какие-либо тревоги?
Потому что, если нет, если в будущем мне нужно будет планировать еженедельную сигнализацию, мне придется сделать еще один загрузочный приемник, приемник сигналов тревоги и службу сигнализации.

Для меня это не кажется слишком умным (скажем, я добавляю еженедельные и ежегодные задания: мне нужно добавить еще 2 приемника и услуги! Мне это кажется безумным).
Но, может быть, я ошибаюсь, и все должно быть так?

В предыдущем приложении, которое я написал (до того, как узнал, что оно не прошло перезагрузку), оно работало с сигналами тревоги, разделяющими все классы.

Спасибо, ребята, за ваше время.

Если вам нужно увидеть мой код, просто попросите его. Но это немного долго...

Это мой файл манифеста, просто чтобы показать, в чем состоит мое сомнение:

<manifest
    xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.android.scheduler2"
    android:versionCode="1"
    android:versionName="1.14.02.11 b"
    >

    <uses-sdk
        android:minSdkVersion="8"
        android:targetSdkVersion="18"
    />

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

    <application
        android:label="@string/app_name"
        android:icon="@drawable/ic_launcher"
        android:theme="@style/Theme.Sample"
        >

        <!-- The Main Activity -->
        <activity
            android:name="com.example.android.scheduler2.ACT_Base"
            android:label="@string/app_name"
            >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>

        <!-- The Preference Activity -->
        <activity android:name="com.example.android.scheduler2.ACT_Prefs" />

        <!-- 2 Alarms = 2 Alarm Boot receivers -->
        <!-- The One Shot Alarm Boot Receiver -->
        <receiver
            android:name="com.example.android.scheduler2.RCV_Boot_One"
            android:enabled="false"
            >
            <intent-filter>
                <action android:name="android.intent.action.BOOT_COMPLETED" />
            </intent-filter>
        </receiver>
        <!-- The Repeating Alarm Boot Receiver -->
        <receiver
            android:name="com.example.android.scheduler2.RCV_Boot_Rep"
            android:enabled="false"
            >
            <intent-filter>
                <action android:name="android.intent.action.BOOT_COMPLETED" />
            </intent-filter>
        </receiver>

        <!-- 2 Alarms = 2 Alarm receivers -->
        <!-- The One Shot Alarm Receiver -->
        <receiver android:name="com.example.android.scheduler2.RCV_Alarm_One" />
        <!-- The Repeating Alarm Receiver -->
        <receiver android:name="com.example.android.scheduler2.RCV_Alarm_Rep" />

        <!-- 2 Alarms = 2 Alarm services -->
        <!-- The One Shot Alarm Service -->
        <service android:name="com.example.android.scheduler2.SVC_Alarm_One" />
        <!-- The Repeating Alarm Service -->
        <service android:name="com.example.android.scheduler2.SVC_Alarm_Rep" />
    </application>
</manifest>

2 ответа

Решение

Как я уже предлагал в разделе комментариев, может быть что-то вроде следующего.

Этот подход требует четырех классов:

  1. BootBroadcastReceiver.class который extends BroadcastReceiver слушать трансляцию onBootCompleted. Как только загрузка завершится, этот класс запустит AlarmStarterService.class,
  2. AlarmStarterService.class который extends Service затем запустит обе тревоги.
  3. AlarmBroadcastReceiver.class которые также extends BroadcastReceiver будет получать трансляции по тревоге, а затем запустить ShowNotificationService.class и передать ему идентификатор через Intent,
  4. И, наконец, ShowNotificationService.class которые также extends Service и покажет уведомление на основе идентификатора, переданного через Intent,

BootBroadcastReceiver может выглядеть следующим образом.

public class BootBroadcastReceiver extends BroadcastReceiver {

    @Override
    public void onReceive(Context context, Intent intent) {
        context.startService(new Intent(context, AlarmStarterService.class));
    }
}

public class AlarmStarterService extends Service {

    public static final int REQUEST_CODE_DAILY = 10000;
    public static final int REQUEST_CODE_MONTHLY = 10001;

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

    @Override
    public void onCreate() {
        createAlarm();

        stopSelf();
    }  

    private void createAlarm() {
        PendingIntent pIntentDaily = getPendingIntent(REQUEST_CODE_DAILY);
        PendingIntent pIntentMonthly = getPendingIntent(REQUEST_CODE_MONTHLY);

        AlarmManager am = (AlarmManager) this
                .getSystemService(Context.ALARM_SERVICE);

        am.setRepeating(AlarmManager.RTC, TIME_DESIRED, AlarmManager.INTERVAL_DAY, pIntentDaily);
        am.setRepeating(AlarmManager.RTC, TIME_DESIRED, AlarmManager.INTERVAL_DAY * 30, pIntentMonthly );
    }

    private PendingIntent getPendingIntent(int requestCode) {
        Intent i= new Intent(this, AlarmBroadcastReceiver.class);
        i.putExtra("_id", requestCode);
        i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);                     

        return PendingIntent.getBroadcast(this, requestCode, i, PendingIntent.FLAG_UPDATE_CURRENT);
    }
}


public class AlarmBroadcastReceiver extends BroadcastReceiver {

    @Override
    public void onReceive(Context context, Intent intent) {
        context.startService(new Intent(context, ShowNotificationService.class)
                .putExtra("_id", intent.getIntExtra("_id", -1)));
    }
}


public class ShowNotificationService extends Service {

    int id;

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

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        id = intent.getIntExtra("_id", -1);
        return START_STICKY;
    }

    @Override
    public void onCreate() {
        switch(id) {
            case AlarmStarterService.REQUEST_CODE_DAILY:
                showDailyNotification();
                break;
            case larmStarterService.REQUEST_CODE_MONTHLY:
                showMonthlyNotification();
                break;
        }

        stopSelf();
    }  
}

Я думаю, что то, что вы пытаетесь сделать, может быть сделано с использованием только одного для них обоих, и обрабатывать различные случаи (даже если они превышают два) путем настройки параметров приложения.

Как вы можете сохранить последнее месячное время будильника и последнее еженедельное и установить срабатывание будильника с самым ранним временем.

Другие вопросы по тегам