te')); return $arr; } /* 遍历用户所有主题 * @param $uid 用户ID * @param int $page 页数 * @param int $pagesize 每页记录条数 * @param bool $desc 排序方式 TRUE降序 FALSE升序 * @param string $key 返回的数组用那一列的值作为 key * @param array $col 查询哪些列 */ function thread_tid_find_by_uid($uid, $page = 1, $pagesize = 1000, $desc = TRUE, $key = 'tid', $col = array()) { if (empty($uid)) return array(); $orderby = TRUE == $desc ? -1 : 1; $arr = thread_tid__find($cond = array('uid' => $uid), array('tid' => $orderby), $page, $pagesize, $key, $col); return $arr; } // 遍历栏目下tid 支持数组 $fid = array(1,2,3) function thread_tid_find_by_fid($fid, $page = 1, $pagesize = 1000, $desc = TRUE) { if (empty($fid)) return array(); $orderby = TRUE == $desc ? -1 : 1; $arr = thread_tid__find($cond = array('fid' => $fid), array('tid' => $orderby), $page, $pagesize, 'tid', array('tid', 'verify_date')); return $arr; } function thread_tid_delete($tid) { if (empty($tid)) return FALSE; $r = thread_tid__delete(array('tid' => $tid)); return $r; } function thread_tid_count() { $n = thread_tid__count(); return $n; } // 统计用户主题数 大数量下严谨使用非主键统计 function thread_uid_count($uid) { $n = thread_tid__count(array('uid' => $uid)); return $n; } // 统计栏目主题数 大数量下严谨使用非主键统计 function thread_fid_count($fid) { $n = thread_tid__count(array('fid' => $fid)); return $n; } ?>android - problem with api using kotlin | data dont show in the app - Stack Overflow
最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

android - problem with api using kotlin | data dont show in the app - Stack Overflow

programmeradmin3浏览0评论

this's first app for me , i tried to use api from my website into my app , when i open the app it say field to connect and it's dont show any data from website

note that : i use kotlin + android studio last version

i have checked my website and api via Postman and it's work perfect , so i think the problem in my app

here's my full code

AdMobHelper.kt

package com.khm.jobstest

import android.app.Activity
import com.google.android.gms.ads.AdRequest
import com.google.android.gms.ads.AdView
import com.google.android.gms.ads.MobileAds

object AdMobHelper {
    fun initializeAdMob(activity: Activity) {
        MobileAds.initialize(activity) {}
    }

    fun loadBannerAd(adView: AdView) {
        val adRequest = AdRequest.Builder().build()
        adView.loadAd(adRequest)
    }
}

ApiService.kt

package com.khm.jobstest

import retrofit2.Call
import retrofit2.http.GET

interface ApiService {
    @GET("jobs/") // Use the correct endpoint
    fun getJobs(): Call<List<JobModel>>
}

JobAdapter.kt

package com.khm.jobstest

import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.ImageView
import android.widget.TextView
import androidx.recyclerview.widget.RecyclerView
import com.bumptech.glide.Glide

class JobAdapter(private val jobs: List<JobModel>) :
    RecyclerView.Adapter<JobAdapter.JobViewHolder>() {

    class JobViewHolder(view: View) : RecyclerView.ViewHolder(view) {
        val jobImage: ImageView = view.findViewById(R.id.jobImage)
        val jobName: TextView = view.findViewById(R.id.jobName)
        val jobDetails: TextView = view.findViewById(R.id.jobDetails)
    }

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): JobViewHolder {
        val view = LayoutInflater.from(parent.context).inflate(R.layout.item_job, parent, false)
        return JobViewHolder(view)
    }

    override fun onBindViewHolder(holder: JobViewHolder, position: Int) {
        val job = jobs[position]
        holder.jobName.text = job.name
        holder.jobDetails.text = job.app_contect
        Glide.with(holder.itemView.context).load(job.app_image).into(holder.jobImage)
    }

    override fun getItemCount(): Int = jobs.size
}

JobModel.kt

package com.khm.jobstest

data class JobModel(
    val name: String,
    val app_contect: String,
    val app_image: String
)

MainActivity.kt

package com.khm.jobstest

import android.os.Bundle
import android.widget.Toast
import androidx.appcompat.app.AppCompatActivity
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import com.google.android.gms.ads.AdRequest
import com.google.android.gms.ads.AdView
import com.google.android.gms.ads.MobileAds
import retrofit2.Call
import retrofit2.Callback
import retrofit2.Response
import retrofit2.Retrofit
import retrofit2.converter.gson.GsonConverterFactory

class MainActivity : AppCompatActivity() {

    private lateinit var recyclerView: RecyclerView
    private lateinit var adView: AdView

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        // Initialize RecyclerView
        recyclerView = findViewById(R.id.recyclerView)
        recyclerView.layoutManager = LinearLayoutManager(this)

        // Initialize AdMob
        MobileAds.initialize(this) {}
        adView = findViewById(R.id.adView)
        adView.loadAd(AdRequest.Builder().build())

        // Check internet connection
        if (!NetworkUtils.isOnline(this)) {
            Toast.makeText(this, "يجب أن تستخدم الإنترنت للتصفح، حاول لاحقًا.", Toast.LENGTH_LONG).show()
            return
        }

        // Fetch data from API
        val retrofit = Retrofit.Builder()
            .baseUrl("/")
            .addConverterFactory(GsonConverterFactory.create())
            .build()

        val apiService = retrofit.create(ApiService::class.java)
        apiService.getJobs().enqueue(object : Callback<List<JobModel>> {
            override fun onResponse(call: Call<List<JobModel>>, response: Response<List<JobModel>>) {
                if (response.isSuccessful && response.body() != null) {
                    recyclerView.adapter = JobAdapter(response.body()!!)
                } else {
                    Toast.makeText(this@MainActivity, "البيانات غير صالحة", Toast.LENGTH_SHORT).show()
                }
            }

            override fun onFailure(call: Call<List<JobModel>>, t: Throwable) {
                Toast.makeText(this@MainActivity, "فشل تحميل البيانات: ${t.message}", Toast.LENGTH_SHORT).show()
            }
        })
    }
}

NetworkUtils.kt

package com.khm.jobstest
import android.content.Context
import android.ConnectivityManager
import android.NetworkCapabilities

object NetworkUtils {
    fun isOnline(context: Context): Boolean {
        val connectivityManager =
            context.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
        val network = connectivityManager.activeNetwork ?: return false
        val capabilities = connectivityManager.getNetworkCapabilities(network) ?: return false
        return capabilities.hasTransport(NetworkCapabilities.TRANSPORT_WIFI) ||
                capabilities.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR)
    }
}

RetrofitInstance.kt

package com.khm.jobstest

import retrofit2.Retrofit
import retrofit2.converter.gson.GsonConverterFactory

object RetrofitInstance {
    private const val BASE_URL = "/"

    val retrofit: Retrofit by lazy {
        Retrofit.Builder()
            .baseUrl(BASE_URL)
            .addConverterFactory(GsonConverterFactory.create())
            .build()
    }

    fun getRetrofitInstance(): Retrofit {
        return retrofit
    }
}

AndroidManifest.xml

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android=";
    xmlns:tools=";>

    <!-- إذن الوصول إلى الإنترنت -->
    <uses-permission android:name="android.permission.INTERNET"/>

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/Theme.JobTest"
        tools:targetApi="31">

        <!-- إضافة App ID لإعلانات AdMob -->
        <meta-data
            android:name="com.google.android.gms.ads.APPLICATION_ID"
            android:value="ca-app-pub-3940256099942544~3347511713"/>

        <!-- تعريف MainActivity مع تحديد android:exported -->
        <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>

activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android=";
    xmlns:ads=";
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <com.google.android.gms.ads.AdView
        android:id="@+id/adView"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        ads:adSize="BANNER"
        ads:adUnitId="ca-app-pub-3940256099942544/6300978111" />

    <androidx.recyclerview.widget.RecyclerView
        android:id="@+id/recyclerView"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />

</LinearLayout>

item_job.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android=";
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="vertical"
    android:padding="8dp">

    <ImageView
        android:id="@+id/jobImage"
        android:layout_width="match_parent"
        android:layout_height="200dp"
        android:scaleType="centerCrop" />

    <TextView
        android:id="@+id/jobName"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="اسم الوظيفة"
        android:textSize="18sp"
        android:textStyle="bold"
        android:paddingTop="8dp" />

    <TextView
        android:id="@+id/jobDetails"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="وصف الوظيفة"
        android:textSize="14sp"
        android:paddingTop="4dp" />
</LinearLayout>

so please any idea, i need help

this's first app for me , i tried to use api from my website into my app , when i open the app it say field to connect and it's dont show any data from website

note that : i use kotlin + android studio last version

i have checked my website and api via Postman and it's work perfect , so i think the problem in my app

here's my full code

AdMobHelper.kt

package com.khm.jobstest

import android.app.Activity
import com.google.android.gms.ads.AdRequest
import com.google.android.gms.ads.AdView
import com.google.android.gms.ads.MobileAds

object AdMobHelper {
    fun initializeAdMob(activity: Activity) {
        MobileAds.initialize(activity) {}
    }

    fun loadBannerAd(adView: AdView) {
        val adRequest = AdRequest.Builder().build()
        adView.loadAd(adRequest)
    }
}

ApiService.kt

package com.khm.jobstest

import retrofit2.Call
import retrofit2.http.GET

interface ApiService {
    @GET("jobs/") // Use the correct endpoint
    fun getJobs(): Call<List<JobModel>>
}

JobAdapter.kt

package com.khm.jobstest

import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.ImageView
import android.widget.TextView
import androidx.recyclerview.widget.RecyclerView
import com.bumptech.glide.Glide

class JobAdapter(private val jobs: List<JobModel>) :
    RecyclerView.Adapter<JobAdapter.JobViewHolder>() {

    class JobViewHolder(view: View) : RecyclerView.ViewHolder(view) {
        val jobImage: ImageView = view.findViewById(R.id.jobImage)
        val jobName: TextView = view.findViewById(R.id.jobName)
        val jobDetails: TextView = view.findViewById(R.id.jobDetails)
    }

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): JobViewHolder {
        val view = LayoutInflater.from(parent.context).inflate(R.layout.item_job, parent, false)
        return JobViewHolder(view)
    }

    override fun onBindViewHolder(holder: JobViewHolder, position: Int) {
        val job = jobs[position]
        holder.jobName.text = job.name
        holder.jobDetails.text = job.app_contect
        Glide.with(holder.itemView.context).load(job.app_image).into(holder.jobImage)
    }

    override fun getItemCount(): Int = jobs.size
}

JobModel.kt

package com.khm.jobstest

data class JobModel(
    val name: String,
    val app_contect: String,
    val app_image: String
)

MainActivity.kt

package com.khm.jobstest

import android.os.Bundle
import android.widget.Toast
import androidx.appcompat.app.AppCompatActivity
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import com.google.android.gms.ads.AdRequest
import com.google.android.gms.ads.AdView
import com.google.android.gms.ads.MobileAds
import retrofit2.Call
import retrofit2.Callback
import retrofit2.Response
import retrofit2.Retrofit
import retrofit2.converter.gson.GsonConverterFactory

class MainActivity : AppCompatActivity() {

    private lateinit var recyclerView: RecyclerView
    private lateinit var adView: AdView

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        // Initialize RecyclerView
        recyclerView = findViewById(R.id.recyclerView)
        recyclerView.layoutManager = LinearLayoutManager(this)

        // Initialize AdMob
        MobileAds.initialize(this) {}
        adView = findViewById(R.id.adView)
        adView.loadAd(AdRequest.Builder().build())

        // Check internet connection
        if (!NetworkUtils.isOnline(this)) {
            Toast.makeText(this, "يجب أن تستخدم الإنترنت للتصفح، حاول لاحقًا.", Toast.LENGTH_LONG).show()
            return
        }

        // Fetch data from API
        val retrofit = Retrofit.Builder()
            .baseUrl("https://trainermods/api/")
            .addConverterFactory(GsonConverterFactory.create())
            .build()

        val apiService = retrofit.create(ApiService::class.java)
        apiService.getJobs().enqueue(object : Callback<List<JobModel>> {
            override fun onResponse(call: Call<List<JobModel>>, response: Response<List<JobModel>>) {
                if (response.isSuccessful && response.body() != null) {
                    recyclerView.adapter = JobAdapter(response.body()!!)
                } else {
                    Toast.makeText(this@MainActivity, "البيانات غير صالحة", Toast.LENGTH_SHORT).show()
                }
            }

            override fun onFailure(call: Call<List<JobModel>>, t: Throwable) {
                Toast.makeText(this@MainActivity, "فشل تحميل البيانات: ${t.message}", Toast.LENGTH_SHORT).show()
            }
        })
    }
}

NetworkUtils.kt

package com.khm.jobstest
import android.content.Context
import android.ConnectivityManager
import android.NetworkCapabilities

object NetworkUtils {
    fun isOnline(context: Context): Boolean {
        val connectivityManager =
            context.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
        val network = connectivityManager.activeNetwork ?: return false
        val capabilities = connectivityManager.getNetworkCapabilities(network) ?: return false
        return capabilities.hasTransport(NetworkCapabilities.TRANSPORT_WIFI) ||
                capabilities.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR)
    }
}

RetrofitInstance.kt

package com.khm.jobstest

import retrofit2.Retrofit
import retrofit2.converter.gson.GsonConverterFactory

object RetrofitInstance {
    private const val BASE_URL = "https://trainermods/api/"

    val retrofit: Retrofit by lazy {
        Retrofit.Builder()
            .baseUrl(BASE_URL)
            .addConverterFactory(GsonConverterFactory.create())
            .build()
    }

    fun getRetrofitInstance(): Retrofit {
        return retrofit
    }
}

AndroidManifest.xml

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android/apk/res/android"
    xmlns:tools="http://schemas.android/tools">

    <!-- إذن الوصول إلى الإنترنت -->
    <uses-permission android:name="android.permission.INTERNET"/>

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/Theme.JobTest"
        tools:targetApi="31">

        <!-- إضافة App ID لإعلانات AdMob -->
        <meta-data
            android:name="com.google.android.gms.ads.APPLICATION_ID"
            android:value="ca-app-pub-3940256099942544~3347511713"/>

        <!-- تعريف MainActivity مع تحديد android:exported -->
        <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>

activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android/apk/res/android"
    xmlns:ads="http://schemas.android/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <com.google.android.gms.ads.AdView
        android:id="@+id/adView"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        ads:adSize="BANNER"
        ads:adUnitId="ca-app-pub-3940256099942544/6300978111" />

    <androidx.recyclerview.widget.RecyclerView
        android:id="@+id/recyclerView"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />

</LinearLayout>

item_job.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="vertical"
    android:padding="8dp">

    <ImageView
        android:id="@+id/jobImage"
        android:layout_width="match_parent"
        android:layout_height="200dp"
        android:scaleType="centerCrop" />

    <TextView
        android:id="@+id/jobName"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="اسم الوظيفة"
        android:textSize="18sp"
        android:textStyle="bold"
        android:paddingTop="8dp" />

    <TextView
        android:id="@+id/jobDetails"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="وصف الوظيفة"
        android:textSize="14sp"
        android:paddingTop="4dp" />
</LinearLayout>

so please any idea, i need help

Share Improve this question edited 2 days ago VLAZ 29.1k9 gold badges62 silver badges84 bronze badges asked Feb 17 at 22:35 devodevo 411 silver badge7 bronze badges 1
  • Please edit your question to reduce the code to a minimal reproducible example and better describe where the problem is. Does the HTTP request wotk? Does the UI receive the data? – tyg Commented 2 days ago
Add a comment  | 

1 Answer 1

Reset to default 0

I think the problem is not in your Kotlin code, but in your API itself

As I can see your api is not returning pure JSON code. It's returning some html code and below it the Json string. This will make Kotlin code unable to parse the data properly.

发布评论

评论列表(0)

  1. 暂无评论