I am facing an issue with Youtube API v3, in particolar with Google API (gapi for short). My final goal is to call the Youtube Data API videos/list to obtain all the info about a specific video.
As per documentation, i followed the recommended steps until step 5 (the example there is a bit outdated) but without success.
Android quickstart doc: https://developers.google.com/youtube/v3/quickstart/android
So, i checked their API docs on how to compose said request here, and i tried composing the request with the parameters part: "snippet" and id: "o-YBDTqX_ZU" (or any other id). There you can see their implementation: uncheck OAuth 2.0 and leave only API Key, then Execute / Show code / Java. I tried to readjust their code to my needs.
https://developers.google.com/youtube/v3/docs/videos/list?hl=en
https://developers.google.com/explorer-help/guides/code_samples#java
Here's my app-level build.gradle
plugins {
id 'com.android.application'
id 'kotlin-android'
}
android {
compileSdk 30
defaultConfig {
applicationId "com.example.testyoutubeapi"
minSdk 23
targetSdk 30
versionCode 1
versionName "1.0"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
kotlinOptions {
jvmTarget = '1.8'
}
}
dependencies {
implementation 'androidx.core:core-ktx:1.6.0'
implementation 'androidx.appcompat:appcompat:1.3.1'
implementation 'com.google.android.material:material:1.4.0'
implementation 'androidx.constraintlayout:constraintlayout:2.1.0'
implementation 'com.google.android.gms:play-services-auth:19.2.0'
implementation 'pub.devrel:easypermissions:0.3.0'
implementation 'com.google.api-client:google-api-client:1.23.0'
implementation 'com.google.oauth-client:google-oauth-client-jetty:1.23.0'
implementation 'com.google.apis:google-api-services-youtube:v3-rev192-1.23.0'
implementation 'com.google.api-client:google-api-client-android:1.23.0' exclude module: 'httpclient'
implementation 'com.google.apis:google-api-services-tasks:v1-rev48-1.23.0' exclude module: 'httpclient'
implementation 'com.google.http-client:google-http-client-gson:1.23.0' exclude module: 'httpclient'
testImplementation 'junit:junit:4.13.2'
androidTestImplementation 'androidx.test.ext:junit:1.1.3'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0'
}
And here is my YoutubeAPI class
class YoutubeAPI() {
companion object {
const val DEVELOPER_KEY = "AIzaS......" // API key
const val APPLICATION_NAME = "API code samples"
private val JSON_FACTORY: JsonFactory = JacksonFactory.getDefaultInstance()
}
private fun getService(): YouTube {
val httpTransport: HttpTransport = AndroidHttp.newCompatibleTransport() //GoogleNetHttpTransport.newTrustedTransport();
return YouTube.Builder(httpTransport, JSON_FACTORY, null)
.setApplicationName(APPLICATION_NAME)
.build();
}
fun start(): VideoListResponse {
val youtubeService = getService()
val request: YouTube.Videos.List = youtubeService.videos()
.list("snippet")
.setKey(DEVELOPER_KEY)
.setId("o-YBDTqX_ZU")
return request.execute()
}
}
Here, when calling AuthorizationCodeInstalledApp(flow, LocalServerReceiver()).authorize("user") an error is thrown, saying that the operation is not permitted
E/AndroidRuntime: FATAL EXCEPTION: Thread-2
Process: com.example.testyoutubeapi, PID: 2209
java.net.SocketException: socket failed: EPERM (Operation not permitted)
at java.net.Socket.createImpl(Socket.java:492)
at java.net.Socket.getImpl(Socket.java:552)
at java.net.Socket.setSoTimeout(Socket.java:1180)
at com.android.okhttp.internal.io.RealConnection.connectSocket(RealConnection.java:143)
at com.android.okhttp.internal.io.RealConnection.connect(RealConnection.java:116)
at com.android.okhttp.internal.http.StreamAllocation.findConnection(StreamAllocation.java:186)
at com.android.okhttp.internal.http.StreamAllocation.findHealthyConnection(StreamAllocation.java:128)
at com.android.okhttp.internal.http.StreamAllocation.newStream(StreamAllocation.java:97)
at com.android.okhttp.internal.http.HttpEngine.connect(HttpEngine.java:289)
at com.android.okhttp.internal.http.HttpEngine.sendRequest(HttpEngine.java:232)
at com.android.okhttp.internal.huc.HttpURLConnectionImpl.execute(HttpURLConnectionImpl.java:465)
at com.android.okhttp.internal.huc.HttpURLConnectionImpl.connect(HttpURLConnectionImpl.java:131)
at com.android.okhttp.internal.huc.DelegatingHttpsURLConnection.connect(DelegatingHttpsURLConnection.java:90)
at com.android.okhttp.internal.huc.HttpsURLConnectionImpl.connect(HttpsURLConnectionImpl.java:30)
at com.google.api.client.http.javanet.NetHttpRequest.execute(NetHttpRequest.java:104)
at com.google.api.client.http.HttpRequest.execute(HttpRequest.java:981)
at com.google.api.client.googleapis.services.AbstractGoogleClientRequest.executeUnparsed(AbstractGoogleClientRequest.java:419)
at com.google.api.client.googleapis.services.AbstractGoogleClientRequest.executeUnparsed(AbstractGoogleClientRequest.java:352)
at com.google.api.client.googleapis.services.AbstractGoogleClientRequest.execute(AbstractGoogleClientRequest.java:469)
at com.example.testyoutubeapi.YoutubeAPI.start(YoutubeAPI.kt:47)
at com.example.testyoutubeapi.MainActivity.onCreate$lambda-1$lambda-0(MainActivity.kt:23)
at com.example.testyoutubeapi.MainActivity.$r8$lambda$6AdxmbUe_rlaFrgzSeLUApTyS2A(Unknown Source:0)
at com.example.testyoutubeapi.MainActivity$$ExternalSyntheticLambda1.run(Unknown Source:4)
at java.lang.Thread.run(Thread.java:919)
The problem here is that Google disable api calls after 90 days of inactivity. Maybe create a request that fires every X days (or ask your backend dev to do it).
If that's not the case, this is a permnission-related problem. Please be sure to have the following permissions in your manifest file
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
Then, simply uninstall the app on the emulator, then
Run your app again and it should work!