1

Basically, I can't find an implementation of com.google.api.client.http.HttpTransport that works in Android SDK 31.

I'm trying to get started with the google-signin API, and I'm getting a ClassCastException.

I'm using code taken nearly verbatim from the google api examples.

        val credentialStream = resources.openRawResource(R.raw.credentials)
            ?: throw FileNotFoundException("Resource not found: $CREDENTIALS_FILE_PATH")

        val clientSecrets = GoogleClientSecrets.load(JSON_FACTORY, InputStreamReader(credentialStream))

        // Build flow and trigger user authorization request.
        val flow = GoogleAuthorizationCodeFlow.Builder(NetHttpTransport(), JSON_FACTORY, clientSecrets, SCOPES)
            .setDataStoreFactory(FileDataStoreFactory(requireContext().filesDir?.resolve(File(TOKENS_DIRECTORY_PATH))))
            .setAccessType("offline")
            .build()

        val receiver = LocalServerReceiver.Builder().setPort(8888).build()
        //returns an authorized Credential object.

        return AuthorizationCodeInstalledApp(flow, receiver).authorize("user@gmail.com")

Every test results in an exception at the last line.

java.lang.NoClassDefFoundError: Failed resolution of: Lcom/sun/net/httpserver/HttpServer;
...

Caused by: java.lang.ClassNotFoundException: Didn't find class "com.sun.net.httpserver.HttpServer" on path: DexPathList[[dex file "/data/d ...

Any ideas? I'm pretty novice to android development.

1 Answers1

0

One solution I found was to add rt.jar from the desktop JVM as a dependency, because it includes that missing class. Check here:

Is it possible to use com.sun.net.httpserver package in android program?

The solution I ended up using was to using Google Play Services instead of GoogleAuthorizationCodeFlow.

In gradle:

    implementation 'com.google.android.gms:play-services-auth:20.1.0'
    implementation ('com.google.api-client:google-api-client-android:1.34.0')

In my ViewModel:

val applicationName = "My Application"
val scopes = listOf( ... some scopes go here ...)

val credential = GoogleAccountCredential.usingOAuth2(application, scopes)
        .setBackOff(ExponentialBackOff())
        .setSelectedAccountName(accountName)

credential can then be used to access other parts of the Google API.