问题
I believe I may be missing something important, nevertheless I cannot figure out how to communicate with an API from my android project on localhost. I pretty much was following this tutorial which is outdated so I was trying to update it into current Android Studio version. However, I have arrived at an impasse, I get this Handshake failed
that I cannot seem to resolve.
EDIT: I'd like to note that I can access the API from a browser on the emulator and it gives the information I requested, but pulling from the app gives the error previously mentioned.
Below is my RestService
which I believe is supposed to connect to my URL, along with some edits based on internet searches which was supposed to help but didn't.
package com.example.newrestapi;
import java.util.Collections;
import java.util.concurrent.TimeUnit;
import okhttp3.CipherSuite;
import okhttp3.ConnectionSpec;
import okhttp3.OkHttpClient;
import okhttp3.TlsVersion;
import okhttp3.logging.HttpLoggingInterceptor;
import retrofit2.converter.gson.GsonConverterFactory;
public class RestService {
//You need to change the IP if you testing environment is not local machine
//or you may have different URL than we have here
private static final String URL = "https://10.0.2.2:80/";
private retrofit2.Retrofit restAdapter;
private InstituteService apiService;
HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor();
public RestService()
{
ConnectionSpec spec = new ConnectionSpec.Builder(ConnectionSpec.MODERN_TLS)
.tlsVersions(TlsVersion.TLS_1_2)
.cipherSuites(
CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
CipherSuite.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,
CipherSuite.TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384
).build();
//OkHttpClient okHttpClient = UnsafeOkHttpClient.getUnsafeOkHttpClient();
interceptor.setLevel(HttpLoggingInterceptor.Level.BODY);
OkHttpClient client = new OkHttpClient.Builder()
.addInterceptor(interceptor)
.readTimeout(180, TimeUnit.SECONDS)
.connectTimeout(180, TimeUnit.SECONDS)
.connectionSpecs(Collections.singletonList(spec))
.build();
restAdapter = new retrofit2.Retrofit.Builder()
.baseUrl(URL)
.addConverterFactory(GsonConverterFactory.create())
.client(client)
.build();
apiService = restAdapter.create(InstituteService.class);
}
public InstituteService getService()
{
return apiService;
}
}
And here is my call to this service and the InstituteService
Interface which include the GETs and SETs:
private void refreshScreen(){
//Call to server to grab list of student records. this is a asyn
InstituteService serv = restService.getService();
Call<List<Student>> response = serv.getStudent();
response.enqueue(new Callback<List<Student>>() {
@Override
public void onResponse(Call<List<Student>> students, Response<List<Student>> response) {
ListView lv = findViewById(R.id.listView);
CustomAdapter customAdapter = new CustomAdapter(MainActivity.this, R.layout.view_student_entry, response.body());
lv.setOnItemClickListener((parent, view, position, id) -> {
student_Id = view.findViewById(R.id.student_Id);
String studentId = student_Id.getText().toString();
Intent objIndent = new Intent(getApplicationContext(), StudentDetail.class);
objIndent.putExtra("student_Id", Integer.parseInt(studentId));
startActivity(objIndent);
});
lv.setAdapter(customAdapter);
}
@Override
public void onFailure(Call<List<Student>> call, Throwable throwable) {
Log.e("MAIN", throwable.getMessage());
Toast.makeText(MainActivity.this, throwable.getMessage(), Toast.LENGTH_LONG).show();
}
});
}
I also created a network_security_config
xml and set android:usesCleartextTraffic="true"
in the manifest.
Any help in fully understanding and accomplishing this task will be appreciated.
EDIT: Or any point in a tutorial's direction?
来源:https://stackoverflow.com/questions/58106483/accessing-asp-net-api-causes-handshake-failed-error-in-android-studio