Android后台Service中使用OkHttpClient POST发送JSON至PHP WebAPI
Android后台Service通过OkHttpClient向PHP接口发送JSON数据解决方案
我来帮你梳理并修正这个Android后台Service发送JSON到PHP接口的实现方案,确保两端能正确交互:
Android端完整实现代码
在后台Service里发送网络请求绝对不能在主线程执行,否则会直接抛出NetworkOnMainThreadException,所以我们用OkHttp的异步请求来处理。下面是修正后的可运行代码片段:
import okhttp3.OkHttpClient; import okhttp3.Request; import okhttp3.RequestBody; import okhttp3.MediaType; import okhttp3.Call; import okhttp3.Callback; import okhttp3.Response; import org.json.JSONObject; import android.app.Service; import android.content.Intent; import android.os.IBinder; import android.util.Log; import java.io.IOException; public class DataUploadService extends Service { private static final String TAG = "DataUploadService"; private static final MediaType JSON = MediaType.parse("application/json; charset=utf-8"); private final OkHttpClient client = new OkHttpClient(); @Override public int onStartCommand(Intent intent, int flags, int startId) { // 构造你要发送的JSON数据 JSONObject jsonObject = new JSONObject(); try { // 示例数据,替换成你的实际字段 jsonObject.put("username", "test_user"); jsonObject.put("age", 25); jsonObject.put("is_active", true); } catch (Exception e) { Log.e(TAG, "JSON构造失败: " + e.getMessage()); stopSelf(); return START_NOT_STICKY; } String requestJson = jsonObject.toString(); // 发起异步POST请求 sendPostRequest("http://cbs.octa.in/webapis/InsertData.php", requestJson); return START_STICKY; } private void sendPostRequest(String url, String jsonBody) { RequestBody body = RequestBody.create(jsonBody, JSON); Request request = new Request.Builder() .url(url) .post(body) .build(); client.newCall(request).enqueue(new Callback() { @Override public void onFailure(Call call, IOException e) { Log.e(TAG, "请求失败: " + e.getMessage()); // 这里可以添加重试逻辑或者发送广播通知前端失败 stopSelf(); } @Override public void onResponse(Call call, Response response) throws IOException { if (response.isSuccessful()) { String responseContent = response.body().string(); Log.d(TAG, "服务器响应: " + responseContent); // 处理响应数据,比如解析返回的JSON } else { Log.e(TAG, "响应失败,状态码: " + response.code()); } stopSelf(); } }); } @Override public IBinder onBind(Intent intent) { return null; } }
PHP端接口修正代码
你的PHP代码思路是对的,但要注意不要依赖$_POST数组——当请求的Content-Type是application/json时,PHP不会自动把JSON数据解析到$_POST里,直接用php://input读取才是正确方式。下面是完善后的接口代码:
<?php // 设置响应头为JSON格式,避免乱码 header('Content-Type: application/json; charset=utf-8'); // 读取请求体中的原始JSON数据 $rawRequestData = file_get_contents('php://input'); // 解析JSON为关联数组 $parsedData = json_decode($rawRequestData, true); // 检查JSON解析是否成功 if ($parsedData === null) { http_response_code(400); // 返回400错误码表示请求无效 echo json_encode([ 'status' => 'error', 'message' => '无效的JSON数据,请检查请求格式' ]); exit; } // 这里写你的业务逻辑,比如插入数据库 // 示例:假设插入到user表 // $db = new mysqli('localhost', 'db_user', 'db_pass', 'db_name'); // if ($db->connect_error) { // echo json_encode(['status' => 'error', 'message' => '数据库连接失败']); // exit; // } // $stmt = $db->prepare("INSERT INTO user (username, age, is_active) VALUES (?, ?, ?)"); // $stmt->bind_param("sii", $parsedData['username'], $parsedData['age'], $parsedData['is_active']); // $stmt->execute(); // 返回成功响应 echo json_encode([ 'status' => 'success', 'message' => '数据接收成功', 'received_data' => $parsedData ]); ?>
关键注意事项
Android端
- 权限配置:在
AndroidManifest.xml中必须添加网络权限:<uses-permission android:name="android.permission.INTERNET" /> <!-- 如果需要检测网络状态,可添加 --> <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> - OkHttp依赖:在Module级别的
build.gradle中添加依赖(版本可以用最新稳定版):implementation 'com.squareup.okhttp3:okhttp:4.12.0' - 后台限制:Android 10及以上版本对后台Service有严格限制,如果需要长期在后台运行,建议改用
WorkManager或者适配后台启动规则。
PHP端
- 服务器配置:确保服务器开启了
allow_url_fopen(大部分默认开启),否则file_get_contents无法读取php://input。 - 错误处理:一定要处理JSON解析失败的情况,避免无效请求导致服务器报错。
内容的提问来源于stack exchange,提问作者JavaEnthusias
相关产品推荐
相关产品推荐

