You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用Retrofit调用Traccar API?调用失败求助

Hey there, let's walk through the common pitfalls that might be causing your Retrofit Basic Auth request to fail, especially with your login flow in onCreate:

1. Double-check your Basic Auth implementation

First, make sure you're adding the Authorization header correctly. There are two reliable ways to do this with Retrofit:

Option 1: Use the @BasicAuth annotation

This is the cleanest approach—Retrofit handles encoding your credentials automatically:

public interface AuthApi {
    @POST("auth/login")
    Call<LoginResponse> attemptLogin(
        @BasicAuth Credentials userCredentials,
        @Body LoginPayload loginData
    );
}

// Credentials class (simple POJO)
public class Credentials {
    private String username;
    private String password;

    // Constructor, getters, setters
}

Option 2: Manually encode the Authorization header

If you prefer to handle encoding yourself, ensure you use the correct Base64 format (no line breaks):

public interface AuthApi {
    @POST("auth/login")
    Call<LoginResponse> attemptLogin(
        @Header("Authorization") String authHeader,
        @Body LoginPayload loginData
    );
}

// Generate the header in your Activity
String rawCredentials = username + ":" + password;
String authHeader = "Basic " + Base64.encodeToString(rawCredentials.getBytes(), Base64.NO_WRAP);

Note: Avoid using Base64.DEFAULT here—it adds line breaks which will break the auth header.

2. Fix your onCreate network call

You can't run network requests on the main thread! If you're using call.execute() directly in onCreate, you'll get a NetworkOnMainThreadException. Always use asynchronous callbacks with enqueue():

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_login);

    // Initialize your Retrofit service
    AuthApi authApi = RetrofitClient.getService();
    String authHeader = "Basic " + Base64.encodeToString(("testUser:testPass").getBytes(), Base64.NO_WRAP);

    // Run the login request asynchronously
    authApi.attemptLogin(authHeader, new LoginPayload())
           .enqueue(new Callback<LoginResponse>() {
               @Override
               public void onResponse(Call<LoginResponse> call, Response<LoginResponse> response) {
                   if (response.isSuccessful()) {
                       // Check if user is registered
                       LoginResponse responseBody = response.body();
                       if (responseBody != null && responseBody.isRegistered()) {
                           // Navigate to main screen
                           startActivity(new Intent(LoginActivity.this, MainActivity.class));
                       } else {
                           // Prompt user to complete registration
                           Toast.makeText(LoginActivity.this, "Please finish registering", Toast.LENGTH_SHORT).show();
                       }
                   } else {
                       // Handle error responses (e.g., 401 Unauthorized)
                       String errorMsg = "Login failed: " + response.code() + " - " + response.message();
                       Toast.makeText(LoginActivity.this, errorMsg, Toast.LENGTH_SHORT).show();
                   }
               }

               @Override
               public void onFailure(Call<LoginResponse> call, Throwable t) {
                   // Handle network errors (no internet, server down)
                   Toast.makeText(LoginActivity.this, "Network error: " + t.getMessage(), Toast.LENGTH_SHORT).show();
               }
           });
}

3. Ensure Session persistence is set up

If your API uses sessions to maintain auth state after login, you need to configure OkHttp to store and send cookies automatically. Add a CookieJar to your OkHttpClient:

OkHttpClient client = new OkHttpClient.Builder()
        .cookieJar(new CookieJar() {
            private final Map<String, List<Cookie>> cookieStore = new HashMap<>();

            @Override
            public void saveFromResponse(HttpUrl url, List<Cookie> cookies) {
                cookieStore.put(url.host(), cookies);
            }

            @Override
            public List<Cookie> loadForRequest(HttpUrl url) {
                List<Cookie> cookies = cookieStore.get(url.host());
                return cookies != null ? cookies : new ArrayList<>();
            }
        })
        .build();

// Attach this client to your Retrofit instance
Retrofit retrofit = new Retrofit.Builder()
        .baseUrl("https://your-api-domain.com/")
        .client(client)
        .addConverterFactory(GsonConverterFactory.create())
        .build();

4. Debug with OkHttp Logging

To see exactly what's being sent/received, add the OkHttp logging interceptor. This will show you the full request headers, body, and response details in Logcat:

// Add the dependency first if you haven't: implementation 'com.squareup.okhttp3:logging-interceptor:4.11.0'
HttpLoggingInterceptor loggingInterceptor = new HttpLoggingInterceptor();
loggingInterceptor.setLevel(HttpLoggingInterceptor.Level.BODY);

OkHttpClient client = new OkHttpClient.Builder()
        .addInterceptor(loggingInterceptor)
        // Add other configs (CookieJar, etc.)
        .build();

Check if the Authorization header is present and correctly formatted, and look for response codes like 401 (invalid credentials) or 500 (server error) to narrow down the issue.


内容的提问来源于stack exchange,提问作者Alex Onofre

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.19 04:29:12