commit
ebbc88dd2e
@ -0,0 +1,34 @@
|
||||
package adaptator
|
||||
|
||||
import android.content.Context
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.widget.TextView
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import api.User
|
||||
import but.androidstudio.tetris.R
|
||||
import javax.xml.xpath.XPath
|
||||
|
||||
class RecyclerViewAdaptator(var userData: List<User>): RecyclerView.Adapter<RecyclerViewAdaptator.ItemViewHolder>(){
|
||||
class ItemViewHolder(private val view: View) : RecyclerView.ViewHolder(view) {
|
||||
val textViewUsername: TextView = view.findViewById(R.id.item_username)
|
||||
val textViewXp: TextView = view.findViewById(R.id.item_xp)
|
||||
val textViewCountry: TextView = view.findViewById(R.id.item_country)
|
||||
}
|
||||
|
||||
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ItemViewHolder {
|
||||
val adapterLayout = LayoutInflater.from(parent.context)
|
||||
.inflate(R.layout.item_layout, parent, false)
|
||||
return ItemViewHolder(adapterLayout)
|
||||
}
|
||||
|
||||
override fun getItemCount(): Int = userData.size
|
||||
|
||||
override fun onBindViewHolder(holder: ItemViewHolder, position: Int) {
|
||||
holder.textViewUsername.text = userData[position].username
|
||||
holder.textViewXp.text = userData[position].xp.toString()
|
||||
holder.textViewCountry.text = userData[position].country
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,3 @@
|
||||
package api
|
||||
|
||||
class Data(val users: List<User>)
|
@ -0,0 +1,9 @@
|
||||
package api
|
||||
|
||||
import retrofit2.Call
|
||||
import retrofit2.http.GET
|
||||
|
||||
interface TetrisAPI {
|
||||
@GET("users/lists/xp")
|
||||
fun getAllUsers() : Call<UserResponse>
|
||||
}
|
@ -0,0 +1,54 @@
|
||||
package api
|
||||
|
||||
import com.google.gson.Gson
|
||||
import com.google.gson.GsonBuilder
|
||||
import okhttp3.OkHttpClient
|
||||
import retrofit2.Call
|
||||
import retrofit2.Callback
|
||||
import retrofit2.Response
|
||||
import retrofit2.Retrofit
|
||||
import retrofit2.converter.gson.GsonConverterFactory
|
||||
|
||||
class TetrisClient(okHttpClient: OkHttpClient) {
|
||||
private val api: TetrisAPI
|
||||
|
||||
|
||||
init {
|
||||
// Create Gson object with lenient policy
|
||||
val gson = GsonBuilder()
|
||||
.setLenient()
|
||||
.create()
|
||||
|
||||
// Create Retrofit instance
|
||||
val retrofit = Retrofit.Builder()
|
||||
.baseUrl("https://ch.tetr.io/api/")
|
||||
.addConverterFactory(GsonConverterFactory.create(gson))
|
||||
.client(okHttpClient)
|
||||
.build()
|
||||
|
||||
|
||||
// Create API instance
|
||||
api = retrofit.create(TetrisAPI::class.java)
|
||||
}
|
||||
|
||||
fun getUsers(callback: (List<User>?, Throwable?) -> Unit) {
|
||||
api.getAllUsers().enqueue(object : Callback<UserResponse> {
|
||||
override fun onResponse(call: Call<UserResponse>, response: Response<UserResponse>) {
|
||||
if (response.isSuccessful) {
|
||||
// API call successful, parse response body
|
||||
val users = response.body()?.data?.users
|
||||
callback(users, null)
|
||||
} else {
|
||||
// API call failed, handle error
|
||||
val error = Exception("API call failed with code ${response.code()}")
|
||||
callback(null, error)
|
||||
}
|
||||
}
|
||||
|
||||
override fun onFailure(call: Call<UserResponse>, t: Throwable) {
|
||||
// API call failed, handle error
|
||||
callback(null, t)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
@ -0,0 +1,14 @@
|
||||
package api
|
||||
|
||||
class User(val id: String,
|
||||
val username: String,
|
||||
val role: String,
|
||||
val xp: Double,
|
||||
val supporter: Boolean,
|
||||
val verified: Boolean,
|
||||
val country: String,
|
||||
val timestamp: String,
|
||||
val gamesPlayed: Int,
|
||||
val gamesWon: Int,
|
||||
val gameTime: Int) {
|
||||
}
|
@ -0,0 +1,3 @@
|
||||
package api
|
||||
|
||||
class UserResponse(val success: Boolean, val data: Data)
|
@ -0,0 +1,83 @@
|
||||
package but.androidstudio.tetris
|
||||
|
||||
import adaptator.RecyclerViewAdaptator
|
||||
import android.os.Bundle
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import androidx.fragment.app.Fragment
|
||||
import androidx.recyclerview.widget.LinearLayoutManager
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import api.TetrisClient
|
||||
import api.User
|
||||
import okhttp3.OkHttpClient
|
||||
import java.io.InputStream
|
||||
import java.security.KeyStore
|
||||
import java.security.SecureRandom
|
||||
import java.security.cert.CertificateFactory
|
||||
import javax.net.ssl.SSLContext
|
||||
import javax.net.ssl.TrustManagerFactory
|
||||
import javax.net.ssl.X509TrustManager
|
||||
|
||||
|
||||
class InfoUserFragment : Fragment() {
|
||||
private lateinit var recyclerView: RecyclerView
|
||||
private lateinit var adaptator: RecyclerViewAdaptator
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
}
|
||||
|
||||
override fun onCreateView(
|
||||
inflater: LayoutInflater, container: ViewGroup?,
|
||||
savedInstanceState: Bundle?
|
||||
): View? {
|
||||
// Inflate the layout for this fragment
|
||||
val view = inflater.inflate(R.layout.fragment_info_user, container, false)
|
||||
// Set up RecyclerView
|
||||
recyclerView = view.findViewById<RecyclerView>(R.id.tableUser)
|
||||
recyclerView.layoutManager = LinearLayoutManager(requireContext())
|
||||
adaptator =RecyclerViewAdaptator(listOf())
|
||||
recyclerView.adapter = adaptator
|
||||
return view
|
||||
}
|
||||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
|
||||
// Read the SSL certificate for the request
|
||||
val certificateStream : InputStream = resources.openRawResource(R.raw.sni_cloudflaressl_com)
|
||||
|
||||
// We create a certificateFactory to extract de data of the certificateInputStream
|
||||
val certificateFactory = CertificateFactory.getInstance("X.509")
|
||||
val certificate = certificateFactory.generateCertificate(certificateStream)
|
||||
|
||||
//To specified the certificate to used
|
||||
val keyStore = KeyStore.getInstance(KeyStore.getDefaultType())
|
||||
keyStore.load(null, null)
|
||||
keyStore.setCertificateEntry("ca", certificate)
|
||||
val trustManagerFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm())
|
||||
trustManagerFactory.init(keyStore)
|
||||
|
||||
//To create a SSL context
|
||||
val sslContext = SSLContext.getInstance("SSL")
|
||||
sslContext.init(null, trustManagerFactory.trustManagers, SecureRandom())
|
||||
|
||||
// We create a OkHttpClient to use the SSLContext
|
||||
val okHttpClient: OkHttpClient = OkHttpClient.Builder()
|
||||
.sslSocketFactory(sslContext.socketFactory, trustManagerFactory.trustManagers[0] as X509TrustManager)
|
||||
.build()
|
||||
|
||||
val client = TetrisClient(okHttpClient)
|
||||
|
||||
client.getUsers { users, error ->
|
||||
if (error != null) {
|
||||
// Handle error
|
||||
println("Error: ${error.message}")
|
||||
} else {
|
||||
// Handle success
|
||||
adaptator.userData = users!!
|
||||
recyclerView.adapter?.notifyDataSetChanged()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,38 @@
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<TextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:text="Username"
|
||||
android:textStyle="bold" />
|
||||
|
||||
<TextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:text="XP"
|
||||
android:textStyle="bold" />
|
||||
|
||||
<TextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:text="Country"
|
||||
android:textStyle="bold" />
|
||||
</LinearLayout>
|
||||
|
||||
<androidx.recyclerview.widget.RecyclerView
|
||||
android:orientation="vertical"
|
||||
android:id="@+id/tableUser"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"/>
|
||||
</LinearLayout>
|
@ -0,0 +1,25 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/item_username"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"/>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/item_xp"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"/>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/item_country"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"/>
|
||||
|
||||
</LinearLayout>
|
@ -0,0 +1,30 @@
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIIFLTCCBNOgAwIBAgIQBVK/egzBVp4B3exMiwpZ0zAKBggqhkjOPQQDAjBKMQsw
|
||||
CQYDVQQGEwJVUzEZMBcGA1UEChMQQ2xvdWRmbGFyZSwgSW5jLjEgMB4GA1UEAxMX
|
||||
Q2xvdWRmbGFyZSBJbmMgRUNDIENBLTMwHhcNMjIwNTIzMDAwMDAwWhcNMjMwNTIz
|
||||
MjM1OTU5WjB1MQswCQYDVQQGEwJVUzETMBEGA1UECBMKQ2FsaWZvcm5pYTEWMBQG
|
||||
A1UEBxMNU2FuIEZyYW5jaXNjbzEZMBcGA1UEChMQQ2xvdWRmbGFyZSwgSW5jLjEe
|
||||
MBwGA1UEAxMVc25pLmNsb3VkZmxhcmVzc2wuY29tMFkwEwYHKoZIzj0CAQYIKoZI
|
||||
zj0DAQcDQgAEtjMD8/gzUYFeKx2j9gc0o3ZHCQH48eYDZmKkiZjB10TyyT4QH2Hn
|
||||
3QfD8eRHKrTU6PlnYol/p2WL/5MnVff9ZKOCA24wggNqMB8GA1UdIwQYMBaAFKXO
|
||||
N+rrsHUOlGeItEX62SQQh5YfMB0GA1UdDgQWBBSUimg81mec3SrIMXpku3tYBLc0
|
||||
qzA0BgNVHREELTArggkqLnRldHIuaW+CB3RldHIuaW+CFXNuaS5jbG91ZGZsYXJl
|
||||
c3NsLmNvbTAOBgNVHQ8BAf8EBAMCB4AwHQYDVR0lBBYwFAYIKwYBBQUHAwEGCCsG
|
||||
AQUFBwMCMHsGA1UdHwR0MHIwN6A1oDOGMWh0dHA6Ly9jcmwzLmRpZ2ljZXJ0LmNv
|
||||
bS9DbG91ZGZsYXJlSW5jRUNDQ0EtMy5jcmwwN6A1oDOGMWh0dHA6Ly9jcmw0LmRp
|
||||
Z2ljZXJ0LmNvbS9DbG91ZGZsYXJlSW5jRUNDQ0EtMy5jcmwwPgYDVR0gBDcwNTAz
|
||||
BgZngQwBAgIwKTAnBggrBgEFBQcCARYbaHR0cDovL3d3dy5kaWdpY2VydC5jb20v
|
||||
Q1BTMHYGCCsGAQUFBwEBBGowaDAkBggrBgEFBQcwAYYYaHR0cDovL29jc3AuZGln
|
||||
aWNlcnQuY29tMEAGCCsGAQUFBzAChjRodHRwOi8vY2FjZXJ0cy5kaWdpY2VydC5j
|
||||
b20vQ2xvdWRmbGFyZUluY0VDQ0NBLTMuY3J0MAwGA1UdEwEB/wQCMAAwggF+Bgor
|
||||
BgEEAdZ5AgQCBIIBbgSCAWoBaAB1AOg+0No+9QY1MudXKLyJa8kD08vREWvs62nh
|
||||
d31tBr1uAAABgO6iKgwAAAQDAEYwRAIgAdeVVw138Q+T/kUu/RdyojBt8cYE3+Ta
|
||||
C8mJjoLZvY4CIDUEiw5lfUGLpXoH8X4HB4zISWVfIpGf2UmBCZ0goKMMAHcANc8Z
|
||||
G7+xbFe/D61MbULLu7YnICZR6j/hKu+oA8M71kwAAAGA7qIqLQAABAMASDBGAiEA
|
||||
lQ2PRS+mQxU0RkZm73SCIUDfLjSMjRFiCXjLJo7FJ78CIQDhgBsqhkZULuN8T0BJ
|
||||
kOSZRde6wJpeD3pFg/qIzgMo6gB2ALc++yTfnE26dfI5xbpY9Gxd/ELPep81xJ4d
|
||||
CYEl7bSZAAABgO6iKh0AAAQDAEcwRQIhAOJMesd21/xYT7JgrgKPGUo4WJqlAsvV
|
||||
HurtPpkBy8cCAiAsSKnLvxW+og6m7YTmKnjEPVWdl2wVejrM2djmJd13JDAKBggq
|
||||
hkjOPQQDAgNIADBFAiBLUqhRLadDrgcbV6AeabEnpLy7LfMj7btLFB3DLLYL0QIh
|
||||
AJg9/jdsmybn7D3mhywg0hAmWWSlqLVp2jp47GU8mJCe
|
||||
-----END CERTIFICATE-----
|
Loading…
Reference in new issue