Android应用连接XAMPP服务器PHP API遇信任锚错误,求解决方案
解决Android连接本地XAMPP服务器时的CertPathValidatorException错误并实现数据提交
错误原因分析
你遇到的java.security.cert.CertPathValidatorException: Trust anchor for certification path not found错误,通常有两种触发场景:
- Android 9.0(API 28)及以上系统默认禁止明文HTTP请求,而本地XAMPP默认使用HTTP协议
- 你误将XAMPP配置为HTTPS,但系统不信任其自签名SSL证书
下面给出针对性解决方案,同时附带日期提交功能的完整实现代码。
解决方案
方案1:允许明文HTTP请求(仅开发环境使用)
适合本地调试场景,直接配置Android应用允许向指定局域网IP发送明文请求:
- 在
res/xml目录下创建network_security_config.xml(无xml目录则新建),内容如下:
<?xml version="1.0" encoding="utf-8"?> <network-security-config> <domain-config cleartextTrafficPermitted="true"> <domain includeSubdomains="true">192.168.x.x</domain> <!-- 替换为你的电脑局域网IP,可通过cmd输入ipconfig查看 --> </domain-config> </network-security-config>
- 在
AndroidManifest.xml的<application>标签中添加配置引用:
android:networkSecurityConfig="@xml/network_security_config"
方案2:信任XAMPP自签名证书(若使用HTTPS)
如果必须用HTTPS调试,需将XAMPP的SSL证书导入应用并配置信任:
- 找到XAMPP的SSL证书,路径通常为
xampp/apache/conf/ssl.crt/server.crt - 将证书文件复制到
app/src/main/res/raw目录(无raw目录则新建),重命名为server.crt - 修改
network_security_config.xml:
<?xml version="1.0" encoding="utf-8"?> <network-security-config> <domain-config> <domain includeSubdomains="true">192.168.x.x</domain> <trust-anchors> <certificates src="@raw/server"/> </trust-anchors> </domain-config> </network-security-config>
- 同样在
AndroidManifest.xml的<application>标签中引用该配置文件。
日期提交功能完整实现
1. 布局文件(activity_main.xml)
添加日期输入框和提交按钮:
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" android:padding="16dp"> <EditText android:id="@+id/et_date" android:layout_width="match_parent" android:layout_height="wrap_content" android:hint="输入日期(如2024-05-20)" android:inputType="date"/> <Button android:id="@+id/btn_submit" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginTop="16dp" android:text="提交"/> </LinearLayout>
2. 网络请求代码(使用OkHttp)
首先在app/build.gradle的dependencies块添加OkHttp依赖:
implementation 'com.squareup.okhttp3:okhttp:4.12.0'
然后在Activity中实现提交逻辑:
import android.os.Bundle; import android.view.View; import android.widget.Button; import android.widget.EditText; import android.widget.Toast; import androidx.appcompat.app.AppCompatActivity; import okhttp3.FormBody; import okhttp3.OkHttpClient; import okhttp3.Request; import okhttp3.RequestBody; import okhttp3.Response; import java.io.IOException; public class MainActivity extends AppCompatActivity { private EditText etDate; private Button btnSubmit; private final OkHttpClient client = new OkHttpClient(); @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); etDate = findViewById(R.id.et_date); btnSubmit = findViewById(R.id.btn_submit); btnSubmit.setOnClickListener(v -> { String date = etDate.getText().toString().trim(); if (!date.isEmpty()) { sendDateToServer(date); } else { Toast.makeText(this, "请输入日期", Toast.LENGTH_SHORT).show(); } }); } private void sendDateToServer(String date) { new Thread(() -> { try { RequestBody formBody = new FormBody.Builder() .add("date", date) .build(); Request request = new Request.Builder() .url("http://192.168.x.x/api/submit_date.php") // 替换为你的PHP API地址,确保电脑局域网IP正确 .post(formBody) .build(); Response response = client.newCall(request).execute(); if (response.isSuccessful() && response.body() != null) { String responseData = response.body().string(); runOnUiThread(() -> Toast.makeText(MainActivity.this, "提交成功:" + responseData, Toast.LENGTH_SHORT).show()); } else { runOnUiThread(() -> Toast.makeText(MainActivity.this, "提交失败", Toast.LENGTH_SHORT).show()); } } catch (IOException e) { e.printStackTrace(); runOnUiThread(() -> Toast.makeText(MainActivity.this, "网络错误:" + e.getMessage(), Toast.LENGTH_SHORT).show()); } }).start(); } }
3. PHP API示例(submit_date.php)
将该文件放在XAMPP的htdocs/api目录下(无api目录则新建):
<?php header("Content-Type: text/plain; charset=utf-8"); if ($_SERVER['REQUEST_METHOD'] === 'POST') { $date = isset($_POST['date']) ? $_POST['date'] : ''; if (!empty($date)) { // 这里可添加数据入库逻辑,比如存入MySQL echo "成功收到日期:{$date}"; } else { echo "日期不能为空"; } } else { echo "仅支持POST请求"; } ?>
关键注意事项
- 确保电脑和安卓设备处于同一WiFi网络
- 关闭电脑防火墙对Apache端口(默认80)的限制
- 必须使用电脑的局域网IP,而非
localhost或127.0.0.1(安卓设备无法访问电脑的本地回环地址) - 上线发布应用时,必须切换为正规SSL证书的HTTPS请求,禁止使用明文HTTP
内容的提问来源于stack exchange,提问作者Kishan Panchal
相关产品推荐
相关产品推荐

