调用 BroadcastReceiver 时应用程序崩溃
App crashes when BroadcastReceiver gets called
我有两个小问题;
我的应用程序的 BroadcastReceiver 在应用程序 运行 时工作正常,我完美地收到了 "Tuesday at 2" toast 消息并且它更新了应用程序,但是当我关闭我的应用程序时,意味着应用程序停止 运行,它没有被调用而是崩溃 "Your app stopped working",所以它知道它应该调用它,但没有调用它,对吗?
BroadcastReceiver 似乎每天下午 2 点左右都会被调用,不仅是星期二下午 2 点,我希望应用程序每周更新一次。是否可能是因为我在 UpcomingFragment 的 onCreate 上调用了 setAlarm() 方法?
在 UpcomingFragment class 中(我将闹钟设置为每周二 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 工作室有问题还是我的应用程序有问题.谢谢!
您不能在 BroadCastReceiver
的上下文中操作 Fragment
。本质上,广播接收器 运行 在应用程序上下文中,您无法在其中访问 UI 内容。
如果您想在广播触发后开始 Activity,您需要以下代码:
Intent intent = new Intent(context, MyActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(intent);
注意: 访问 UI(包括片段)必须在 activity 上下文中完成。
更新#1
It seems that the BroadcastReceiver gets called everyday at around 2pm, not only on Tuesdays at 2pm, I want the app to update once a week. Is it maybe because I call my setAlarm() method on my UpcomingFragment's onCreate?
我想我有比你更好的方法。
获取当前时间并将其星期设置为星期二可能会导致 weird behaviors.
使用 boot completed broadcast receiver to set the alarm 可能更好。
对于前者,您的日程安排代码应将闹钟设置为最近的星期二下午 2 点。为此,this answer 可能会有所帮助。
对于后者,首先,将以下权限添加到您的清单文件中。
<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
}
这可确保您的应用在任何情况下都在每周二下午 2 点更新。
我有两个小问题;
我的应用程序的 BroadcastReceiver 在应用程序 运行 时工作正常,我完美地收到了 "Tuesday at 2" toast 消息并且它更新了应用程序,但是当我关闭我的应用程序时,意味着应用程序停止 运行,它没有被调用而是崩溃 "Your app stopped working",所以它知道它应该调用它,但没有调用它,对吗?
BroadcastReceiver 似乎每天下午 2 点左右都会被调用,不仅是星期二下午 2 点,我希望应用程序每周更新一次。是否可能是因为我在 UpcomingFragment 的 onCreate 上调用了 setAlarm() 方法?
在 UpcomingFragment class 中(我将闹钟设置为每周二 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 工作室有问题还是我的应用程序有问题.谢谢!
您不能在 BroadCastReceiver
的上下文中操作 Fragment
。本质上,广播接收器 运行 在应用程序上下文中,您无法在其中访问 UI 内容。
如果您想在广播触发后开始 Activity,您需要以下代码:
Intent intent = new Intent(context, MyActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(intent);
注意: 访问 UI(包括片段)必须在 activity 上下文中完成。
更新#1
It seems that the BroadcastReceiver gets called everyday at around 2pm, not only on Tuesdays at 2pm, I want the app to update once a week. Is it maybe because I call my setAlarm() method on my UpcomingFragment's onCreate?
我想我有比你更好的方法。
获取当前时间并将其星期设置为星期二可能会导致 weird behaviors.
使用 boot completed broadcast receiver to set the alarm 可能更好。
对于前者,您的日程安排代码应将闹钟设置为最近的星期二下午 2 点。为此,this answer 可能会有所帮助。
对于后者,首先,将以下权限添加到您的清单文件中。
<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
}
这可确保您的应用在任何情况下都在每周二下午 2 点更新。