Calendar.Events?.get(calendarId, eventId) выдает ошибку android .os.NetworkOnMainThreadException - PullRequest
0 голосов
/ 03 апреля 2020

У меня проблема с тем, что если я ищу событие по идентификатору с помощью библиотеки Google Calendar Java, она ничего не возвращает и выдает ошибку. У меня есть следующий код:


@Module
class GoogleCalendarsApiServiceModule @Inject constructor(): IGoogleCalendarsApiServiceModule {

    private lateinit var googleCalendarService: Calendar

    private val httpTransport: NetHttpTransport = NetHttpTransport()
    private val subscriptions: Disposable = Disposable.empty()

    init {
        this.subscriptions.apply {
            AndroidContextObservable.context()
                .subscribe { context ->
                    val googleCredential = GoogleCredentialsBuilder.getCredentials(httpTransport, context)
                    googleCalendarService = ServiceBuilder.buildGoogleCalendarService(googleCredential, httpTransport)
                }
        }
    }

    fun finalize() {
        this.subscriptions.dispose()
    }

    override fun getEventById(eventId: String): Observable<Event> {
        return Observable.create { subscriber ->
            val calendarEvents: Calendar.Events? = googleCalendarService.events()

            val event: Event = calendarEvents!!
                .get("primary", eventId)
                .execute()

            subscriber.onNext(event)
            subscriber.onComplete()
        }
    }
}

Который затем называется сопоставленным сервисом слоем вверх:

@Module
class GoogleCalendarService @Inject constructor(): IGoogleCalendarService {

    @Inject
    lateinit var googleCalendarsApiServiceModule: GoogleCalendarsApiServiceModule

    init {
        DaggerServiceModuleComponent.create().inject(this)
    }

    override fun getCalendarEventById(eventId: String): Observable<MeetingEvent> {
        return this.googleCalendarsApiServiceModule.getEventById(eventId)
            .map { mapMeetingEvent(it) }
            .onErrorReturn { throw Exception(it) }
    }
}

И тогда я получаю ошибку: I/System.out: io.reactivex.rxjava3.exceptions.CompositeException: 2 exceptions occurred.

Когда я отлаживаю, проблема возникает из-за того, что ничего не возвращается из Calendar.Events?.get(). Я немного озадачен этим, потому что если я go до https://developers.google.com/calendar/v3/reference/events/get и использую интерактивный API с идентификатором ... скажем 2ilol72ocluq4i1mvlbqn7egel (идентификатор события, который действительно существует и является используется этим приложением), я получаю следующий ответ:

{
 "kind": "calendar#event",
 "etag": "\"3168457487134000\"",
 "id": "2ilol72ocluq4i1mvlbqn7egel",
 "status": "confirmed",
 "htmlLink": "https://www.google.com/calendar/event?eid=Mmlsb2w3Mm9jbHVxNGkxbXZsYnFuN2VnZWwgZnJlZW1hbi5tYXJjODgwQG0",
 "created": "2020-03-14T23:32:23.000Z",
 "updated": "2020-03-14T23:32:23.567Z",
 "summary": "TEST123",
 "description": "Test123",
 "location": "IKEA Room",
 "creator": {
  "email": "example@email.com",
  "self": true
 },
 "organizer": {
  "email": "example@email.com",
  "self": true
 },
 "start": {
  "dateTime": "2020-03-14T23:32:00Z"
 },
 "end": {
  "dateTime": "2020-03-15T00:32:00Z"
 },
 "iCalUID": "2ilol72ocluq4i1mvlbqn7egel@google.com",
 "sequence": 0,
 "reminders": {
  "useDefault": true
 }
}

The same API that is called in the application works when done on the interactive API

Кто-нибудь есть какие-либо предложения относительно того, что может быть причиной проблемы?

Я также пытался просто получить список и отфильтровать его по идентификатору:

    override fun getCalendarEventsByRoomName(eventId: String): Observable<Event> {
        return Observable.create { subscriber ->
            val now = DateTime(System.currentTimeMillis())
            val events: Calendar.Events? = googleCalendarService.events()

            val event = events!!.list("primary")
                .setQ(eventId) // <-- use the event ID as a query
                .setMaxResults(1)
                .setOrderBy("startTime")
                .setSingleEvents(true)
                .execute()

            subscriber.onNext(event )
            subscriber.onComplete()
        }
    }

Но это ничего не возвращает, что является тем же результатом в интерактивном API для googleCalendarService.events().list()

РЕДАКТИРОВАТЬ: Дальнейшая отладка выявила следующую ошибку:

android.os.NetworkOnMainThreadException

Это означает, что подозрительная строка кода находится в вызывающей деятельности:

class ViewMeetingEventDataActivity: AppCompatActivity() {

    @Inject lateinit var bundleUtilityModule: BundleUtilityModule
    @Inject lateinit var fragmentUtilityModule: FragmentUtilityModule
    @Inject lateinit var googleCalendarService: GoogleCalendarService

    private val subscriptions: Disposable = Disposable.empty()
    private lateinit var eventId: String
    private lateinit var event: MeetingEvent;

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        AndroidContextObservable.setContext(this)
        DaggerServiceModuleComponent.create().inject(this)
        DaggerUtilityModuleComponent.create().inject(this)

        this.eventId = intent.getStringExtra(BundleData.MEETING_EVENT_ID.name)!!
        this.subscriptions.apply {
            googleCalendarService.getCalendarEventById(eventId)
                .subscribe(
                    { meetingEvent: MeetingEvent -> event = meetingEvent; println(meetingEvent.description + "Hello") },
                    {}
                )
        }

    }

    override fun onDestroy() {
        super.onDestroy()
        this.subscriptions.dispose()
    }
}

где this._subscriptions.apply {} называется.

1 Ответ

0 голосов
/ 03 апреля 2020

Удалось решить проблему с помощью следующего кода:

this.subscriptions.apply {
    googleCalendarService.getCalendarEventById(eventId)
        .subscribeOn(Schedulers.io())
        .subscribe(
            { meetingEvent: MeetingEvent -> event = meetingEvent },
            {}
        )
}

Проблема заключалась в том, что исходный блок:

this.subscriptions.apply {
    googleCalendarService.getCalendarEventById(eventId)
        .subscribe(
            { meetingEvent: MeetingEvent -> event = meetingEvent },
            {}
        )
    }

в вызывающей операции блокировал основной поток пользовательского интерфейса. Ошибка, однако, была поглощена сервисом GoogleCalendarService. Теперь мы позвоним subscribeOn(), что решает проблему.

...