如何在Android Studio中发起HTTP请求触发树莓派PHP脚本且不加载网页
在Android onClick中调用树莓派的PHP脚本(无需加载网页)
这问题我之前帮朋友解决过,核心就是给你的PHP脚本发个HTTP请求就行,完全不用加载网页——毕竟你只需要触发脚本执行,不是要显示网页内容。下面给你两种靠谱的实现方式,还有要注意的坑:
第一步:先搞定Android的网络权限和配置
首先得让你的App能访问网络,还要处理Android 9+的明文HTTP限制(如果你的树莓派用的是HTTP而不是HTTPS的话):
- 添加网络权限
在AndroidManifest.xml里的<manifest>标签下添加:
<uses-permission android:name="android.permission.INTERNET" />
- 处理明文HTTP(Android 9+)
如果你的PHP脚本用的是HTTP(不是HTTPS),Android 9及以上默认会阻止明文请求,你可以二选一:
- 推荐:给树莓派的Web服务配置HTTPS(更安全)
- 快速解决:创建
res/xml/network_security_config.xml文件,内容如下:<?xml version="1.0" encoding="utf-8"?> <network-security-config> <domain-config cleartextTrafficPermitted="true"> <domain includeSubdomains="true">你的树莓派IP地址</domain> <!-- 比如192.168.1.100 --> </domain-config> </network-security-config>
然后在AndroidManifest.xml的<application>标签里加上:
android:networkSecurityConfig="@xml/network_security_config"
方式一:用OkHttp(推荐,代码简洁)
OkHttp是Square出品的非常流行的网络库,比Android原生的HttpURLConnection好用太多。
- 添加依赖
在你的Module级build.gradle(通常是app/build.gradle)的dependencies块里添加:
implementation 'com.squareup.okhttp3:okhttp:4.12.0'
(可以去OkHttp官网看最新版本,这个是稳定版)
- 在onClick里写请求代码
比如你有个按钮要打开LED,点击事件里这么写:
// 找到你的按钮 Button ledOnBtn = findViewById(R.id.led_on_button); ledOnBtn.setOnClickListener(v -> { // 替换成你的PHP脚本URL,比如树莓派IP是192.168.1.100,脚本叫control_led.php String phpUrl = "http://192.168.1.100/control_led.php?action=on"; // 初始化OkHttp客户端 OkHttpClient client = new OkHttpClient(); // 构建GET请求(如果要传复杂参数,用POST更合适,下面会说) Request request = new Request.Builder() .url(phpUrl) .get() .build(); // 异步执行请求(不能在主线程发网络请求!) client.newCall(request).enqueue(new Callback() { @Override public void onFailure(@NonNull Call call, @NonNull IOException e) { // 请求失败,比如网络不通,要在主线程弹提示 runOnUiThread(() -> Toast.makeText(MainActivity.this, "操作失败:" + e.getMessage(), Toast.LENGTH_SHORT).show()); } @Override public void onResponse(@NonNull Call call, @NonNull Response response) throws IOException { if (response.isSuccessful()) { // 服务器返回成功,获取响应内容 String responseBody = response.body().string(); // 在主线程更新UI或提示 runOnUiThread(() -> Toast.makeText(MainActivity.this, "LED已打开:" + responseBody, Toast.LENGTH_SHORT).show()); } else { // 服务器返回错误码,比如404、500 runOnUiThread(() -> Toast.makeText(MainActivity.this, "服务器错误:" + response.code(), Toast.LENGTH_SHORT).show()); } } }); });
- 如果要用POST传参数
如果不想把参数拼在URL里(比如参数比较多或者敏感),用POST请求:
// 构建POST请求体 FormBody formBody = new FormBody.Builder() .add("action", "on") .add("led_id", "1") // 比如控制多个LED的话传ID .build(); // 构建POST请求 Request request = new Request.Builder() .url(phpUrl) .post(formBody) .build();
方式二:用Android原生HttpURLConnection(无需第三方库)
如果你不想加第三方依赖,用原生的HttpURLConnection也能实现,就是代码繁琐一点:
Button ledOffBtn = findViewById(R.id.led_off_button); ledOffBtn.setOnClickListener(v -> { // 开子线程执行网络请求,不能在主线程! new Thread(() -> { HttpURLConnection connection = null; BufferedReader reader = null; try { URL url = new URL("http://192.168.1.100/control_led.php?action=off"); connection = (HttpURLConnection) url.openConnection(); connection.setRequestMethod("GET"); connection.setConnectTimeout(5000); // 5秒连接超时 connection.setReadTimeout(5000); // 5秒读取超时 int responseCode = connection.getResponseCode(); if (responseCode == HttpURLConnection.HTTP_OK) { // 读取服务器返回的内容 reader = new BufferedReader(new InputStreamReader(connection.getInputStream())); StringBuilder result = new StringBuilder(); String line; while ((line = reader.readLine()) != null) { result.append(line); } // 在主线程显示结果 runOnUiThread(() -> Toast.makeText(MainActivity.this, "LED已关闭:" + result.toString(), Toast.LENGTH_SHORT).show()); } else { runOnUiThread(() -> Toast.makeText(MainActivity.this, "服务器错误:" + responseCode, Toast.LENGTH_SHORT).show()); } } catch (Exception e) { e.printStackTrace(); runOnUiThread(() -> Toast.makeText(MainActivity.this, "操作失败:" + e.getMessage(), Toast.LENGTH_SHORT).show()); } finally { // 关闭资源 if (reader != null) { try { reader.close(); } catch (IOException e) { e.printStackTrace(); } } if (connection != null) { connection.disconnect(); } } }).start(); });
几个关键注意事项
- 不能在主线程发网络请求:Android从API 11开始就禁止在主线程执行网络操作,否则会抛出
NetworkOnMainThreadException,所以必须用异步线程(OkHttp的enqueue是异步,原生的要自己开Thread)。 - 确保设备在同一局域网:你的Android手机/平板和树莓派必须连接同一个WiFi,这样才能访问到树莓派的Web服务。
- 安全性问题:如果你的树莓派暴露在公网,一定要加身份验证(比如在PHP脚本里检查API密钥、用户名密码),避免被别人恶意调用控制你的设备。
内容的提问来源于stack exchange,提问作者ToddLowell
相关产品推荐
相关产品推荐

