Android AlarmReceiver 和 BootReceiver
在我的应用程序中,我创建警报。因此,当手机重新启动时,我需要再次创建警报。
但是,当我重新启动手机(模拟器)并且必须创建警报时,会强制关闭。它说:
Unable to instantiate receiver com.yannv.vehiclesmanager.AlarmReceiver:
java.lang.ClassNotFoundException: com.yannv.vehiclesmanager.AlarmReceiver in loader
dalvik.system.PathClassLoader[/data/app/com..etc]
这是我的清单的相关部分(不知道问题是否来自那里..)
<receiver android:name="AlarmReceiver">
<intent-filter>
<action
android:name="afficherNotification" />
<data
android:scheme="rappel" />
</intent-filter>
</receiver>
<receiver android:name="com.yannv.vehiclesmanager.BootReceiver">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
</receiver>
</application>
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
感谢您的帮助
BootReceiver Class :
package com.yannv.vehiclesmanager;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import android.app.AlarmManager;
import android.app.PendingIntent;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.database.Cursor;
public class BootReceiver extends BroadcastReceiver{
/*Lorsqu'on éteint le téléphone, les alarmes sont supprimées. Cette méthode est appelée
au démarrage du téléphone et sert à recréer les alarmes*/
public void onReceive(Context context, Intent in) {
final int NOT_AUCUN = 0; //ID des possibilités de notification
final int NOT_AU_DEBUT = 1;
final int NOT_10_MINUTES = 2;
final int NOT_30_MINUTES = 3;
final int NOT_1_HEURE = 4;
final int NOT_2_HEURES = 5;
final int NOT_3_HEURES = 6;
final int NOT_12_HEURES = 7;
final int NOT_24_HEURES = 8;
final int NOT_2_JOURS = 9;
final int NOT_1_SEMAINE = 10;
final int ID_COLUMN_ID = 0;
final int ID_COLUMN_DATE = 2;
final int ID_COLUMN_HEURE = 4;
final int ID_COLUMN_NOTIF = 7;
int heures;
int minutes;
int annee;
int mois;
int jour;
Intent intent = new Intent(context, AlarmReceiver.class);
Date dateRappel = null;
Date dateNotif;
final SimpleDateFormat dateFormatDB = new SimpleDateFormat ("yyyy'.'MM'.'dd");
DBAdapter db;
AlarmManager am = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
db = new DBAdapter(context);
db.open();
Cursor c = db.recupListeRappelAVenir();
c.moveToFirst();
for(int i=0;i<c.getCount();i++){
try {
dateRappel = dateFormatDB.parse(c.getString(ID_COLUMN_DATE).toString());
} catch (ParseException e) {
e.printStackTrace();
}
String[] heureRappel = c.getString(ID_COLUMN_HEURE).toString().split(":");
heures = (int) Integer.parseInt(heureRappel[0]);
minutes = (int) Integer.parseInt(heureRappel[1]);
annee = dateRappel.getYear();
mois = dateRappel.getMonth();
jour = dateRappel.getDay();
dateNotif = null;
dateNotif = new Date (annee, mois, jour, heures, minutes);
PendingIntent sender = PendingIntent.getBroadcast(context, c.getInt(ID_COLUMN_ID), intent, 0);
switch(c.getInt(ID_COLUMN_NOTIF)){
case NOT_AUCUN :
//Pas de notification
dateNotif = null;
break;
case NOT_AU_DEBUT :
//On ne fait rien
break;
case NOT_10_MINUTES :
dateNotif.setTime(dateNotif.getTime()- 600000);
break;
case NOT_30_MINUTES :
dateNotif.setTime(dateNotif.getTime()- 1800000);
break;
case NOT_1_HEURE :
dateNotif.setTime(dateNotif.getTime()- 3600000);
break;
case NOT_2_HEURES :
dateNotif.setTime(dateNotif.getTime()- 7200000);
break;
case NOT_3_HEURES :
dateNotif.setTime(dateNotif.getTime()- 10800000);
break;
case NOT_12_HEURES :
dateNotif.setTime(dateNotif.getTime()- 43200000);
break;
case NOT_24_HEURES :
dateNotif.setTime(dateNotif.getTime()- 86400000);
break;
case NOT_2_JOURS :
dateNotif.setTime(dateNotif.getTime() - 172800000);
break;
case NOT_1_SEMAINE :
dateNotif.setTime(dateNotif.getTime() - 604800000);
break;
}
if (dateNotif != null){
am.set(AlarmManager.RTC_WAKEUP, dateNotif.getTime(), sender);
}
c.moveToNext();
}
c.close();
db.close();
}
}
AlarmReceiver Class
package com.yannv.vehiclesmanager;
import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.util.Log;
import android.widget.Toast;
public class AlarmReceiver extends BroadcastReceiver{
@Override
public void onReceive(Context context, Intent intent) {
try {
//Création de la notification
NotificationManager nm = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
int icon = R.drawable.icon;
CharSequence tickerText = "Notification de Vehicles Manager";
long when = System.currentTimeMillis();
CharSequence contentTitle = "Vehicles Manager : rappel !";
CharSequence contentText = "Pressez pour voir la liste des rappels";
Intent notificationIntent = new Intent(context, Rappel.class);
PendingIntent contentIntent = PendingIntent.getActivity(context, 0, notificationIntent, 0);
Notification notification = new Notification(icon, tickerText, when);
notification.setLatestEventInfo(context, contentTitle, contentText, contentIntent);
notification.defaults |= Notification.DEFAULT_SOUND;
notification.defaults |= Notification.DEFAULT_VIBRATE;
notification.flags = Notification.FLAG_AUTO_CANCEL;
nm.notify(0, notification);
} catch (Exception exception) {
Toast.makeText(context, "Vehicle's Manager : erreur lors du lancement d'une notification", Toast.LENGTH_LONG).show();
Log.e("ALARM_RECEIVER", exception.toString());
}
}
}
编辑:问题已解决。看来我所有的问题都来自 BootReceiver 类的这一行:
jour = dateRappel.getDay();
我将其替换为
jour = dateRappel.getDate();
And it Works。
In my application, I create alarms. So, when the phone is rebooted, I need to create again the alarms.
But when I reboot the phone (emulator) and that alarms must be created, there is a Force Close. It says :
Unable to instantiate receiver com.yannv.vehiclesmanager.AlarmReceiver:
java.lang.ClassNotFoundException: com.yannv.vehiclesmanager.AlarmReceiver in loader
dalvik.system.PathClassLoader[/data/app/com..etc]
Here is the concerned part of my manifest (don't know if problem comes from there..)
<receiver android:name="AlarmReceiver">
<intent-filter>
<action
android:name="afficherNotification" />
<data
android:scheme="rappel" />
</intent-filter>
</receiver>
<receiver android:name="com.yannv.vehiclesmanager.BootReceiver">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
</receiver>
</application>
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
Thanks for your help
BootReceiver Class :
package com.yannv.vehiclesmanager;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import android.app.AlarmManager;
import android.app.PendingIntent;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.database.Cursor;
public class BootReceiver extends BroadcastReceiver{
/*Lorsqu'on éteint le téléphone, les alarmes sont supprimées. Cette méthode est appelée
au démarrage du téléphone et sert à recréer les alarmes*/
public void onReceive(Context context, Intent in) {
final int NOT_AUCUN = 0; //ID des possibilités de notification
final int NOT_AU_DEBUT = 1;
final int NOT_10_MINUTES = 2;
final int NOT_30_MINUTES = 3;
final int NOT_1_HEURE = 4;
final int NOT_2_HEURES = 5;
final int NOT_3_HEURES = 6;
final int NOT_12_HEURES = 7;
final int NOT_24_HEURES = 8;
final int NOT_2_JOURS = 9;
final int NOT_1_SEMAINE = 10;
final int ID_COLUMN_ID = 0;
final int ID_COLUMN_DATE = 2;
final int ID_COLUMN_HEURE = 4;
final int ID_COLUMN_NOTIF = 7;
int heures;
int minutes;
int annee;
int mois;
int jour;
Intent intent = new Intent(context, AlarmReceiver.class);
Date dateRappel = null;
Date dateNotif;
final SimpleDateFormat dateFormatDB = new SimpleDateFormat ("yyyy'.'MM'.'dd");
DBAdapter db;
AlarmManager am = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
db = new DBAdapter(context);
db.open();
Cursor c = db.recupListeRappelAVenir();
c.moveToFirst();
for(int i=0;i<c.getCount();i++){
try {
dateRappel = dateFormatDB.parse(c.getString(ID_COLUMN_DATE).toString());
} catch (ParseException e) {
e.printStackTrace();
}
String[] heureRappel = c.getString(ID_COLUMN_HEURE).toString().split(":");
heures = (int) Integer.parseInt(heureRappel[0]);
minutes = (int) Integer.parseInt(heureRappel[1]);
annee = dateRappel.getYear();
mois = dateRappel.getMonth();
jour = dateRappel.getDay();
dateNotif = null;
dateNotif = new Date (annee, mois, jour, heures, minutes);
PendingIntent sender = PendingIntent.getBroadcast(context, c.getInt(ID_COLUMN_ID), intent, 0);
switch(c.getInt(ID_COLUMN_NOTIF)){
case NOT_AUCUN :
//Pas de notification
dateNotif = null;
break;
case NOT_AU_DEBUT :
//On ne fait rien
break;
case NOT_10_MINUTES :
dateNotif.setTime(dateNotif.getTime()- 600000);
break;
case NOT_30_MINUTES :
dateNotif.setTime(dateNotif.getTime()- 1800000);
break;
case NOT_1_HEURE :
dateNotif.setTime(dateNotif.getTime()- 3600000);
break;
case NOT_2_HEURES :
dateNotif.setTime(dateNotif.getTime()- 7200000);
break;
case NOT_3_HEURES :
dateNotif.setTime(dateNotif.getTime()- 10800000);
break;
case NOT_12_HEURES :
dateNotif.setTime(dateNotif.getTime()- 43200000);
break;
case NOT_24_HEURES :
dateNotif.setTime(dateNotif.getTime()- 86400000);
break;
case NOT_2_JOURS :
dateNotif.setTime(dateNotif.getTime() - 172800000);
break;
case NOT_1_SEMAINE :
dateNotif.setTime(dateNotif.getTime() - 604800000);
break;
}
if (dateNotif != null){
am.set(AlarmManager.RTC_WAKEUP, dateNotif.getTime(), sender);
}
c.moveToNext();
}
c.close();
db.close();
}
}
AlarmReceiver Class
package com.yannv.vehiclesmanager;
import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.util.Log;
import android.widget.Toast;
public class AlarmReceiver extends BroadcastReceiver{
@Override
public void onReceive(Context context, Intent intent) {
try {
//Création de la notification
NotificationManager nm = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
int icon = R.drawable.icon;
CharSequence tickerText = "Notification de Vehicles Manager";
long when = System.currentTimeMillis();
CharSequence contentTitle = "Vehicles Manager : rappel !";
CharSequence contentText = "Pressez pour voir la liste des rappels";
Intent notificationIntent = new Intent(context, Rappel.class);
PendingIntent contentIntent = PendingIntent.getActivity(context, 0, notificationIntent, 0);
Notification notification = new Notification(icon, tickerText, when);
notification.setLatestEventInfo(context, contentTitle, contentText, contentIntent);
notification.defaults |= Notification.DEFAULT_SOUND;
notification.defaults |= Notification.DEFAULT_VIBRATE;
notification.flags = Notification.FLAG_AUTO_CANCEL;
nm.notify(0, notification);
} catch (Exception exception) {
Toast.makeText(context, "Vehicle's Manager : erreur lors du lancement d'une notification", Toast.LENGTH_LONG).show();
Log.e("ALARM_RECEIVER", exception.toString());
}
}
}
EDIT : Problem solved. It seems that all my problems came from this line of the BootReceiver class:
jour = dateRappel.getDay();
I replace it by
jour = dateRappel.getDate();
And it works.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
上面的解决方案不是我想要的..但万一有人遇到像我一样的问题(我使用的是短路径):
将其放入您的
AndroidManifest.xml
之前 < code>:<接收者
android:name="com.path.to.your.receiver.MyAlarmReceiver"
安卓:导出=“假”
android:process=":remote" >
<意图过滤器>
<动作 android:name="com.socialparc.TIMES_UP" />
“path.to.your.receiver”可能是 com.example.MyAlarmReceiver.. 取决于您选择的文件结构
The above solutions were not what I was looking for .. but on the off chance that someone had a problem like I did (I was using the short path):
Put this in your
AndroidManifest.xml
before</application>
:<receiver
android:name="com.path.to.your.receiver.MyAlarmReceiver"
android:exported="false"
android:process=":remote" >
<intent-filter>
<action android:name="com.socialparc.TIMES_UP" />
</intent-filter>
</receiver>
"path.to.your.receiver" might be com.example.MyAlarmReceiver.. depends on the file structure you chose
为 AlarmReceiver 提供完全限定名称
检查 AlarmReceiver 类中的包名称。它应该只是这样
give the fully qualified name to the AlarmReceiver
check the package name in the AlarmReceiver class.It should be like this only