java .io.NotSerializableException: android .app.PendingIntent - PullRequest
0 голосов
/ 21 марта 2020

Я пытаюсь создать экземпляр AlarmManager с pendingIntent, но я не могу понять, где я ошибаюсь.

В моем android приложении реализован класс клиента (eventHandler), который это Serializable. Я преобразовал объект моего класса в байтовый массив, чтобы передать его в качестве дополнительного в мое намерение тревоги. Приложение запускается и работает нормально, читая байтовый массив и создавая намерение тревоги в моем объекте с pendingintent. Проблема возникает, когда я пытаюсь запустить второе действие, получить объект моего класса (который можно сериализовать), а затем преобразовать его в байтовый массив для передачи в качестве дополнительного.

Код, который является проблемой:

Intent intent = new Intent(getActivity(), EventWeatherActivity.class);
            ByteArrayOutputStream bos = new ByteArrayOutputStream();
            ObjectOutputStream out = null;
            try {
                out = new ObjectOutputStream(bos);
                **out.writeObject(event);**
                out.flush();
                byte[] data = bos.toByteArray();

                intent.putExtra(EXTRA_MESSAGE, data);

out.writeObject (событие); - это строка, вызывающая ошибку. Но событие, которое принадлежит eventHandler (Serializable), действительно запускалось при запуске приложения, так почему это проблема, когда я запускаю другое действие?

Я получаю ошибку:

    W/System.err: java.io.NotSerializableException: android.app.PendingIntent
2020-03-21 10:26:43.440 7646-7646/com.example.scrollingtext W/System.err:     at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1240)
2020-03-21 10:26:43.440 7646-7646/com.example.scrollingtext W/System.err:     at java.io.ObjectOutputStream.defaultWriteFields(ObjectOutputStream.java:1604)
2020-03-21 10:26:43.440 7646-7646/com.example.scrollingtext W/System.err:     at java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.java:1565)
2020-03-21 10:26:43.443 7646-7646/com.example.scrollingtext W/System.err:     at java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1488)
2020-03-21 10:26:43.443 7646-7646/com.example.scrollingtext W/System.err:     at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1234)
2020-03-21 10:26:43.443 7646-7646/com.example.scrollingtext W/System.err:     at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:354)
2020-03-21 10:26:43.444 7646-7646/com.example.scrollingtext W/System.err:     at com.example.scrollingtext.EventFragment$1.onItemClick(EventFragment.java:122)

В моем классе клиента (событие eventHandler):

                    Intent alarmIntent = new Intent(context, NotificationReceiver.class);

                ByteArrayOutputStream bos = new ByteArrayOutputStream();
                ObjectOutputStream out = null;
                try {
                    out = new ObjectOutputStream(bos);
                    out.writeObject(this);
                    out.flush();
                    byte[] data = bos.toByteArray();
                    alarmIntent.putExtra("imw.notification", data);
                } catch (IOException e) {
                    e.printStackTrace();
                } finally {
                    try {
                        bos.close();
                    } catch (IOException ex) {
                        ex.printStackTrace();
                    }
                }

                final int id = (int) System.currentTimeMillis();
                pendingIntent = PendingIntent.getBroadcast(context, id, alarmIntent, PendingIntent.FLAG_UPDATE_CURRENT);

Ответы [ 2 ]

0 голосов
/ 22 марта 2020

Да, pendingIntent не может быть сериализовано, но странно, когда приложение запускается изначально, pendingIntent нормально работает в EventHandler, и аварийный сигнал успешно создан. Проблема возникает, когда я пытаюсь затем получить копию этого объекта eventHandler и преобразовать ее в байтовый массив, как описано выше, чтобы я мог передать объект eventHandler в свою вторую деятельность. Если я закомментирую создание pendingIntent и alarm, приложение будет работать нормально, передавая объект eventHandler между действиями.

Итак, как уже упоминалось выше, я разделил создание Alarm в классе «Notification»:

public class Notifications implements Serializable {

private PendingIntent pendingIntent;
private int notification_period;
private String notification_interval;
private Activity activity;
private Context context;
private AlarmManager manager;
private eventHandler event;

public Notifications(eventHandler event, int notification_period, String notification_interval, Activity activity, Context context)
{
    this.notification_interval = notification_interval;
    this.notification_period = notification_period;
    this.activity = activity;
    this.context = context;
    this.event = event;
}

public void setAlarm()
{
    manager = (android.app.AlarmManager) activity.getSystemService(Context.ALARM_SERVICE);
    if(notification_period != -1 && !notification_interval.equals("-1")) {

        Intent alarmIntent = new Intent(context, NotificationReceiver.class);

        ByteArrayOutputStream bos = new ByteArrayOutputStream();
        ObjectOutputStream out = null;
        try {
            out = new ObjectOutputStream(bos);
            out.writeObject(event);
            out.flush();
            byte[] data = bos.toByteArray();
            alarmIntent.putExtra("imw.notification", data);
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                bos.close();
            } catch (IOException ex) {
                ex.printStackTrace();
            }
        }

        final int id = (int) System.currentTimeMillis();
        pendingIntent = PendingIntent.getBroadcast(context, id, alarmIntent, PendingIntent.FLAG_UPDATE_CURRENT);

        if(notification_interval.equals("minute")) {
            manager.setRepeating(android.app.AlarmManager.ELAPSED_REALTIME_WAKEUP, SystemClock.elapsedRealtime(), notification_period*60*1000, pendingIntent);
        }
        else if(notification_interval.equals("hour")) {
            manager.setRepeating(android.app.AlarmManager.ELAPSED_REALTIME_WAKEUP, SystemClock.elapsedRealtime() * android.app.AlarmManager.INTERVAL_HOUR * notification_period, android.app.AlarmManager.INTERVAL_HOUR, pendingIntent);
        }
        else if(notification_interval.equals("day")) {
            manager.setRepeating(android.app.AlarmManager.ELAPSED_REALTIME_WAKEUP, SystemClock.elapsedRealtime() * android.app.AlarmManager.INTERVAL_DAY * notification_period, android.app.AlarmManager.INTERVAL_DAY, pendingIntent);
        }

        Log.d("alarm_set", notification_period + " " + notification_interval);
    }
    else {
        if(pendingIntent != null)
        {
            manager.cancel(pendingIntent);
            Log.d("alarm_cancelled", pendingIntent.toString());
        }
    }
}

}

.. и теперь с указанным выше, в моем классе eventHandler:

public void processEvent() {

    try {

        dailyWeather dWeather = new dailyWeather(raw_weather);
        hWeather = new hourlyWeather(raw_weather);

        tag = event.get("Tag");
        start_date = event.get("Start Date");
        start_time = event.get("Start Time");
        end_time = event.get("End Time");
        location = event.get("Location");
        lat = event.get("Lat");
        lng = event.get("Lng");

        notification_period = Integer.parseInt(event.get("Notification Period"));
        notification_interval = event.get("Notification Interval");

        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("dd/MM/yyyy");
        LocalDate fromDate = LocalDate.parse(start_date, formatter);
        LocalDateTime localTime_fromTime = LocalDateTime.parse(start_date + " " + start_time, DateTimeFormatter.ofPattern("dd/MM/yyyy HH:mm"));
        LocalDateTime localTime_toTime = LocalDateTime.parse(start_date + " " + end_time, DateTimeFormatter.ofPattern("dd/MM/yyyy HH:mm"));

        if (DAYS.between(LocalDate.now(), fromDate) > 7) {
            bActive = false;
        }
        else if(LocalDateTime.now().isAfter(localTime_toTime)) {
            Log.d("Expired", "End time");
            bActive = false;
            bExpired = true;
            bContainsHours = true;
        }
        else {
            bActive = true;
            weather = dWeather.getWeather(start_date);

            if (!start_time.equals("0")) {
                bContainsHours = true;
            }

            if(notification_period != -1 && !notification_interval.equals("")) {
                notificationManager = new Notifications(this, notification_period, notification_interval, activity, context);
                notificationManager.setAlarm();
            }
        }

    }catch(Exception e)
    {
        Log.d("Err", "Error appearing here");
        e.printStackTrace();
    }
}

теперь приложение зависало, когда я запускаю его с самого начала, жалуясь, что AlarmManager не сериализовано.

    java.io.NotSerializableException: android.app.AlarmManager
2020-03-22 12:22:50.371 16593-16593/com.example.scrollingtext W/System.err:     at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1240)
2020-03-22 12:22:50.371 16593-16593/com.example.scrollingtext W/System.err:     at java.io.ObjectOutputStream.defaultWriteFields(ObjectOutputStream.java:1604)
2020-03-22 12:22:50.372 16593-16593/com.example.scrollingtext W/System.err:     at java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.java:1565)
2020-03-22 12:22:50.373 16593-16593/com.example.scrollingtext W/System.err:     at java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1488)
2020-03-22 12:22:50.373 16593-16593/com.example.scrollingtext W/System.err:     at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1234)
2020-03-22 12:22:50.373 16593-16593/com.example.scrollingtext W/System.err:     at java.io.ObjectOutputStream.defaultWriteFields(ObjectOutputStream.java:1604)
2020-03-22 12:22:50.373 16593-16593/com.example.scrollingtext W/System.err:     at java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.java:1565)
2020-03-22 12:22:50.374 16593-16593/com.example.scrollingtext W/System.err:     at java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1488)
2020-03-22 12:22:50.374 16593-16593/com.example.scrollingtext W/System.err:     at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1234)
2020-03-22 12:22:50.374 16593-16593/com.example.scrollingtext W/System.err:     at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:354)
2020-03-22 12:22:50.374 16593-16593/com.example.scrollingtext W/System.err:     at com.example.scrollingtext.Notifications.setAlarm(Notifications.java:47)
2020-03-22 12:22:50.377 16593-16593/com.example.scrollingtext W/System.err:     at com.example.scrollingtext.eventHandler.processEvent(eventHandler.java:98)
0 голосов
/ 21 марта 2020

Мне кажется, проблема в том, что ваш класс EventHandler содержит поле pendingIntent, которое нельзя сериализовать. Вы должны отделить свой класс EventHandler и описать только те поля, которые вы хотите сериализовать. Также, пожалуйста, предоставьте полный список вашего EventHandler класса, чтобы узнать, что еще может вызвать проблему. Ваш текущий список не полный.

...