将Serializable对象传递给Pending Intent

Mar*_*ski 6 java serialization android android-intent

我正在尝试将一个可序列化的对象发送到待处理的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);
Run Code Online (Sandbox Code Playgroud)

收到的警报为空.

//AlarmAlertBroadcastReceiver.java

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

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

//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);
Run Code Online (Sandbox Code Playgroud)

收到的警报为空.

//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");
    }
}
Run Code Online (Sandbox Code Playgroud)

Dav*_*ser 12

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

Intent myIntent = new Intent(getApplicationContext(), 
                             AlarmAlertBroadcastReciever.class);
Bundle bundle = new Bundle();
bundle.putSerializable("alarm", alarm);
myIntent.putExtra("bundle", bundle);
Run Code Online (Sandbox Code Playgroud)

并在AlarmAlertBroadcastReciever.onReceive():

Bundle bundle = intent.getBundleExtra("bundle");
if (bundle != null) {
    Alarm alarm = (Alarm)bundle.getSerializable("alarm");
}
Run Code Online (Sandbox Code Playgroud)

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

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


Mar*_*ski 3

我正在使用 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);
Run Code Online (Sandbox Code Playgroud)

然后我收到了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();
        }
    }
}
Run Code Online (Sandbox Code Playgroud)