UWP Windows 10应用对接Google Calendar API v3遇阻求解决方案
Hey there! I get it—trying to get Google Calendar API v3 working with a UWP app on Raspberry Pi can feel frustrating, especially since official support is missing and workarounds can hit snags. Let’s walk through the most likely fixes for the redirect URI issue and get your calendar events showing up on that screen.
First: Double-Check Your Google Cloud Console OAuth Configuration
Most redirect URI problems boil down to misconfigured OAuth settings in Google Cloud Console, not just code changes. Here’s what to verify:
- Create the right OAuth client type: Instead of a "Web application" or "UWP" client, create a Desktop app client ID. UWP can leverage the Desktop OAuth flow as a workaround, and this avoids the UWP-specific broker issues.
- Add the correct redirect URIs: For the Desktop flow, add these URIs to your client ID settings:
http://localhost(covers local server callback)urn:ietf:wg:oauth:2.0:oob(for manual code entry, useful if Raspberry Pi’s GUI has issues with popups)
- Save and re-download credentials: After updating, download the new
credentials.jsonfile and replace the one in your UWP project.
Adjust Your Code for UWP + Desktop OAuth Flow
The default UWP auth code won’t work, so switch to the GoogleWebAuthorizationBroker flow (used for Desktop apps) but tweak it to fit UWP’s sandbox restrictions:
Key Code Changes
- Handle file paths correctly: UWP runs in a sandbox, so you can’t use relative paths for
credentials.jsonortoken.json. Use the app’s local folder instead:string credentialsPath = Path.Combine(Windows.Storage.ApplicationData.Current.LocalFolder.Path, "credentials.json"); string tokenPath = Path.Combine(Windows.Storage.ApplicationData.Current.LocalFolder.Path, "token.json"); - Use
LocalServerCodeReceiverfor callbacks: This bypasses UWP’s auth broker and uses a local server to capture the OAuth redirect. Here’s a full example:using Google.Apis.Auth.OAuth2; using Google.Apis.Calendar.v3; using Google.Apis.Services; using Google.Apis.Util.Store; using System.IO; using System.Threading; public async Task<CalendarService> InitializeCalendarService() { UserCredential credential; string[] scopes = { CalendarService.Scope.CalendarReadonly }; string appName = "Raspberry Pi Calendar Display"; var credentialsPath = Path.Combine(Windows.Storage.ApplicationData.Current.LocalFolder.Path, "credentials.json"); var tokenPath = Path.Combine(Windows.Storage.ApplicationData.Current.LocalFolder.Path, "token.json"); using (var stream = new FileStream(credentialsPath, FileMode.Open, FileAccess.Read)) { credential = await GoogleWebAuthorizationBroker.AuthorizeAsync( GoogleClientSecrets.Load(stream).Secrets, scopes, "user", CancellationToken.None, new FileDataStore(tokenPath, true), new LocalServerCodeReceiver()); } return new CalendarService(new BaseClientService.Initializer() { HttpClientInitializer = credential, ApplicationName = appName }); }
Raspberry Pi-Specific Troubleshooting
Since you’re running this on a Pi, there are a few extra hoops:
- Enable developer mode: Make sure your Raspberry Pi has Windows 10 IoT Core developer mode enabled so you can deploy and debug the UWP app properly.
- Network permissions: Double-check that your UWP app has the
Internet (Client)capability enabled in the Package.appxmanifest—without this, it can’t reach Google’s API servers. - Manual auth fallback: If the Pi’s GUI doesn’t show the OAuth login popup, use the
urn:ietf:wg:oauth:2.0:oobredirect URI. When the app runs, it’ll show a code entry prompt—open the provided URL on another device, log in, copy the code, and paste it into the Pi’s app.
Verify the Calendar Service Works
Once your service is initialized, test fetching events with a simple call to confirm everything’s working:
var service = await InitializeCalendarService(); var eventsRequest = service.Events.List("primary"); eventsRequest.TimeMin = DateTime.Now; eventsRequest.ShowDeleted = false; eventsRequest.SingleEvents = true; eventsRequest.MaxResults = 10; eventsRequest.OrderBy = EventsResource.ListRequest.OrderByEnum.StartTime; var events = await eventsRequest.ExecuteAsync(); if (events.Items != null && events.Items.Count > 0) { foreach (var eventItem in events.Items) { string start = eventItem.Start.DateTime?.ToString() ?? eventItem.Start.Date; Debug.WriteLine($"{start} - {eventItem.Summary}"); } }
If you still hit issues, check the Google Cloud Console’s OAuth consent screen—make sure your app is published (even as "Testing") and that your Google account is added as a test user if it’s not in production.
内容的提问来源于stack exchange,提问作者Raither

