簡體   English   中英

將Serializable對象傳遞給Pending Intent

[英]Pass Serializable Object to Pending 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);

收到的警報為空。

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

將自定義對象放入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上執行此操作的示例。

我正在使用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();
        }
    }
}

你有putSerializable在Bundle。 而且你試圖從意圖中獲得getSerializable

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

試試看。

Intent putExtra(String name,Parcelable value)

將擴展數據添加到intent。 名稱必須包含包前綴,例如app com.android.contacts將使用“com.android.contacts.ShowAll”之類的名稱。

參考

這是一個建議,你可以嘗試parcelabler,它更有效,並根據Android特定需求量身定制。 所以讓你的模型類在這里被包圍 之后粘貼到您的項目中,然后使用任一捆綁將其傳遞給另一個活動

bundle.putParcelable(KEY_PARCEL, detailModelsList.get(position));

要么

intent.putParcelableArrayListExtra("Parcelaber",myList);

有兩件事我想建議:

  1. 您需要將Action設置為您的意圖,例如: yourIntent.setAction("abc.xyz")
  2. 您應該使用FLAG_UPDATE_CURRENT而不是FLAG_CANCEL_CURRENT

希望能幫助到你。

您是否嘗試過除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");
        }

    }

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM