Android Studio Retrofit stürzt ständig ab, meine App kann keine Verbindung herstellen
Posted: 07 Jan 2025, 12:01
Bitte sehen Sie sich unten den Logcat-Bericht an. Ich versuche, eine Remote-API zu erstellen. Ich verwende einen lokalen Server auf meinem Windows-PC, kann aber scheinbar keine Verbindung von der App zum Remote-Server herstellen. Die App zeigt die Batterieprozentsätze einwandfrei an, leitet die Informationen jedoch nicht an meinen Server weiter. Alle Vorschläge wären sehr willkommen.
Bitte sehen Sie sich unten die Nachrüstdatei an
siehe unten meine MainActivity.Kt
Code: Select all
java.lang.ExceptionInInitializerError
at com.example.bms.MainActivity.sendBatteryDataToServer(MainActivity.kt:93)
at com.example.bms.MainActivity.access$sendBatteryDataToServer(MainActivity.kt:28)
at com.example.bms.MainActivity$batteryStatusReceiver$1.onReceive(MainActivity.kt:60)
at android.app.LoadedApk$ReceiverDispatcher$Args.lambda$getRunnable$0(LoadedApk.java:1814)
at android.app.LoadedApk$ReceiverDispatcher$Args.$r8$lambda$mcNAAl1SQ4MyJPyDg8TJ2x2h0Rk(Unknown Source:0)
at android.app.LoadedApk$ReceiverDispatcher$Args$$ExternalSyntheticLambda0.run(D8$$SyntheticClass:0)
at android.os.Handler.handleCallback(Handler.java:959)
at android.os.Handler.dispatchMessage(Handler.java:100)
at android.os.Looper.loopOnce(Looper.java:232)
at android.os.Looper.loop(Looper.java:317)
at android.app.ActivityThread.main(ActivityThread.java:8705)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:580)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:886)
Caused by: java.lang.NullPointerException: Attempt to get length of null array
at okhttp3.internal.tls.BasicTrustRootIndex.(BasicTrustRootIndex.java:32)
at okhttp3.internal.platform.Platform.buildTrustRootIndex(Platform.java:303)
at okhttp3.internal.platform.AndroidPlatform.buildTrustRootIndex(AndroidPlatform.java:256)
at okhttp3.internal.platform.Platform.buildCertificateChainCleaner(Platform.java:173)
at okhttp3.internal.platform.AndroidPlatform.buildCertificateChainCleaner(AndroidPlatform.java:212)
at okhttp3.internal.tls.CertificateChainCleaner.get(CertificateChainCleaner.java:41)
at okhttp3.OkHttpClient$Builder.sslSocketFactory(OkHttpClient.java:782)
at com.example.bms.network.RetrofitInstance.(RetrofitInstance.kt:38)
at com.example.bms.MainActivity.sendBatteryDataToServer(MainActivity.kt:93)
at com.example.bms.MainActivity.access$sendBatteryDataToServer(MainActivity.kt:28)
at com.example.bms.MainActivity$batteryStatusReceiver$1.onReceive(MainActivity.kt:60)
at android.app.LoadedApk$ReceiverDispatcher$Args.lambda$getRunnable$0(LoadedApk.java:1814)
at android.app.LoadedApk$ReceiverDispatcher$Args.$r8$lambda$mcNAAl1SQ4MyJPyDg8TJ2x2h0Rk(Unknown Source:0)
at android.app.LoadedApk$ReceiverDispatcher$Args$$ExternalSyntheticLambda0.run(D8$$SyntheticClass:0)
at android.os.Handler.handleCallback(Handler.java:959)
at android.os.Handler.dispatchMessage(Handler.java:100)
at android.os.Looper.loopOnce(Looper.java:232)
at android.os.Looper.loop(Looper.java:317)
at android.app.ActivityThread.main(ActivityThread.java:8705)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:580)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:886)
Code: Select all
package com.example.bms.network
import okhttp3.OkHttpClient
import retrofit2.Call
import retrofit2.Retrofit
import retrofit2.converter.gson.GsonConverterFactory
import retrofit2.http.Body
import retrofit2.http.POST
import java.security.cert.X509Certificate
import javax.net.ssl.SSLContext
import javax.net.ssl.SSLSocketFactory
import javax.net.ssl.X509TrustManager
// Insecure SSL configurations for Retrofit
fun getInsecureTrustManager(): X509TrustManager {
return object : X509TrustManager {
override fun checkClientTrusted(chain: Array?, authType: String?) {}
override fun checkServerTrusted(chain: Array?, authType: String?) {}
override fun getAcceptedIssuers(): Array? = null
}
}
fun getInsecureSocketFactory(): SSLSocketFactory {
val context = SSLContext.getInstance("TLS")
context.init(null, arrayOf(getInsecureTrustManager()), java.security.SecureRandom())
return context.socketFactory
}
// Retrofit instance setup
object RetrofitInstance {
// Base URL for your API
private const val BASE_URL = "http://192.168.1.134:3000/battery/status" // Replace with your actual API URL
// Create OkHttpClient for additional configurations (e.g., logging, timeouts)
private val client = OkHttpClient.Builder()
.sslSocketFactory(getInsecureSocketFactory(), getInsecureTrustManager())
.hostnameVerifier { _, _ -> true } // Accept all hostnames (only for development)
.build()
// Create Retrofit instance
private val retrofit = Retrofit.Builder()
.baseUrl(BASE_URL) // Set the base URL for your API
.addConverterFactory(GsonConverterFactory.create()) // Add Gson converter to convert JSON
.client(client) // Use the OkHttp client
.build()
// Provide the API service
val batteryApiService: BatteryApiService by lazy {
retrofit.create(BatteryApiService::class.java)
}
}
// Retrofit service interface to define API methods
interface BatteryApiService {
// Define your POST request to send battery data
@POST("battery/status")
fun sendBatteryStatus(@Body batteryData: BatteryData): Call
}
// Data class to hold battery data
data class BatteryData(
val batteryPercentage: String,
val batteryStatus: String
)
Code: Select all
package com.example.bms
import android.content.BroadcastReceiver
import android.content.Context
import android.content.Intent
import android.content.IntentFilter
import android.os.BatteryManager
import android.os.Bundle
import android.util.Log
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.padding
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.MutableState
import androidx.compose.runtime.mutableStateOf
import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.dp
import com.example.bms.network.RetrofitInstance
import com.example.bms.network.BatteryData
import retrofit2.Call
import retrofit2.Callback
import retrofit2.Response
import com.example.bms.ui.theme.BMSTheme
class MainActivity : ComponentActivity() {
// State variables to store battery info
private val batteryPercentage = mutableStateOf("Battery: 0%")
private val batteryStatus = mutableStateOf("Status: Unknown")
// BroadcastReceiver to listen to battery changes
private val batteryStatusReceiver = object : BroadcastReceiver() {
override fun onReceive(context: Context?, intent: Intent?) {
if (intent == null) {
Log.e("MainActivity", "Received intent is null")
return
}
// Get battery percentage
val level = intent.getIntExtra(BatteryManager.EXTRA_LEVEL, -1)
val scale = intent.getIntExtra(BatteryManager.EXTRA_SCALE, -1)
val batteryPct = (level * 100) / scale
// Get battery charging status
val status = intent.getIntExtra(BatteryManager.EXTRA_STATUS, -1)
val isCharging = when (status) {
BatteryManager.BATTERY_STATUS_CHARGING -> "Charging"
BatteryManager.BATTERY_STATUS_FULL -> "Full"
BatteryManager.BATTERY_STATUS_DISCHARGING -> "Discharging"
else -> "Unknown"
}
// Update the battery percentage and status state variables
batteryPercentage.value = "Battery: $batteryPct%"
batteryStatus.value = "Status: $isCharging"
// Send battery data to the server
sendBatteryDataToServer(batteryPct, isCharging)
}
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
BMSTheme {
BatteryStatusUI(batteryPercentage, batteryStatus)
}
}
}
override fun onStart() {
super.onStart()
// Register the receiver to listen for battery changes
val filter = IntentFilter(Intent.ACTION_BATTERY_CHANGED)
registerReceiver(batteryStatusReceiver, filter)
}
override fun onStop() {
super.onStop()
// Unregister the receiver to avoid memory leaks
unregisterReceiver(batteryStatusReceiver)
}
// Function to send battery data to the remote server
private fun sendBatteryDataToServer(batteryPct: Int, isCharging: String) {
val batteryData = BatteryData(
batteryPercentage = "$batteryPct%",
batteryStatus = isCharging
)
RetrofitInstance.batteryApiService.sendBatteryStatus(batteryData).enqueue(object : Callback {
override fun onResponse(call: Call, response: Response) {
if (response.isSuccessful) {
Log.d("MainActivity", "Battery data sent successfully")
} else {
Log.e("MainActivity", "Failed to send battery data: ${response.message()}")
}
}
override fun onFailure(call: Call, t: Throwable) {
Log.e("MainActivity", "Error sending battery data: ${t.message}", t)
}
})
}
}
@Composable
fun BatteryStatusUI(batteryPercentage: MutableState, batteryStatus: MutableState) {
// UI for displaying battery percentage and status
Column(modifier = Modifier.padding(16.dp)) {
Text(text = batteryPercentage.value)
Text(text = batteryStatus.value)
}
}