我有一个应用程序,它使用AlarmManager为用户通知安排警报。我将报警对象的一个实例传递给AlarmManager使用的PendingEvent:
public void scheduleAlarms(List<Alarm> alarms)
{
for (Alarm alarm : alarms)
{
Log.d(Constants.EVERY_OTHER_ALARM_APP_LOG_TAG,
"Setting alarm for: " + new Date(alarm.getTime()).toString() +
" with an interval of " +
IntervalEnumStringProvider.getIntervalStringInGivenFormat(
alarm.getInterval(),
true));
PendingIntent alarmScheduledPending = createPendingIntent(alarm);
alarmManager.setRepeating(AlarmManager.RTC_WAKEUP,
alarm.getTime(),
(alarm.getInterval() * Constants.ONE_SECOND_IN_MILLIS),
alarmScheduledPending);
}
}
private PendingIntent createPendingIntent(Alarm alarm)
{
alarmBroadcastReceiverIntent = new Intent(context, AlarmBroadcastReceiver.class);
alarmBroadcastReceiverIntent.putExtra(Constants.SCHEDULED_ALARM_TAG, alarm);
return PendingIntent.getBroadcast(context,
alarm.getIdForPendingIntent(),
alarmBroadcastReceiverIntent,
PendingIntent.FLAG_UPDATE_CURRENT);
}
发生报警时间时,my AlarmBroadcastReceiver(我的AlarmBroadcastReceiver(报警广播接收器))正确接收广播,但LogCat警告未找到报警类:
06-29 08:30:00.084: W/Intent(66): Failure filling in extras
06-29 08:30:00.084: W/Intent(66): java.lang.RuntimeException: Parcelable encounteredClassNotFoundException reading a Serializable object (name = com.fastplanet.everyotheralarmapp.alarm.Alarm)
06-29 08:30:00.084: W/Intent(66): at android.os.Parcel.readSerializable(Parcel.java:1890)
06-29 08:30:00.084: W/Intent(66): at android.os.Parcel.readValue(Parcel.java:1761)
06-29 08:30:00.084: W/Intent(66): at android.os.Parcel.readMapInternal(Parcel.java:1947)
06-29 08:30:00.084: W/Intent(66): at android.os.Bundle.unparcel(Bundle.java:169)
06-29 08:30:00.084: W/Intent(66): at android.os.Bundle.putAll(Bundle.java:242)
06-29 08:30:00.084: W/Intent(66): at android.content.Intent.fillIn(Intent.java:4530)
06-29 08:30:00.084: W/Intent(66): at com.android.server.am.PendingIntentRecord.send(PendingIntentRecord.java:185)
06-29 08:30:00.084: W/Intent(66): at android.app.PendingIntent.send(PendingIntent.java:400)
06-29 08:30:00.084: W/Intent(66): at com.android.server.AlarmManagerService$AlarmThread.run(AlarmManagerService.java:636)
06-29 08:30:00.084: W/Intent(66): Caused by: java.lang.ClassNotFoundException: com.fastplanet.everyotheralarmapp.alarm.Alarm
06-29 08:30:00.084: W/Intent(66): at java.lang.Class.classForName(Native Method)
06-29 08:30:00.084: W/Intent(66): at java.lang.Class.forName(Class.java:237)
06-29 08:30:00.084: W/Intent(66): at java.io.ObjectInputStream.resolveClass(ObjectInputStream.java:2595)
06-29 08:30:00.084: W/Intent(66): at java.io.ObjectInputStream.readNewClassDesc(ObjectInputStream.java:1848)
06-29 08:30:00.084: W/Intent(66): at java.io.ObjectInputStream.readClassDesc(ObjectInputStream.java:852)
06-29 08:30:00.084: W/Intent(66): at java.io.ObjectInputStream.readNewObject(ObjectInputStream.java:2006)
06-29 08:30:00.084: W/Intent(66): at java.io.ObjectInputStream.readNonPrimitiveContent(ObjectInputStream.java:956)
06-29 08:30:00.084: W/Intent(66): at java.io.ObjectInputStream.readObject(ObjectInputStream.java:2289)
06-29 08:30:00.084: W/Intent(66): at java.io.ObjectInputStream.readObject(ObjectInputStream.java:2243)
06-29 08:30:00.084: W/Intent(66): at android.os.Parcel.readSerializable(Parcel.java:1884)
06-29 08:30:00.084: W/Intent(66): ... 8 more
06-29 08:30:00.084: W/Intent(66): Caused by: java.lang.NoClassDefFoundError: com.fastplanet.everyotheralarmapp.alarm.Alarm
06-29 08:30:00.084: W/Intent(66): ... 18 more
06-29 08:30:00.084: W/Intent(66): Caused by: java.lang.ClassNotFoundException: com.fastplanet.everyotheralarmapp.alarm.Alarm in loader dalvik.system.PathClassLoader@4001ad90
06-29 08:30:00.084: W/Intent(66): at dalvik.system.PathClassLoader.findClass(PathClassLoader.java:243)
06-29 08:30:00.084: W/Intent(66): at java.lang.ClassLoader.loadClass(ClassLoader.java:573)
06-29 08:30:00.084: W/Intent(66): at java.lang.ClassLoader.loadClass(ClassLoader.java:532)
06-29 08:30:00.084: W/Intent(66): ... 18 more
然而,BroadcastReceiver成功地从接收到的意图中解包了报警对象,应用程序按预期工作。
发生什么事了?
更新-添加的清单:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.fastplanet.everyotheralarmapp"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk
android:minSdkVersion="4"
android:targetSdkVersion="4" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission android:name="android.permission.SEND_SMS" />
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
<application
android:name=".data.TheEveryOtherAlarmAppApplication"
android:icon="@drawable/ic_launcher"
android:label="@string/app_name" >
<receiver android:name="com.fastplanet.everyotheralarmapp.alarm.AlarmBroadcastReceiver" >
</receiver>
<receiver android:name=".alarm.BootReceiver" >
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
<action android:name="android.intent.action.QUICKBOOT_POWERON" />
</intent-filter>
</receiver>
<activity android:name=".TheEveryOtherAlarmAppActivity"
android:screenOrientation="portrait" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity
android:name=".NewAlarmActivity"
android:screenOrientation="portrait"
android:theme="@android:style/Theme.Dialog" >
</activity>
<activity
android:name=".About"
android:screenOrientation="portrait"
android:theme="@android:style/Theme.Dialog" >
</activity>
<activity
android:name=".AlarmAlertDialogActivity"
android:excludeFromRecents="true"
android:noHistory="true"
android:taskAffinity=""
android:theme="@android:style/Theme.NoDisplay" >
</activity>
<activity
android:name=".AlarmDetailsActivity"
android:screenOrientation="portrait" >
</activity>
</application>
</manifest>
更新2-添加警报类
public class Alarm implements Serializable
{
private static final long serialVersionUID = -5410846652701834321L;
private int id = 0;
private String name = "";
private long interval = 0;
private long time;
private String description;
public Alarm(String name, long time, long interval, String description, int id)
{
this.name = name;
this.time = time;
this.interval = interval;
this.description = description;
this.id = id;
}
public void setInterval(long newAlarmInterval)
{
this.interval = newAlarmInterval;
}
public long getInterval()
{
return interval;
}
public void setTime(long time)
{
this.time = time;
}
public long getTime()
{
return time;
}
public void setName(String name)
{
this.name = name;
}
public String getName()
{
return name;
}
public void setDescription(String newAlarmDescription)
{
this.description = newAlarmDescription;
}
public String getDescription()
{
return description;
}
public int getIdForPendingIntent()
{
return id;
}
@Override
public String toString()
{
return "name: " + name + ", time: "
+ new Date(time).toLocaleString()
+ ", interval: "
+ IntervalEnumStringProvider.getIntervalStringInGivenFormat(interval, true)
+ ", description: " + description
+ ", id: " + id;
}
@Override
public Alarm clone() throws CloneNotSupportedException
{
return new Alarm(new String(name), time, interval, new String(description), id);
}
}
如果您想将警报对象作为Intent中的EXTRA传递,那么您的警报类需要实现Parcelable,而不是Serializable。
编辑:
看来这不是真的。看起来您可以使用Serializable。然而,OP无法实现这一点,SE上还有其他帖子,人们在实现这一点时遇到了问题。
像
ClassNotFoundException: com.fastplanet.everyotheralarmapp.alarm.Alarm in loader
<receiver android:name=".alarm.BootReceiver" >
我一直在纠结这个问题,解决方法是(这里归功于mazur):
这是android的一个缺陷。我的目标API是19,最小API是11。此处输入缺陷:“使用自定义包裹时ClassNotFoundException”https://code.google.com/p/android/issues/detail?id=6822
注册报警时:
Bundle bundle = new Bundle();
bundle.putParcelable("com.foo.alarm", alert);
mNotificationReceiverIntent.putExtra("com.foo.alarm",bundle);
mNotificationReceiverPendingIntent = PendingIntent.getBroadcast(this,
0, mNotificationReceiverIntent, 0);
收到警报时,
Bundle oldBundle = intent.getBundleExtra("com.foo.alarm");
Alert alert = oldBundle.getParcelable("com.foo.alarm");
问题内容: 有人可以解释和之间的确切区别吗? 在什么情况下我们必须使用每个Receiver类? 问题答案: 和之间只有一个区别。 当您收到内部广播方法时, 假设, BroadcastReceiver : 它 不保证 该 CPU将保持清醒 ,如果你启动一些长时间运行的进程。CPU可能会立即回到睡眠状态。 WakefulBroadcastReceiver : 这是 保证 该 CPU将保持清醒 ,直到你
通知广播接收机: 谁能帮帮我吗?我不知道我做错了什么
所以我尝试使用redis设置广播,但是我无法让它工作,因为我想我缺少一些配置选项。 . env文件 控制器 测试员。php 但是,当我在数据库的failed_jobs表中运行此操作时,会弹出以下错误: Symfony\Component\Debug\Exception\fatalthrowable错误:在/var/www/vendor/light/broadcasting/BroadcastMan
4.2.1.3 内部广播接收器 内部广播接收器是广播接收器,它将永远不会收到从内部应用以外发送的任何广播。 它由几个内部应用组成,用于保护内部应用处理的信息或功能。 要点(接收广播): 定义内部签名权限来接收广播。 声明使用内部签名权限来接收结果。 将导出属性显式设置为true。 需要静态广播接收器定义的内部签名权限。 需要内部签名来注册动态广播接收器。 确认内部签名权限是由内部应用定义的。 尽管
4.2.1.2 公共广播接收器 公共广播接收器是可以从未指定的大量应用程序接收广播的广播接收器,因此有必要注意,它可能从恶意软件接收广播。 要点(接收广播): 将导出属性显式设为true。 小心并安全地处理收到的意图。 返回结果时,不要包含敏感信息。 公共广播接收器的示例代码可以用于静态和动态广播接收器。 PublicReceiver.java package org.jssec.android.
4.2.1.1 私有广播接收器 私人广播接收器是最安全的广播接收器,因为只能接收到从应用内发送的广播。 动态广播接收器不能注册为私有,所以私有广播接收器只包含静态广播接收器。 要点(接收广播): 将导出属性显示设为false 小心并安全地处理收到的意图,即使意图从相同的应用中发送 敏感信息可以作为返回结果发送,因为请求来自相同应用 AndroidManifest.xml <?xml version