Android AlarmReceiver 和 BootReceiver

发布于 2024-12-03 05:43:25 字数 7036 浏览 0 评论 0原文

在我的应用程序中,我创建警报。因此,当手机重新启动时,我需要再次创建警报。

但是,当我重新启动手机(模拟器)并且必须创建警报时,会强制关闭。它说:

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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

愿得七秒忆 2024-12-10 05:43:26

上面的解决方案不是我想要的..但​​万一有人遇到像我一样的问题(我使用的是短路径):

将其放入您的 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

空心空情空意 2024-12-10 05:43:25

为 AlarmReceiver 提供完全限定名称

<receiver android:name="com.yannv.vehiclesmanager.AlarmReceiver">
    <intent-filter>
        <action
            android:name="afficherNotification" />
        <data
            android:scheme="rappel" />
    </intent-filter>
</receiver>

检查 AlarmReceiver 类中的包名称。它应该只是这样

package com.yannv.vehiclesmanager;

give the fully qualified name to the AlarmReceiver

<receiver android:name="com.yannv.vehiclesmanager.AlarmReceiver">
    <intent-filter>
        <action
            android:name="afficherNotification" />
        <data
            android:scheme="rappel" />
    </intent-filter>
</receiver>

check the package name in the AlarmReceiver class.It should be like this only

package com.yannv.vehiclesmanager;
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文