2

Android開発は言うまでもなく、Javaは初めてです。コーディングのバックグラウンドはありませんが、目覚まし時計のような「単純な」ものから始めようと思いました。だから今、私は目覚まし時計を書いています。アラームが鳴った後に繰り返されない場合は、アラームを更新して非アクティブにしたいと考えています。パーセル可能な AlarmClass (アラーム オブジェクト) をインテントでアラーム設定画面に渡すと、問題なく渡されます。同じ AlarmClass をインテントに渡し、それを Alarm Manager の PendingIntent に入れてから、アラームを閉じることができる画面から取得しようとすると、まったく同じ方法で呼び出して入力している AlarmClass オブジェクトは常に null です。

これが私のアラームクラスです:

package com.example.wakeme;

import java.util.Calendar;

import android.os.Parcel;
import android.os.Parcelable;

public class AlarmClass implements Parcelable{
    Calendar cal = Calendar.getInstance();
    private long id = 1;
    private int active = 1;
    private long time = cal.getTimeInMillis();
    private int repeating = 0;
    private int skipweekends = 0;
    private int skipweekdays = 0;
    private int alarmnumber = -1;


    public long getId(){
        return id;
    }

    public void setId(long id) {
        this.id = id;
    }

    public int getActive(){
        return active;
    }

    public void setActive(int active) {
        this.active = active;
    }

    public int getRepeating(){
        return repeating;
    }

    public void setRepeating(int repeating){
        this.repeating = repeating;
    }

    public void setTime(long time){
        this.time = time;
    }

    public long getTime(){
        return time;
    }

    public int getSkipWeekends(){
        return skipweekends;
    }

    public void setSkipWeekends(int skipweekends){
        this.skipweekends = skipweekends;
    }

    public int getSkipWeekdays(){
        return skipweekdays;
    }

    public void setSkipWeekdays(int skipweekdays){
        this.skipweekdays = skipweekdays;
    }

    public void setAlarmNumber(int alarmnumber){
        this.alarmnumber = alarmnumber;
    }

    public int getAlarmNumber(){
        return alarmnumber;
    }

    @Override
    public int describeContents(){
        return 0;
    }

    private AlarmClass(Parcel in){
        this.id = in.readLong();
        this.active = in.readInt();
        this.repeating = in.readInt();
        this.skipweekdays = in.readInt();
        this.skipweekends = in.readInt();
        this.time = in.readLong();
        this.alarmnumber = in.readInt();
    }

    AlarmClass() {
        return;
    }

    public void writeToParcel(Parcel out, int flags) {
        out.writeLong(this.id);
        out.writeInt(this.active);
        out.writeInt(this.repeating);
        out.writeInt(this.skipweekdays);
        out.writeInt(this.skipweekends);
        out.writeLong(this.time);
        out.writeInt(this.alarmnumber);
    }

    public static final Parcelable.Creator<AlarmClass> CREATOR = new Parcelable.Creator<AlarmClass>(){
        public AlarmClass createFromParcel(Parcel in){
            return new AlarmClass(in);
        }
        public AlarmClass[] newArray(int size) {
            return new AlarmClass[size];
        }
    };

ここから、オブジェクトをアラーム セッターに渡して問題なく更新できます。

public void startSet(View view){
        Intent set = new Intent(this, SetAlarm.class);
        set.putExtra("alarm", new AlarmClass());
        startActivity(set);
    }

そして、ここのタイムセッターで問題なく受信します。null ではありません:

public class SetAlarm extends MainActivity {
    AlarmClass passAlarm = new AlarmClass();


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.alarm_set);
        setAlarmSetListener();
        setDeleteListener();
        passAlarm = (AlarmClass) getIntent().getParcelableExtra("alarm");
        if(passAlarm.getAlarmNumber() != -1){
            TimePicker picker = (TimePicker) findViewById(R.id.timePicker1);
            Calendar passedTime = Calendar.getInstance();
            passedTime.setTimeInMillis(passAlarm.getTime());
            picker.setCurrentHour(passedTime.get(Calendar.HOUR_OF_DAY));
            picker.setCurrentMinute(passedTime.get(Calendar.MINUTE));
            String ampm = (passedTime.get(Calendar.HOUR_OF_DAY) > 12 ? "pm" : "am");
            String message = "Passed Time is: " + (passedTime.get((Calendar.HOUR_OF_DAY)%12)!=0?(passedTime.get(Calendar.HOUR_OF_DAY)%12):12) + ":" + passedTime.get(Calendar.MINUTE) + " " + ampm;
            Toast.makeText(getApplicationContext(), message, Toast.LENGTH_SHORT).show();
        }
        else{
        // Do Nothing
        }

    }

しかし、PendingIntent を介して次のように送信された場合:

private void newAlarm(AlarmClass alarmclass){
        Intent intent = new Intent(getBaseContext(), Alarm.class);
        intent.putExtra("alarm", alarmclass);
        Calendar cal = Calendar.getInstance();
        cal.setTimeInMillis(alarmclass.getTime());
        AlarmsDataSource alarm =  new AlarmsDataSource(this);
        alarm.open();
        AlarmClass alarmObject = new AlarmClass();
        alarmObject = alarm.createAlarm(true, cal.getTimeInMillis(), false, false, false);
        PendingIntent torpedo = PendingIntent.getBroadcast(this,alarmObject.getAlarmNumber(),intent,PendingIntent.FLAG_UPDATE_CURRENT);
        AlarmManager goOff = (AlarmManager) getSystemService(ALARM_SERVICE);
        goOff.set(AlarmManager.RTC_WAKEUP, alarmObject.getTime() ,torpedo);
        Toast.makeText(getApplicationContext(), "Alarm Number " + alarmObject.getAlarmNumber(), Toast.LENGTH_LONG).show();
        alarm.close();
    }

アラーム アクティビティでも同じように受信されます。

public class Boom extends MainActivity{
AlarmClass boomAlarm = new AlarmClass();

        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            final Window wake = getWindow();
            wake.addFlags(WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON | WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD);
            setContentView(R.layout.boom);
            setTheme(R.style.AlarmStyle);
            overridePendingTransition(android.R.anim.fade_in,5000);
            boomAlarm = (AlarmClass) getIntent().getParcelableExtra("alarm");
    //      Vibrator buzz = (Vibrator) getSystemService(VIBRATOR_SERVICE);
    //      buzz.vibrate(1000);
            snoozeListener();
            dismissListener();
        }

boomAlarm に渡すパーセル可能なオブジェクトは常に null です。

パーセル可能なオブジェクトがインテントで問題なく機能するのに、PendingIntent の反対側で null になる理由を知っている人はいますか?

4

4 に答える 4

4

カスタム Parcelable を使用しているときに ClassNotFoundException に似た問題に直面しているようです

https://code.google.com/p/android/issues/detail?id=6822で説明されている回避策と、カスタム Parcelable を使用する場合の ClassNotFoundException の回答があります。

于 2014-01-15T15:48:48.970 に答える
0

編集:あなたの問題はこの行にあると思います:

PendingIntent torpedo = PendingIntent.getBroadcast(this,alarmObject.getAlarmNumber(),intent,PendingIntent.FLAG_UPDATE_CURRENT);

ここでアクティビティを開始していませんが、BroadCast は次のように変更を試みます。

PendingIntent torpedo = PendingIntent.getActivity(this,alarmObject.getAlarmNumber(),intent,PendingIntent.FLAG_UPDATE_CURRENT);

に変更PendingIntent.getBroadcast()PendingIntent.getActivity()ます。

そして、次のように変更してみてください。

Intent intent = new Intent(getBaseContext(), Alarm.class);

Intent intent = new Intent(this , Alarm.class);

また

Intent intent = new Intent(getApplicationContext(), Alarm.class);
于 2013-10-07T01:39:35.590 に答える
0

試す

boomAlarm = (AlarmClass) getIntent().getExtras().get("alarm");

それ以外の

boomAlarm = (AlarmClass) getIntent().getParcelableExtra("alarm");

うまくいかない場合

make AlarmClass は、Parceable ではなく Serializable を拡張します。

于 2016-11-04T13:27:43.920 に答える