Можно ли избежать "повторного кода" для нескольких сигналов тревоги (ранее было: "Несколько сигналов тревоги" = "Несколько получателей загрузки")?
У меня очень тонкий вопрос, который может показаться гротескным для более опытных глаз, чем у меня.
Я реализую 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 ответа
Как я уже предлагал в разделе комментариев, может быть что-то вроде следующего.
Этот подход требует четырех классов:
BootBroadcastReceiver.class
которыйextends BroadcastReceiver
слушать трансляцию onBootCompleted. Как только загрузка завершится, этот класс запуститAlarmStarterService.class
,AlarmStarterService.class
которыйextends Service
затем запустит обе тревоги.AlarmBroadcastReceiver.class
которые такжеextends BroadcastReceiver
будет получать трансляции по тревоге, а затем запуститьShowNotificationService.class
и передать ему идентификатор черезIntent
,- И, наконец,
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();
}
}
Я думаю, что то, что вы пытаетесь сделать, может быть сделано с использованием только одного для них обоих, и обрабатывать различные случаи (даже если они превышают два) путем настройки параметров приложения.
Как вы можете сохранить последнее месячное время будильника и последнее еженедельное и установить срабатывание будильника с самым ранним временем.