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

如何在Android Studio中发起HTTP请求触发树莓派PHP脚本且不加载网页

在Android onClick中调用树莓派的PHP脚本(无需加载网页)

这问题我之前帮朋友解决过,核心就是给你的PHP脚本发个HTTP请求就行,完全不用加载网页——毕竟你只需要触发脚本执行,不是要显示网页内容。下面给你两种靠谱的实现方式,还有要注意的坑:

第一步:先搞定Android的网络权限和配置

首先得让你的App能访问网络,还要处理Android 9+的明文HTTP限制(如果你的树莓派用的是HTTP而不是HTTPS的话):

  1. 添加网络权限
    在AndroidManifest.xml里的<manifest>标签下添加:
<uses-permission android:name="android.permission.INTERNET" />
  1. 处理明文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好用太多。

  1. 添加依赖
    在你的Module级build.gradle(通常是app/build.gradle)的dependencies块里添加:
implementation 'com.squareup.okhttp3:okhttp:4.12.0'

(可以去OkHttp官网看最新版本,这个是稳定版)

  1. 在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());
            }
        }
    });
});
  1. 如果要用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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.14 08:43:19