从广播接收器发送ArrayList<Object>到活动界面

5

场景:

  • 我设置了一个定时器,每次定时器执行时,我的广播接收器会启动。

  • 在广播接收器中,我进行了各种检查,并最终生成了 Notify 类的 ArrayList。

  • 我在状态栏中显示通知。

  • 当用户点击通知时,我会显示一个 Activity。在我的 Activity 中,我需要使用 ArrayList 将其显示在视图上。

以下是示例代码:

public class ReceiverAlarm extends BroadcastReceiver {

    @Override
    public void onReceive(Context context, Intent intent) {
         ArrayList<Notify> notifications = new ArrayList<Notify>();

         //do the checks, for exemplification I add these values
         notifications.add(new Notify("id1","This is very important"));
         notifications.add(new Notify("id2","This is not so important"));
         notifications.add(new Notify("id3","This is way too mimportant"));

         NotificationManager notificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
         //init some values from notificationManager
         Intent intentNotif = new Intent(context, NotificationViewer.class);
                intentNotif.putParcelableArrayListExtra("list", notifications);
         PendingIntent contentIntent = PendingIntent.getActivity(context, 0, intentNotif, 0);


         Notification notification = new Notification(icon, text, when);
         notification.setLatestEventInfo(context, contentTitle, contentText, contentIntent);
         notificationManager.notify(NOTIFICATION_ID, notification);
    }

And

   public class NotificationViewer extends Activity {


            @Override
            protected void onCreate(Bundle savedInstanceState) {
                    super.onCreate(savedInstanceState);
                    setContentView(R.layout.notification_viewer);

                   ArrayList<Notify> testArrayList = null;

        Bundle b = getIntent().getExtras();
        if (b != null) {
            testArrayList = b.getParcelableArrayList("list");
        }
    }

并且
public class Notify implements Parcelable {

    public Notify(Parcel in) {
        readFromParcel(in);
    }

    @SuppressWarnings("rawtypes")
    public static final Parcelable.Creator CREATOR = new Parcelable.Creator() {
        public Notify createFromParcel(Parcel in) {
            return new Notify(in);
        }

        public Notify[] newArray(int size) {
            return new Notify[size];
        }
    };

    @Override
    public void writeToParcel(Parcel dest, int flags) {
        dest.writeString(id);
        dest.writeString(text);
    }

    private void readFromParcel(Parcel in) {
        id = in.readString();
        text = in.readString();
    }

    public Notify(String id, String text) {
        super();
        this.id = id;
        this.text = text;
    }

    /** The id. */
    public String id;

    /** Notification text to be displayed. */
    public String text;

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

}

当我从NotificatioNActivity获取b.getParcelableArrayList("list")时,出现以下错误:

E/AndroidRuntime(14319): java.lang.RuntimeException: Unable to start activity

ComponentInfo{NotificationViewer}: java.lang.RuntimeException: Parcel android.os.Parcel@4050f960: Unmarshalling unknown type code 7602277 at offset 124

从我在SO上提出的问题可以看出,我需要将我的对象Parcelable化。也许我在这方面做错了什么,但是...我不知道该如何解决。我做错了什么?


我无法从快速扫描中看出问题。你能否添加一个 if(getIntent().getExtras().contains("list")) { log.v("", "存在"); } else { log.v("", "不存在"); } ? - Graeme
这个例子明确地为创建者 Parcelable.Creator<MyParcelable> CREATOR 进行了类型定义。你也应该这样做吗? - njzk2
2个回答

5
NotificationViewer活动中获取值,可以像这样操作:
ArrayList<Notify> testArrayList = getIntent().getParcelableArrayListExtra("list");

您正在使用putParcelableArrayListExtra()方法传递值,因此需要使用getParcelableArrayListExtra()方法来获取值,而不是使用getParcelableArrayList()方法。


我已经仔细阅读了你的代码,并且按照你的机制进行了相同的操作,结果在我的环境下运行正常。你需要仔细调试你的代码,因为在我的环境下它是正常工作的。可能存在其他问题。 - Vineet Shukla
我认为Notify的声明有问题,也许我在Parcelable实现中漏掉了什么? - Alin
你的Parcelable实现是正确的。你发布的代码没有问题。可能是其他部分出了问题。 - Vineet Shukla
那我就无法找到问题了。按照你说的使用它,错误仍然存在:03-13 12:25:48.324: E/AndroidRuntime(15185): Caused by: Unmarshalling unknown type code at android.os.Parcel.readValue(Parcel.java:1913) at android.os.Parcel.readListInternal(Parcel.java:2092) at android.os.Parcel.readArrayList(Parcel.java:1536) - Alin
啊...在getParcelableArrayListExtra参数中有一个拼写错误。你是对的,现在它像你说的那样工作了。谢谢你的帮助。 - Alin

1

结合自定义的ParcelablePendingIntent有点棘手,但幸运的是,IntentParcelable,为什么不将你收到的Intent作为额外参数传递给你在PendingIntent中包装的Intent,让接收的ActivityService来处理呢?

编辑:如CW的答案所述。

编辑:示例

您的ReceiverAlarm类将“有点像这样”工作:

public class ReceiverAlarm extends BroadcastReceiver {
    @Override
    public void onReceive(Context context, Intent intent) {
        NotificationManager notificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
        Intent intentNotif = new Intent(context, NotificationViewer.class);
        intentNotif.putExtra("intent", intent);
        PendingIntent contentIntent = PendingIntent.getActivity(context, 0, intentNotif, 0);

        Notification notification = new Notification(icon, text, when);
        notification.setLatestEventInfo(context, contentTitle, contentText, contentIntent);
        notificationManager.notify(NOTIFICATION_ID, notification);
    }
}

NotificationViewer活动中:

public class NotificationViewer extends Activity {
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);


        // Fetch the Intent you received in your BroadcastReceiver
        Intent broadcastIntent = getIntent().getParcelableExtra("intent");

        if (broadcastIntent != null) {
            // Do processing previously done in the receiver here 
            // and create your "Notify" objects.
        }
    }
}

我不太明白你的意思。你能提供一个简短的示例代码吗? - Alin
我现在想我明白了,但是我在问题中没有提到的是(因为我认为这不相关),在我的通知文本中,我显示类似“您有4个通知”的内容,其中4是列表的大小。这意味着我不能在我的Activity中使用它,因为通知已经可见。感谢您的代码,我会在需要的情况下保留它。 - Alin

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接