将Serializable对象传递给Pending Intent

时间:2016-11-08 06:30:32

标签: java android android-intent serialization

我正在尝试将可序列化对象发送到待处理的Intent。问题是收到的警报返回为null。即使Alarm实现了可序列化的接口。

//AlarmService.java

Intent myIntent = new Intent(getApplicationContext(), AlarmAlertBroadcastReciever.class);
Bundle bundle = new Bundle();
bundle.putSerializable("alarm", alarm);
myIntent.putExtras(bundle);
PendingIntent pendingIntent = PendingIntent.getBroadcast(getApplicationContext(), 0, myIntent, PendingIntent.FLAG_CANCEL_CURRENT);

AlarmManager alarmManager = (AlarmManager)getApplicationContext().getSystemService(Context.ALARM_SERVICE);

alarmManager.set(AlarmManager.RTC_WAKEUP, alarm.getAlarmTime().getTimeInMillis(), pendingIntent);

收到的警报为空。

//AlarmAlertBroadcastReceiver.java

public class AlarmAlertBroadcastReciever extends BroadcastReceiver {
    @Override
    public void onReceive(Context context, Intent intent) {
        Alarm alarm = (Alarm)intent.getExtras().getSerializable("alarm");
    }
}

编辑: 我尝试过的更多内容如下,但它似乎不起作用:

//AlarmService.java

Intent myIntent = new Intent(getApplicationContext(), AlarmAlertBroadcastReciever.class);
myIntent.putExtra("alarm", alarm);
myIntent.setAction("abc.xyz");

PendingIntent pendingIntent = PendingIntent.getBroadcast(getApplicationContext(), 0, myIntent, PendingIntent.FLAG_UPDATE_CURRENT);

AlarmManager alarmManager = (AlarmManager)getApplicationContext().getSystemService(Context.ALARM_SERVICE);

alarmManager.set(AlarmManager.RTC_WAKEUP, alarm.getAlarmTime().getTimeInMillis(), pendingIntent);

收到的警报为空。

//AlarmAlertBroadcastReceiver.java

public class AlarmAlertBroadcastReciever extends BroadcastReceiver {
    @Override
    public void onReceive(Context context, Intent intent) {
        Alarm alarm = (Alarm)intent.getExtras().getSerializable("alarm");
      //Alarm alarm = (Alarm)intent.getSerializableExtra("alarm");
    }
}

7 个答案:

答案 0 :(得分:9)

将自定义对象放入Intent然后传递给AlarmManagerNotificationManager或其他外部应用程序时存在已知问题。您可以尝试将自定义对象包装在Bundle中,因为这有时会起作用。例如,将代码更改为:

Intent myIntent = new Intent(getApplicationContext(), 
                             AlarmAlertBroadcastReciever.class);
Bundle bundle = new Bundle();
bundle.putSerializable("alarm", alarm);
myIntent.putExtra("bundle", bundle);

AlarmAlertBroadcastReciever.onReceive()

Bundle bundle = intent.getBundleExtra("bundle");
if (bundle != null) {
    Alarm alarm = (Alarm)bundle.getSerializable("alarm");
}

如果这不起作用(这应该适用于大多数Android版本/设备,但不是全部,尤其是非常新版本),您需要将Serializeable对象转换为byte[]和将byte[]放入附加内容。

有很多关于如何在Stackoverflow上执行此操作的示例。

答案 1 :(得分:2)

我正在使用android Nougat,所以这些答案都没有奏效。我最终以字节数组传递对象。

//AlarmService.java

Intent myIntent = new Intent(getApplicationContext(), AlarmAlertBroadcastReciever.class);
ByteArrayOutputStream bos = new ByteArrayOutputStream();
ObjectOutputStream out = null;
try {
    out = new ObjectOutputStream(bos);
    out.writeObject(alarm);
    out.flush();
    byte[] data = bos.toByteArray();
    myIntent.putExtra("alarm", data);
} catch (IOException e) {
    e.printStackTrace();
} finally {
    try {
        bos.close();
    } catch (IOException ex) {
        ex.printStackTrace();
    }
}

PendingIntent pendingIntent = PendingIntent.getBroadcast(getApplicationContext(), 0, myIntent, PendingIntent.FLAG_CANCEL_CURRENT);

AlarmManager alarmManager = (AlarmManager) getApplicationContext().getSystemService(Context.ALARM_SERVICE);
alarmManager.set(AlarmManager.RTC_WAKEUP, alarm.getAlarmTime().getTimeInMillis(), pendingIntent);

然后我收到了Byte []

//AlarmAlertBroadcastReceiver.java

@Override
public void onReceive(Context context, Intent intent) {
   ByteArrayInputStream bis = new ByteArrayInputStream(intent.getByteArrayExtra("alarm"));
    ObjectInput in = null;
    Alarm alarm = null;
    try {
        in = new ObjectInputStream(bis);
        alarm = (Alarm)in.readObject();
    } catch (ClassNotFoundException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    } finally {
        try {
            if (in != null) {
                in.close();
            }
        } catch (IOException ex) {
            ex.printStackTrace();
        }
    }
}

答案 2 :(得分:0)

你在Bundle中有putSerializable。你试图从getSerializable开始。

For set : `myIntent.putExtra("alarm", alarm);` 
For get : `(Alarm)intent.getExtras().getSerializableExtra("alarm");` 
Also make sure your `Alarm` calss have `implements` with `Serializable`.

试试。

答案 3 :(得分:0)

Intent putExtra(String name,                 可分配价值)

将扩展数据添加到intent中。名称必须包含包前缀,例如app com.android.contacts将使用" com.android.contacts.ShowAll"等名称。

Reference

答案 4 :(得分:0)

这是一个建议,你可以尝试parcelabler,这是更有效和针对Android特定需求量身定制的。 所以让你的模型类分为here. 之后粘贴到您的项目中,然后使用bundle

将其传递给另一个活动
intent.putParcelableArrayListExtra("Parcelaber",myList);

Action

答案 5 :(得分:0)

我想提出两件事:

  1. 您需要将yourIntent.setAction("abc.xyz")设置为您的意图,例如:FLAG_UPDATE_CURRENT
  2. 您应该使用FLAG_CANCEL_CURRENT代替{{1}}
  3. 希望它有所帮助。

答案 6 :(得分:0)

您是否尝试过除0以外的任何其他请求ID

例如

int requestID = (int) System.currentTimeMillis();

PendingIntent pendingIntent = PendingIntent.getBroadcast(getApplicationContext(), requestID , myIntent, PendingIntent.FLAG_UPDATE_CURRENT);

 public void onReceive(Context context, Intent intent) {

        if(intent!=null && intent.hasExtra("alarm")){
        Alarm alarm = (Alarm)intent.getExtras().getSerializable("alarm");
        }

    }