Android/Retrofit:应用程序不通过http进行通信,只能通过https进行通信



我正在尝试创建一个通过http协议与服务器通信的Android应用程序。我正在使用 Retrofit 向服务器发送 GET 请求,但我总是收到以下错误:

java.net.UnknownServiceException: CLEARTEXT communication to http://demo5373349.mockable.io/ not permitted by network security policy

虽然尝试通过https访问服务器时不存在这样的问题,但我也将编写服务器端,并且我应该使用http。

代码如下:

private TextView textView;
private EditText editText;
private Button getButton;
private Retrofit retrofit;
private ServerConnection connection;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
retrofit = new Retrofit.Builder()
.baseUrl("http://demo5373349.mockable.io/")
.addConverterFactory(GsonConverterFactory.create())
.build();
connection = retrofit.create(ServerConnection.class);
textView = findViewById(R.id.textView);
editText = findViewById(R.id.editText);
getButton = findViewById(R.id.buttonGET);
getButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
getHandler();
}
});
}
private void getHandler(){
connection.sendGET().enqueue(new Callback<Message>() {
@Override
public void onResponse(Call<Message> call, Response<Message> response) {
if(response.isSuccessful()) {
textView.setText(response.body().toString());
}else {
textView.setText("Server Error");
}
}
@Override
public void onFailure(Call<Message> call, Throwable t) {
textView.setText("Connection Error");
}
});
}

和界面:

public interface ServerConnection {
@GET("./")
Call<Message> sendGET();
}

从 Android 9.0 (SDK 28( 开始,默认情况下,使用明文网络通信处于停用状态。请参阅安卓 9.0 (SDK 28( 明文已停用

根据安全首选项的顺序,您有多个选项:

  • 将所有网络访问更改为使用 HTTPS。
  • 将网络安全配置文件添加到项目中。
  • 通过在清单中向应用程序添加android:usesCleartextTraffic="true",为应用启用明文支持。

若要将网络安全文件添加到项目,需要执行两项操作。您需要将文件规范添加到清单中:

<application android:networkSecurityConfig="@xml/network_security_config" .../>

其次,创建文件 res/xml/network_security_config.xml 并指定您的安全需求:

<?xml version="1.0" encoding="utf-8"?>
<network-security-config>
<domain-config cleartextTrafficPermitted="true">
<domain includeSubdomains="true">insecure.example.com</domain>
</domain-config>
</network-security-config>