While I am learning Kotlin Course from oreilly. When I was trying to practice one project in android app to show list of items coming from an api I am started getting the error "Trust anchor for certification path not found.". I followed exact same code that was shown in the video but author did not get the error but I am getting it I am unable to find the proper solutions even the ones suggested in Stackoverflow.
Many of the solutions told that I need to put a cert file in the project to communicate. I tried creating selfsigned certificate for hosts such as localhost and the api host to which I am trying to connect but ending up getting same issue.
Can any one help checking my code and advise where I am doing wrong.
interface WeatherAPI{
@GET("api/bins/3mei")
fun getForcast() : Call<List<Forecast>>
}
class Forecast(val high: String, val low: String)
class WeatherRetriever{
val service : WeatherAPI
init{
val retrofit = Retrofit.Builder().baseUrl("https://myjson.dit.upm.es/")
.addConverterFactory(GsonConverterFactory.create())
.build();
service = retrofit.create(WeatherAPI::class.java);
}
fun getForecast(callback: Callback<List<Forecast>>){
val call = service.getForcast();
call.enqueue(callback);
}
}
AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
package="in.net.sudhir.apps.weatherapp">
<uses-permission android:name="android.permission.INTERNET" />
<application
android:allowBackup="true"
android:dataExtractionRules="@xml/data_extraction_rules"
android:fullBackupContent="@xml/backup_rules"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/Theme.WeatherApp"
android:usesCleartextTraffic="false"
android:networkSecurityConfig="@xml/network_security_config"
tools:targetApi="31">
<activity
android:name=".ForcastActivity"
android:exported="false" />
<activity
android:name=".MainActivity"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
Calling from activity:
var retriever = WeatherRetriever();
val callback = object : Callback<List<Forecast>>{
override fun onResponse(
call: Call<List<Forecast>>,
response: Response<List<Forecast>>
) {
println("We got a response");
println(response?.body());
}
override fun onFailure(call: Call<List<Forecast>>, t: Throwable) {
println("We got a failure");
println(t.message);
}
}
retriever.getForecast(callback);
Please check and let me know what all I need to do. I tried multiple searches on internet no where they are clearly mentioning how to fix it they are vaguely saying create certificate and put it but create certificate for which host whether its localhost or the remote api that I am trying to connect they are not saying.
2
Answers
There are some typos in the code, check getForecast()
}
class Forecast(val high: String, val low: String)
class WeatherRetriever {
val service: WeatherAPI
init {
val retrofit =
Retrofit.Builder()
.baseUrl("https://myjson.dit.upm.es/"😉
.addConverterFactory(GsonConverterFactory.create())
.build()
service = retrofit.create(WeatherAPI::class.java)
}
}
I’ve struggled with this as well. I got it working by creating a development cert and referencing it in the my android studio project. You can read the error here in this article on Common problems verifying server certificates where it references the error explicitly:
The relevant link will take you to an article on Network Security Information and creating a network_security_config file and using an exported PEM file from you keychain (Mac) in the @raw/server directory…Configure a custom CA
What it doesn’t go into is the creating a developer cert on your system. For good reason I guess, it’s not their domain, but it has made it challenging to piece this together.
Additionally, I was using dotnet for the api so I had to edit the Kestrel configuration as it’s the web server. I had to put a line in the appsettings.Development.json file:
I’m still trying to sort it all out as it didn’t work for iOS so I had to create Developer Cert for that which got it working, but now my Android app is broken.