【问题标题】:getParcelableExtra always null on Pending Intent, but not IntentgetParcelableExtra 在 Pending Intent 上始终为空,但不是 Intent
【发布时间】:2013-10-13 11:37:59
【问题描述】:

我是 Java 新手,更不用说 Android 开发了。我没有编码背景,但我想我会从一些“简单”的东西开始,比如闹钟。所以现在我正在编写一个闹钟,如果它们在响起后没有重复,我想将它们更新为非活动状态。当我带着一个意图将一个可打包的 AlarmClass(我的警报对象)传递到警报设置屏幕时,它通过就好了。 当我将相同的 AlarmClass 传递给一个意图,并将其放在警报管理器中的 PendingIntent 中,然后尝试从可以解除警报的屏幕中获取它时,我正在调用的 AlarmClass 对象并以完全相同的方式填充始终为空。

这是我的闹钟课程:

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

我在这里的时间设定器上收到它就好了。它是非空的:

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 的传递的 parcelable 对象始终为 null。

有谁知道为什么一个可打包的对象在一个意图中工作得很好,但在 PendingIntent 的另一边却是空的?

【问题讨论】:

    标签: android object null android-pendingintent parcelable


    【解决方案1】:

    编辑: 我认为您的问题出在这一行:

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

    您不是在此处开始活动,而是广播尝试按如下方式更改它:

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

    【讨论】:

    • 好的,等我回来试试。那么除了 getActivity 调用之外,我还需要使用具有唯一名称的“setActivity”吗?上次我这样做时,我无法取消附加了“.cancel()”的待处理意图。我真的很感激帮助。我正在学习,但错综复杂的东西仍然比我想的更频繁。
    • 嗯...看起来如果我使用 getActivity 而不是 getBroadcast,我的警报将不再在指定时间触发。
    • 将上下文调用更改为 getApplicationContext() 有效。 “这个”没有。谢谢您的帮助!上次我试了一下,我一定也有其他问题。
    • 这里只是为了澄清。当我最终得到这个工作时,那是因为我没有在广播接收器中重新附加额外的东西。所以他们在我试图让他们参加的活动之前就被丢弃了。
    【解决方案2】:

    【讨论】:

    • 我一定会尝试使用 bundle hack 看看是否可行。对于像我这样的菜鸟来说,这似乎比尝试编组和解组自己更简单。谢谢!
    【解决方案3】:

    事实证明,ParcelableExtra 被广播接收器丢弃了!我确实通过了它,但是,当广播接收器启动活动时,它没有重新附加附加功能;导致 Activity 在尝试获取 ParcelableExtras 时为空。

    【讨论】:

    • 有什么解决办法
    【解决方案4】:

    试试

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

    而不是

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

    如果它不起作用

    使 AlarmClass 扩展 Serializable 而不是 Parceable。

    【讨论】:

      猜你喜欢
      • 2019-11-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-08-19
      相关资源
      最近更新 更多