Fix Android app connection and timeout issues

Add proper timeout configuration to OkHttpClient (30s connect/read/write)
Update OkHttp logging-interceptor to 4.12.0 to match OkHttp version
Improve error messages to show server URL for debugging
Configure backend to listen on all interfaces (0.0.0.0)
Remove EdgeToEdge calls that interfered with layout
This commit is contained in:
2026-03-29 17:54:23 -06:00
parent d3723b8ae5
commit 8d419b0dd9
5 changed files with 39 additions and 19 deletions

View File

@@ -39,7 +39,7 @@ dependencies {
implementation("com.squareup.retrofit2:retrofit:2.9.0") implementation("com.squareup.retrofit2:retrofit:2.9.0")
implementation("com.squareup.retrofit2:converter-gson:2.9.0") implementation("com.squareup.retrofit2:converter-gson:2.9.0")
implementation("com.squareup.okhttp3:logging-interceptor:4.9.1") implementation("com.squareup.okhttp3:logging-interceptor:4.12.0")
implementation("com.squareup.okhttp3:okhttp:4.12.0") implementation("com.squareup.okhttp3:okhttp:4.12.0")
implementation("com.google.android.material:material:1.11.0") implementation("com.google.android.material:material:1.11.0")

View File

@@ -39,15 +39,8 @@ public class HomeActivity extends AppCompatActivity {
@Override @Override
protected void onCreate(Bundle savedInstanceState) { protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
EdgeToEdge.enable(this);
setContentView(R.layout.activity_home); setContentView(R.layout.activity_home);
ViewCompat.setOnApplyWindowInsetsListener(findViewById(R.id.main), (v, insets) -> {
Insets systemBars = insets.getInsets(WindowInsetsCompat.Type.systemBars());
v.setPadding(systemBars.left, systemBars.top, systemBars.right, systemBars.bottom);
return insets;
});
//get the bottom navbar from the layout //get the bottom navbar from the layout
bottomNav = findViewById(R.id.bottom_navigation); bottomNav = findViewById(R.id.bottom_navigation);

View File

@@ -52,15 +52,8 @@ public class MainActivity extends AppCompatActivity {
} }
} }
EdgeToEdge.enable(this);
setContentView(R.layout.activity_main); setContentView(R.layout.activity_main);
ViewCompat.setOnApplyWindowInsetsListener(findViewById(R.id.main), (v, insets) -> {
Insets systemBars = insets.getInsets(WindowInsetsCompat.Type.systemBars());
v.setPadding(systemBars.left, systemBars.top, systemBars.right, systemBars.bottom);
return insets;
});
//get all controls from layout //get all controls from layout
tvLoginStatus = findViewById(R.id.tvLoginStatus); tvLoginStatus = findViewById(R.id.tvLoginStatus);
etUser = findViewById(R.id.etUser); etUser = findViewById(R.id.etUser);
@@ -132,15 +125,43 @@ public class MainActivity extends AppCompatActivity {
} }
}); });
} else { } else {
Toast.makeText(MainActivity.this, "Login failed", Toast.LENGTH_SHORT).show(); String errorMessage;
tvLoginStatus.setText("Login failed"); switch (response.code()) {
case 401:
errorMessage = "Invalid username or password";
break;
case 500:
errorMessage = "Server error. Please try again later.";
break;
case 503:
errorMessage = "Service unavailable. Backend may be starting up.";
break;
default:
errorMessage = "Login failed (Error " + response.code() + ")";
}
Toast.makeText(MainActivity.this, errorMessage, Toast.LENGTH_LONG).show();
tvLoginStatus.setText(errorMessage);
} }
} }
@Override @Override
public void onFailure(Call<AuthDTO.LoginResponse> call, Throwable t) { public void onFailure(Call<AuthDTO.LoginResponse> call, Throwable t) {
Toast.makeText(MainActivity.this, "Login failed", Toast.LENGTH_SHORT).show(); Log.e("MainActivity", "Login request failed", t);
tvLoginStatus.setText("Login failed");
String errorMessage;
if (t instanceof java.net.ConnectException ||
t instanceof java.net.SocketTimeoutException ||
t instanceof java.net.UnknownHostException) {
errorMessage = "Cannot connect to server at " + RetrofitClient.BASE_URL +
". Please check if the backend is running.";
} else if (t instanceof java.io.IOException) {
errorMessage = "Network error. Please check your connection.";
} else {
errorMessage = "Login failed: " + t.getMessage();
}
Toast.makeText(MainActivity.this, errorMessage, Toast.LENGTH_LONG).show();
tvLoginStatus.setText(errorMessage);
} }
}); });
}); });

View File

@@ -11,6 +11,8 @@ import okhttp3.logging.HttpLoggingInterceptor;
import retrofit2.Retrofit; import retrofit2.Retrofit;
import retrofit2.converter.gson.GsonConverterFactory; import retrofit2.converter.gson.GsonConverterFactory;
import java.util.concurrent.TimeUnit;
//Retrofit client Used for API calls //Retrofit client Used for API calls
public class RetrofitClient { public class RetrofitClient {
public static final String BASE_URL = getBaseUrl(); public static final String BASE_URL = getBaseUrl();
@@ -41,6 +43,9 @@ public class RetrofitClient {
OkHttpClient client = new OkHttpClient.Builder() OkHttpClient client = new OkHttpClient.Builder()
.addInterceptor(interceptor) .addInterceptor(interceptor)
.addInterceptor(new AuthInterceptor(context)) .addInterceptor(new AuthInterceptor(context))
.connectTimeout(30, TimeUnit.SECONDS)
.readTimeout(30, TimeUnit.SECONDS)
.writeTimeout(30, TimeUnit.SECONDS)
.build(); .build();
//build the retrofit object with all needed properties //build the retrofit object with all needed properties

View File

@@ -36,6 +36,7 @@ spring:
server: server:
port: ${SERVER_PORT:8080} port: ${SERVER_PORT:8080}
address: ${SERVER_ADDRESS:0.0.0.0}
servlet: servlet:
context-path: / context-path: /