Приложение аварийно завершает работу при вызове BroadcastReceiver

У меня есть два небольших вопроса;

  1. BroadcastReceiver моего приложения отлично работает, когда приложение работает, я отлично получаю всплывающее сообщение «Вторник в 2», и оно обновляет приложение, но когда я закрываю свое приложение, это означает, что приложение перестает работать, оно не вызывается, а вместо этого он вылетает «Ваше приложение перестало работать», поэтому он знает, что должен вызывать его, но не делает этого, верно?

  2. Кажется, что BroadcastReceiver вызывается каждый день около 14:00, а не только по вторникам в 14:00, я хочу, чтобы приложение обновлялось раз в неделю. Возможно, это потому, что я вызываю свой метод setAlarm() для onCreate моего UpcomingFragment?

В классе UpcomingFragment (где я установил будильник, чтобы он срабатывал каждый вторник в 2 часа)

 private void setAlarm(){
    AlarmManager alarmMgr = (AlarmManager) getActivity().getSystemService(Context.ALARM_SERVICE);
    Intent intent = new Intent(getActivity(), UpdateReceiver.class);
    intent.putExtra("greeting", "Hello");
    PendingIntent alarmIntent = PendingIntent.getBroadcast(getActivity(), 0, intent, 0);

    Calendar calendar = Calendar.getInstance();
    calendar.setTimeInMillis(System.currentTimeMillis());
    calendar.set(Calendar.DAY_OF_WEEK, Calendar.TUESDAY);
    calendar.set(Calendar.HOUR_OF_DAY, 14);

    // With setInexactRepeating(), you have to use one of the AlarmManager interval
    // constants--in this case, AlarmManager.INTERVAL_DAY.
    alarmMgr.setInexactRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(),
            AlarmManager.INTERVAL_DAY, alarmIntent);
}

В BroadcastReceiver onReceive()

public class UpdateReceiver extends BroadcastReceiver {
    @Override
    public void onReceive(Context context, Intent intent) {
         UpcomingFragment.getInstance().update();
         //if tuesday
         Toast.makeText(context, "Tuesday at 2" , Toast.LENGTH_LONG).show();
   }
}

Манифест:

<uses-permission android:name="com.android.alarm.permission.SET_ALARM"/>
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>

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

я не могу предоставить вам logcat, потому что он не печатает его, когда обналичивает, я не знаю, виновата ли здесь моя студия Android или мое приложение. Спасибо!


person Community    schedule 14.11.2015    source источник
comment
Означает, что UpcomingFragment.getInstance().update(); строка вызывает проблему   -  person ρяσѕρєя K    schedule 14.11.2015


Ответы (1)


Вы не можете манипулировать Fragment внутри контекста BroadCastReceiver. По сути, широковещательные приемники запускаются внутри контекста приложения, и вы не можете получить доступ к материалам пользовательского интерфейса.

Если вы хотите запустить действие после запуска этой трансляции, вам понадобится следующий код:

Intent intent = new Intent(context, MyActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(intent);

Примечание. Доступ к пользовательскому интерфейсу (включая фрагменты) должен выполняться в контексте действия.


Обновление №1

Кажется, что BroadcastReceiver вызывается каждый день около 14:00, а не только по вторникам в 14:00, я хочу, чтобы приложение обновлялось раз в неделю. Возможно, это потому, что я вызываю свой метод setAlarm() для onCreate моего UpcomingFragment?

Я думаю, что у меня есть лучший подход, чем ваш.

В первом случае ваши коды расписания должны устанавливать будильник на ближайший вторник в 14:00. Для этого этот ответ может быть полезно.

Для последнего сначала добавьте следующее разрешение в файл манифеста.

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

Затем определите другой широковещательный приемник и объявите его в файле манифеста.

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

Добавьте этот код в свой только что созданный широковещательный приемник.

@Override
public void onReceive(Context context, Intent intent) {
    // Set the alarm to coming Tuesday on 2 PM
}

Это гарантирует, что ваше приложение будет обновляться каждый вторник в 14:00 при любых обстоятельствах.

person frogatto    schedule 14.11.2015
comment
Большое спасибо, друг, и не могли бы вы возражать или иметь хоть малейшее представление по второму вопросу сверху? - person ; 15.11.2015
comment
но что, если пользователь не открывает ни свой телефон во вторник, ни приложение? - person ; 15.11.2015
comment
@MadBoy О, ты прав! Вы должны немного изменить этот код, чтобы решить эту проблему. - person frogatto; 15.11.2015
comment
@MadBoy stackoverflow.com/questions/13227035/ - person frogatto; 15.11.2015