3

私はAlarmManagerを使用してユーザー通知のアラームをスケジュールするアプリを持っています。AlarmManagerによって使用されるPendingIntentにAlarmオブジェクトのインスタンスを渡します。

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);
}

アラーム時刻が発生すると、AlarmBroadcastReceiverクラスはブロードキャストを正しく受信しますが、LogCatはAlarmクラスが見つからなかったことを警告します。

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は受信したインテントからAlarmオブジェクトを正常に解凍し、アプリは期待どおりに機能します。

どうしたの?

更新-マニフェストを追加:

<?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>

UPDATE2-アラームクラスの追加

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);
    }
}
4

5 に答える 5

8

私はこの問題に苦労しました。解決策は次のとおりです(mazurの功績はこちら):

これはアンドロイドの欠陥です。私のターゲット API は 19 で、最小 API は 11 です。欠陥はここに入力されます。

アラーム登録時:

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");
于 2014-03-12T02:15:15.970 に答える
0

なので

ClassNotFoundException: com.fastplanet.everyotheralarmapp.alarm.Alarm in loader

<receiver android:name=".alarm.BootReceiver" >
于 2012-06-29T08:41:09.083 に答える
0

Android 2.3でも同じ問題がありました。

次の変更を行った後、シリアライズ可能なエクストラを BroadcastReceiver に渡すことが機能するようになりました。

  • PendingIntent の Action 文字列で Intent を作成します。
  • AndroidManifest に BroadcastReceiver を静的に登録します。
于 2013-04-01T23:14:10.107 に答える
0

ADT17 を使用しても同じ問題が発生しますが、BroadcastReceiver が起動しません。SO: Tried to change Proguard Configuration で説明したことを試しましたが、Proguard はデフォルトで無効になっていることが判明しました。実装しようとしましParcelableたが、問題はまだ残っています。機能した唯一のことは、BroadCastReceiver を、受信するオブジェクトのクラスが存在する同じパッケージに配置することでした。OPで説明されているように、例外は引き続き警告としてスローされることに注意してください。

于 2012-12-17T16:43:32.610 に答える
0

インテントでアラーム オブジェクトを EXTRA として渡したい場合、アラーム クラスはシリアライズ可能ではなく、パーセル可能を実装する必要があります。

編集:

これは正しくないようです。Serializable を使用できるようです。ただし、OPはこれを機能させることができず、SEには他の投稿があり、これを機能させるのに問題がありました。

于 2012-06-29T08:55:43.843 に答える