2015-08-06 2 views
0

Вот мой BootBroadcastНамерение не повторяется AlarmManager

public class BootBroadcast extends BroadcastReceiver { 

    public static final String FILE_NAME = "BootBroadcast.java"; 
    private static final long REPEAT_TIME_TO_CHECK_EXPENSES = 1000 * 60; //1 minute 

@Override 
    public void onReceive(Context context, Intent intent) { 
     Log.v(FILE_NAME, "in onReceive"); 
     AlarmManager service = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE); 

     Intent service1 = new Intent(context, ISCheckExpenses.class); 
     Log.v(FILE_NAME, "starting service1"); 
     context.startService(service1); 

     PendingIntent pending1 = PendingIntent.getBroadcast(context, 0, service1, PendingIntent.FLAG_UPDATE_CURRENT); 
     Calendar cal1 = Calendar.getInstance(); 
     cal1.add(Calendar.SECOND, 600); 
     service.setInexactRepeating(AlarmManager.RTC_WAKEUP, cal1.getTimeInMillis(), REPEAT_TIME_TO_CHECK_EXPENSES, pending1); 
    } 
} 

А вот мой ISCheckExpenses

public class ISCheckExpenses extends IntentService { 
public static final String FILE_NAME = "ISCER"; 
private int recurringExpensesNotificationID = 001; 
private int recurringExpensesMultiplier = 123; 

public ISCheckExpenses(){ 
     super(ISCheckExpenses.class.getName()); 
    } 

@Override 
    public void onCreate() { 
     super.onCreate(); 
    } 

@Override 
    protected void onHandleIntent(Intent intent){ 

     Log.d(FILE_NAME, "IntentService Started!"); 

    //do some processing and send a notification to the user 
    String subject, content; 
    subject = getString(R.string.recurring_expenses_notification_due_subject); 
       content = getApplicationContext().getString(R.string.recurring_expenses_notification_due_content); 
    sendNotification(recurringExpensesNotificationID,1,subject,content); 
    } 

    private void sendNotification(int notificationID, int notificationType, String subject, String content){ 
     Intent myIntent = new Intent(this, MainActivity.class); 
     int randomID = 1; 

      myIntent.putExtra("intentCaller","expensesRecurring"); 
      randomID = recurringExpensesMultiplier * requestID; 

     //just to make sure the random ID is non-negative 
     if (randomID < 0){ 
      randomID = randomID * -1; 
     } 
     myIntent.setAction(Intent.ACTION_VIEW); 
     myIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_NEW_TASK); 
     PendingIntent pIntent = PendingIntent.getActivity(getBaseContext(), randomID, myIntent, PendingIntent.FLAG_UPDATE_CURRENT); 

     NotificationCompat.Builder n = new NotificationCompat.Builder(this) 
       .setContentTitle(subject) 
       .setContentText(content) 
       .setSmallIcon(R.mipmap.ic_launcher) 
       .setContentIntent(pIntent) 
       .setAutoCancel(true); 

     NotificationManager notificationManager = 
       (NotificationManager) getSystemService(NOTIFICATION_SERVICE); 
     n.build().flags |= Notification.FLAG_AUTO_CANCEL; 
     notificationManager.notify(notificationID, n.build()); 
    } 
} 

И оба файла уже внутри моей AndroidManifest.xml

<uses-feature 
    android:glEsVersion="0x00020000" 
    android:required="true" /> 
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" /> 
<uses-permission android:name="android.permission.VIBRATE" /> 
<uses-permission android:name="android.permission.WAKE_LOCK" /> 
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" /> 
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> 

<application 
     android:allowBackup="true" 
     android:icon="@mipmap/ic_launcher" 
     android:label="@string/app_name" 
     android:theme="@style/AppTheme" > 
     <activity 
      android:name=".MainActivity" 
      android:launchMode="singleTop" 
      android:label="@string/app_name" > 
      <intent-filter> 
       <action android:name="android.intent.action.MAIN" /> 

       <category android:name="android.intent.category.LAUNCHER" /> 
      </intent-filter> 
     </activity> 
<service 
      android:name=".ISCheckExpenses" 
      android:exported="false" 
      android:icon="@mipmap/ic_launcher" 
      android:enabled="true" /> 
<receiver android:name=".BootBroadcast" > 
      <intent-filter> 
       <action android:name="android.intent.action.BOOT_COMPLETED" /> 
      </intent-filter> 
     </receiver> 
</application> 

Через несколько секунд после перезапуска устройства появится уведомление. Затем я нажимаю на уведомление, чтобы очистить его. И мое приложение должно повторно отобразить уведомление через 1 минуту? Но это не так. И я ожидаю увидеть «IntentService Started!» каждые 1 минуту в моем logcat .. но ничего не появляется? «IntentService началась!» отображается только один раз.

Что мне здесь не хватает? Спасибо

Btw Я проверил это на KitKat и Lollipop.

ответ

0

Моя ошибка была я неправильно поняла BroadcastReceiver и AlarmManager должны работать. Вместо выполнения AlarmManager в onReceive, как я делал выше, я должен был создать еще одну функцию, которая вызывает новый Intent и передает вызывающую активность в качестве контекста, а BroadcastReceiver - как класс.

Так вот, как моя рабочая BroadcastReceiver выглядит следующим образом:

public class BootBroadcast extends BroadcastReceiver { 

    //private static final long REPEAT_TIME_TO_CHECK_EXPENSES = 1000 * 30; 
    //private static final long REPEAT_TIME_TO_ANALYZE_LOCATION = 1000 * 30; 

    @Override 
    public void onReceive(Context context, Intent intent) { 

     int what = intent.getIntExtra("what",0); 

     if (what == 1) { 
      Intent intentService1 = new Intent(context, ISCheckRecurringItemsAndCC.class); 
      context.startService(intentService1); 
     }else if (what == 2) { 
      Intent service2 = new Intent(context, ISCheckLocationAndRating.class); 
      context.startService(service2); 
     }else{ 
      //should only reach here when the device boots 
      Intent intentService1 = new Intent(context, ISCheckRecurringItemsAndCC.class); 
      context.startService(intentService1); 

      Intent service2 = new Intent(context, ISCheckLocationAndRating.class); 
      context.startService(service2); 
     } 
    } 

    public void setAlarm(Context context){ 
     Log.v(FILE_NAME,"inside setAlarm"); 
     AlarmManager am = (AlarmManager)context.getSystemService(Context.ALARM_SERVICE); 

     Intent myIntent = new Intent(context, BootBroadcast.class); 
     myIntent.putExtra("what", 1); 
     PendingIntent myPendingIntent = PendingIntent.getBroadcast(context, 111, myIntent, 0); 
     am.setRepeating(AlarmManager.RTC_WAKEUP, System.currentTimeMillis(), REPEAT_TIME_TO_CHECK_EXPENSES, myPendingIntent); 

     myIntent = new Intent(context, BootBroadcast.class); 
     myIntent.putExtra("what", 2); 
     myPendingIntent = PendingIntent.getBroadcast(context, 222, myIntent, 0); 
     am.setRepeating(AlarmManager.RTC_WAKEUP, System.currentTimeMillis(), REPEAT_TIME_TO_ANALYZE_LOCATION, myPendingIntent); 

    } 
} 

Код выше отлично работает для меня.

1

Проблема заключается в том, что вы пытаетесь запустить свой Service, используя PendingIntent для трансляции. Вам нужно будет отправить сигнал тревоги другому абоненту BroadcastReceiver, так как вы хотите разбудить устройство, а затем получите этот приемник Service. Вам также, вероятно, придется координировать работу с замками слежения, чтобы обеспечить достаточное время работы устройства.

+0

Я попытался изменить его на AlarmManager.RTC, но проблема все еще сохраняется ... Кстати, извините за поздний ответ, потому что я получил свое намерение работать несколько дней назад. Я сделал это, я просто перестроил содержимое моего AndroidManifest.xml.Я думал, что все понял, но внезапно вчера эта проблема сохраняется снова - мое намерение не повторяется будильником – imin

1

Вы получаете первый «IntentService Started!» потому что вы явно вызвать startService() от вашего BootReceiver, но ваш менеджер сигнализации настроен на запуск через 10 минут, а не через 1 минуту для первого появления, потому что вы делаете:

Calendar cal1 = Calendar.getInstance(); 
cal1.add(Calendar.SECOND, 600); 
service.setInexactRepeating(AlarmManager.RTC_WAKEUP, cal1.getTimeInMillis(), REPEAT_TIME_TO_CHECK_EXPENSES, pending1); 

т.е. вы добавляете 600 секунд (10 минут) до текущего времени и использовать это время, в течение которого AlarmManager должен сначала запускать. Вместо того, чтобы просто менять время, которое вы добавляете с 600 до 60 секунд, я бы изменил BroadcastReceiver, так что вместо того, чтобы звонить startService() и устанавливать первый раз для вызова, я просто передал текущее время в миллисекундах на AlarmManager.setInexactRepeating() для triggerAtMillis время так, что это вызывает сразу, то в ваших секундных интервалах 60 - то есть изменить метод onReceive() к:

@Override 
public void onReceive(Context context, Intent intent) { 
    Log.v(FILE_NAME, "in onReceive"); 
    AlarmManager service = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE); 

    Intent service1 = new Intent(context, ISCheckExpenses.class); 
    Log.v(FILE_NAME, "starting service1"); 
    context.startService(service1); 

    PendingIntent pending1 = PendingIntent.getBroadcast(context, 0, service1, PendingIntent.FLAG_UPDATE_CURRENT); 
    service.setInexactRepeating(AlarmManager.RTC_WAKEUP, System.currentTimeMillis(), REPEAT_TIME_TO_CHECK_EXPENSES, pending1); 
} 

вы также должны помнить, что, как вы используете setInexactRepeating(), тревога может быть отложены до одной еще 60 секунд, как описано в документации.

+0

Извините, это еще не решило мою проблему. Кстати, жаль позднего ответа, потому что я получил свое намерение работать несколько дней назад. Я сделал это, я просто перестроил содержимое моего AndroidManifest.xml. Я думал, что все понял, но внезапно вчера эта проблема повторяется снова - мое намерение не повторяется будильником – imin