From 96c0b944c1f6ff7cd280fb27c05a9a02b41c6dbb Mon Sep 17 00:00:00 2001 From: hmalik144 Date: Sun, 19 Apr 2020 12:29:36 +0100 Subject: [PATCH] Gradle dependencies updates, Api class and handling added. --- app/build.gradle | 30 +++++++++++++ app/src/main/AndroidManifest.xml | 1 + .../h_mal/candyspace/data/api/ApiClass.kt | 33 ++++++++++++++ .../data/api/NetworkConnectionInterceptor.kt | 43 +++++++++++++++++++ .../data/api/QueryParamsInterceptor.kt | 29 +++++++++++++ .../candyspace/data/api/ResponseUnwrap.kt | 29 +++++++++++++ .../example/h_mal/candyspace/data/api/User.kt | 38 ++++++++++++++++ .../data/repositories/Repository.kt | 11 ++++- app/src/main/res/layout/main_fragment.xml | 20 ++++++--- 9 files changed, 228 insertions(+), 6 deletions(-) create mode 100644 app/src/main/java/com/example/h_mal/candyspace/data/api/NetworkConnectionInterceptor.kt create mode 100644 app/src/main/java/com/example/h_mal/candyspace/data/api/QueryParamsInterceptor.kt create mode 100644 app/src/main/java/com/example/h_mal/candyspace/data/api/ResponseUnwrap.kt create mode 100644 app/src/main/java/com/example/h_mal/candyspace/data/api/User.kt diff --git a/app/build.gradle b/app/build.gradle index e066ca7..d289840 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -1,6 +1,7 @@ apply plugin: 'com.android.application' apply plugin: 'kotlin-android' apply plugin: 'kotlin-android-extensions' +apply plugin: 'kotlin-kapt' android { compileSdkVersion 29 @@ -36,4 +37,33 @@ dependencies { testImplementation 'junit:junit:4.12' androidTestImplementation 'androidx.test.ext:junit:1.1.1' androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0' + + //Retrofit and GSON + implementation 'com.squareup.retrofit2:retrofit:2.6.0' + implementation 'com.squareup.retrofit2:converter-gson:2.6.0' + + //Kotlin Coroutines + implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:1.3.0" + implementation "org.jetbrains.kotlinx:kotlinx-coroutines-core:1.3.0" + + // ViewModel and LiveData + implementation "androidx.lifecycle:lifecycle-extensions:2.1.0" + + //New Material Design + implementation 'com.google.android.material:material:1.1.0-alpha10' + + //Kodein Dependency Injection + implementation "org.kodein.di:kodein-di-generic-jvm:6.2.1" + implementation "org.kodein.di:kodein-di-framework-android-x:6.2.1" + + //Android Room + implementation "androidx.room:room-runtime:2.2.0-rc01" + implementation "androidx.room:room-ktx:2.2.0-rc01" + kapt "androidx.room:room-compiler:2.2.0-rc01" + + implementation 'com.xwray:groupie:2.3.0' + implementation 'com.xwray:groupie-kotlin-android-extensions:2.3.0' + implementation 'com.xwray:groupie-databinding:2.3.0' + + implementation "androidx.preference:preference-ktx:1.1.0" } diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 14f4979..ac442fe 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -2,6 +2,7 @@ + + + companion object{ + operator fun invoke( + networkConnectionInterceptor: NetworkConnectionInterceptor, + queryParamsInterceptor: QueryParamsInterceptor + ) : ApiClass{ + + val okkHttpclient = OkHttpClient.Builder() + .addNetworkInterceptor(networkConnectionInterceptor) + .addInterceptor(queryParamsInterceptor) + .build() + + return Retrofit.Builder() + .client(okkHttpclient) + .baseUrl("https://api.stackexchange.com/2.2/") + .addConverterFactory(GsonConverterFactory.create()) + .build() + .create(ApiClass::class.java) + } + } } \ No newline at end of file diff --git a/app/src/main/java/com/example/h_mal/candyspace/data/api/NetworkConnectionInterceptor.kt b/app/src/main/java/com/example/h_mal/candyspace/data/api/NetworkConnectionInterceptor.kt new file mode 100644 index 0000000..deee93c --- /dev/null +++ b/app/src/main/java/com/example/h_mal/candyspace/data/api/NetworkConnectionInterceptor.kt @@ -0,0 +1,43 @@ +package com.example.h_mal.candyspace.data.api + +import android.content.Context +import android.net.ConnectivityManager +import android.net.NetworkCapabilities +import okhttp3.Interceptor +import okhttp3.Response +import java.io.IOException + +/* +* +* +*/ +class NetworkConnectionInterceptor( + context: Context +) : Interceptor { + + private val applicationContext = context.applicationContext + + override fun intercept(chain: Interceptor.Chain): Response { + if (!isInternetAvailable()){ + throw IOException("Make sure you have an active data connection") + } + return chain.proceed(chain.request()) + } + + private fun isInternetAvailable(): Boolean { + var result = false + val connectivityManager = + applicationContext.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager? + connectivityManager?.let { + it.getNetworkCapabilities(connectivityManager.activeNetwork)?.apply { + result = when { + hasTransport(NetworkCapabilities.TRANSPORT_WIFI) -> true + hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR) -> true + else -> false + } + } + } + return result + } + +} diff --git a/app/src/main/java/com/example/h_mal/candyspace/data/api/QueryParamsInterceptor.kt b/app/src/main/java/com/example/h_mal/candyspace/data/api/QueryParamsInterceptor.kt new file mode 100644 index 0000000..8aa199e --- /dev/null +++ b/app/src/main/java/com/example/h_mal/candyspace/data/api/QueryParamsInterceptor.kt @@ -0,0 +1,29 @@ +package com.example.h_mal.candyspace.data.api + +import okhttp3.Interceptor +import okhttp3.Request +import okhttp3.Response + + +class QueryParamsInterceptor : Interceptor{ + + override fun intercept(chain: Interceptor.Chain): Response { + val original = chain.request() + val originalHttpUrl = original.url() + + val url = originalHttpUrl.newBuilder() + .addQueryParameter("site", "stackoverflow") + .addQueryParameter("pagesize","20") + .addQueryParameter("order","desc") + .addQueryParameter("sort","reputation") + .build() + + // Request customization: add request headers + // Request customization: add request headers + val requestBuilder: Request.Builder = original.newBuilder() + .url(url) + + val request: Request = requestBuilder.build() + return chain.proceed(request) + } +} \ No newline at end of file diff --git a/app/src/main/java/com/example/h_mal/candyspace/data/api/ResponseUnwrap.kt b/app/src/main/java/com/example/h_mal/candyspace/data/api/ResponseUnwrap.kt new file mode 100644 index 0000000..e3b379a --- /dev/null +++ b/app/src/main/java/com/example/h_mal/candyspace/data/api/ResponseUnwrap.kt @@ -0,0 +1,29 @@ +package com.example.h_mal.candyspace.data.api + +import org.json.JSONException +import org.json.JSONObject +import retrofit2.Response +import java.io.IOException + +abstract class ResponseUnwrap { + + suspend fun apiRequest(call: suspend () -> Response) : T{ + + val response = call.invoke() + if(response.isSuccessful){ + return response.body()!! + }else{ + val error = response.errorBody()?.string() + + val message = StringBuilder() + error?.let{ + try{ + message.append(JSONObject(it).getString("error_message")) + }catch(e: JSONException){ } + message.append("\n") + } + message.append("Error Code: ${response.code()}") + throw IOException(message.toString()) + } + } +} \ No newline at end of file diff --git a/app/src/main/java/com/example/h_mal/candyspace/data/api/User.kt b/app/src/main/java/com/example/h_mal/candyspace/data/api/User.kt new file mode 100644 index 0000000..60fdf1c --- /dev/null +++ b/app/src/main/java/com/example/h_mal/candyspace/data/api/User.kt @@ -0,0 +1,38 @@ +package com.example.h_mal.candyspace.data.api + +import com.google.gson.annotations.Expose +import com.google.gson.annotations.SerializedName + + +class User { + @SerializedName("last_modified_date") + @Expose + var lastModifiedDate: Int? = null + @SerializedName("reputation") + @Expose + var reputation: Int? = null + @SerializedName("creation_date") + @Expose + var creationDate: Int? = null + @SerializedName("user_type") + @Expose + var userType: String? = null + @SerializedName("user_id") + @Expose + var userId: Int? = null + @SerializedName("location") + @Expose + var location: String? = null + @SerializedName("website_url") + @Expose + var websiteUrl: String? = null + @SerializedName("link") + @Expose + var link: String? = null + @SerializedName("profile_image") + @Expose + var profileImage: String? = null + @SerializedName("display_name") + @Expose + var displayName: String? = null +} \ No newline at end of file diff --git a/app/src/main/java/com/example/h_mal/candyspace/data/repositories/Repository.kt b/app/src/main/java/com/example/h_mal/candyspace/data/repositories/Repository.kt index 7c145ca..98334f9 100644 --- a/app/src/main/java/com/example/h_mal/candyspace/data/repositories/Repository.kt +++ b/app/src/main/java/com/example/h_mal/candyspace/data/repositories/Repository.kt @@ -1,5 +1,14 @@ package com.example.h_mal.candyspace.data.repositories -class Repository { +import com.example.h_mal.candyspace.data.api.ApiClass +import com.example.h_mal.candyspace.data.api.ResponseUnwrap +import com.example.h_mal.candyspace.data.api.User +class Repository( + private val api: ApiClass +): ResponseUnwrap() { + + suspend fun sdasda(username: String): User { + return apiRequest { api.getUsersFromApi(username) } + } } \ No newline at end of file diff --git a/app/src/main/res/layout/main_fragment.xml b/app/src/main/res/layout/main_fragment.xml index d27636e..d9b5d33 100644 --- a/app/src/main/res/layout/main_fragment.xml +++ b/app/src/main/res/layout/main_fragment.xml @@ -7,14 +7,24 @@ android:layout_height="match_parent" tools:context=".ui.main.MainFragment"> - + + + app:layout_constraintTop_toBottomOf="@id/search_bar" + tools:listitem="@android:layout/simple_list_item_2"> + +