在安卓端实现一个能接收 POST 请求(JSON 格式)的本地服务器接口,核心是借助安卓的网络编程能力搭建轻量级 HTTP 服务器。下面我会用 NanoHttpd(轻量级、易集成的 HTTP 服务器库)来实现,这是安卓端做本地服务器最常用且简单的方案。
一、实现思路
- 集成 NanoHttpd 依赖,简化 HTTP 服务器开发;
- 自定义服务器类,继承 NanoHttpd,重写
serve()方法处理请求; - 在
serve()中判断请求方式(POST)、解析 JSON 数据; - 配置安卓权限(网络、前台服务,避免后台被杀死);
- 启动 / 停止服务器,测试接口可用性。
二、完整实现步骤
1. 添加依赖(build.gradle)
在模块级 build.gradle(Module: app)的 dependencies 中添加 NanoHttpd 依赖:
gradle
dependencies {
// 轻量级HTTP服务器库
implementation 'org.nanohttpd:nanohttpd:2.3.1'
// 可选:Gson解析JSON(也可用Android自带的JSONObject)
implementation 'com.google.code.gson:gson:2.10.1'
}
同步 Gradle(Sync Now)确保依赖下载完成。
2. 自定义 HTTP 服务器类
创建 LocalHttpServer 类,处理 POST 请求并解析 JSON:
java
运行
java
import android.util.Log;
import fi.iki.elonen.NanoHTTPD;
import com.google.gson.Gson;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Map;
// 自定义服务器类,指定端口(比如8080,可自定义)
public class LocalHttpServer extends NanoHTTPD {
private static final String TAG = "LocalHttpServer";
// 定义接口路径
private static final String API_PATH = "/callBack";
private final Gson gson = new Gson();
public LocalHttpServer() {
// 端口号:建议选1024以上(避免系统端口),比如8080
super(8080);
}
@Override
public Response serve(IHTTPSession session) {
// 1. 判断请求方式是否为POST
if (!Method.POST.equals(session.getMethod())) {
// 非POST请求返回405(方法不允许)
return newFixedLengthResponse(Response.Status.METHOD_NOT_ALLOWED,
"application/json", "{\"code\":405,\"msg\":\"仅支持POST请求\"}");
}
// 2. 判断请求路径是否匹配目标接口
String uri = session.getUri();
if (!API_PATH.equals(uri)) {
// 路径不匹配返回404
return newFixedLengthResponse(Response.Status.NOT_FOUND,
"application/json", "{\"code\":404,\"msg\":\"接口不存在\"}");
}
try {
// 3. 解析POST请求中的JSON数据
Map<String, String> files = new java.util.HashMap<>();
session.parseBody(files);
// 获取请求体(JSON字符串)
String jsonBody = files.get("postData");
Log.d(TAG, "接收到的JSON数据:" + jsonBody);
// 示例:解析JSON为自定义对象(根据你的业务调整)
// 假设接收的JSON结构是 {"orderId":"123","amount":100}
NotifyData notifyData = gson.fromJson(jsonBody, NotifyData.class);
Log.d(TAG, "解析后:订单ID=" + notifyData.getOrderId() + ",金额=" + notifyData.getAmount());
// 4. 处理业务逻辑(比如保存数据、回调等)
// TODO: 这里写你的业务代码
// 5. 返回响应(JSON格式)
String responseJson = gson.toJson(new ResponseData(200, "接收成功", notifyData));
return newFixedLengthResponse(Response.Status.OK,
"application/json;charset=UTF-8", responseJson);
} catch (IOException | ResponseException e) {
Log.e(TAG, "解析请求失败", e);
// 异常返回500
return newFixedLengthResponse(Response.Status.INTERNAL_ERROR,
"application/json", "{\"code\":500,\"msg\":\"服务器内部错误\"}");
}
}
// 接收的JSON数据模型(根据你的实际需求定义)
public static class NotifyData {
private String orderId;
private double amount;
// getter/setter
public String getOrderId() { return orderId; }
public void setOrderId(String orderId) { this.orderId = orderId; }
public double getAmount() { return amount; }
public void setAmount(double amount) { this.amount = amount; }
}
// 响应数据模型
public static class ResponseData {
private int code;
private String msg;
private NotifyData data;
public ResponseData(int code, String msg, NotifyData data) {
this.code = code;
this.msg = msg;
this.data = data;
}
// getter/setter(Gson需要)
public int getCode() { return code; }
public void setCode(int code) { this.code = code; }
public String getMsg() { return msg; }
public void setMsg(String msg) { this.msg = msg; }
public NotifyData getData() { return data; }
public void setData(NotifyData data) { this.data = data; }
}
}
3. 配置安卓权限
在 AndroidManifest.xml 中添加必要权限(注意安卓 6.0 + 部分权限需动态申请,但网络权限是普通权限):
xml
<!-- 网络权限 -->
<uses-permission android:name="android.permission.INTERNET" />
<!-- 允许访问网络状态 -->
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<!-- 前台服务权限(避免服务器被后台杀死) -->
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
<!-- 如果你的应用是安卓12+,需要声明前台服务类型 -->
<application ...>
<service
android:name=".LocalServerService"
android:foregroundServiceType="dataSync|network" />
</application>
4. 封装为前台服务(避免服务器被杀死)
安卓后台进程容易被系统回收,建议将服务器放在前台服务中运行:
java
运行
java
import android.app.Notification;
import android.app.NotificationChannel;
import android.app.NotificationManager;
import android.app.Service;
import android.content.Intent;
import android.os.Build;
import android.os.IBinder;
import androidx.core.app.NotificationCompat;
public class LocalServerService extends Service {
private LocalHttpServer httpServer;
@Override
public void onCreate() {
super.onCreate();
// 启动HTTP服务器
try {
httpServer = new LocalHttpServer();
httpServer.start();
// 启动前台服务
startForeground(1, createNotification());
} catch (IOException e) {
e.printStackTrace();
}
}
@Override
public void onDestroy() {
super.onDestroy();
// 停止服务器
if (httpServer != null) {
httpServer.stop();
}
}
@Override
public IBinder onBind(Intent intent) {
return null;
}
// 创建前台服务通知
private Notification createNotification() {
String channelId = "LocalServerChannel";
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
NotificationChannel channel = new NotificationChannel(
channelId, "本地服务器", NotificationManager.IMPORTANCE_LOW);
NotificationManager manager = getSystemService(NotificationManager.class);
manager.createNotificationChannel(channel);
}
return new NotificationCompat.Builder(this, channelId)
.setContentTitle("本地服务器运行中")
.setContentText("端口:8080")
.setSmallIcon(android.R.drawable.ic_menu_info_details)
.build();
}
}
5. 在 Activity 中启动 / 停止服务
java
运行
java
import android.content.Intent;
import android.os.Bundle;
import androidx.appcompat.app.AppCompatActivity;
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// 启动本地服务器服务
Intent serviceIntent = new Intent(this, LocalServerService.class);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
startForegroundService(serviceIntent);
} else {
startService(serviceIntent);
}
}
@Override
protected void onDestroy() {
super.onDestroy();
// 停止服务(测试用,实际根据需求调整)
stopService(new Intent(this, LocalServerService.class));
}
}
三、测试接口
- 运行安卓应用,确保服务启动(通知栏会显示 "本地服务器运行中");
- 获取安卓设备的 IP 地址(设置 - 关于手机 - 状态信息 - IP 地址,比如
192.168.1.100); - 用 Postman/Postwoman 等工具发送 POST 请求:
-
请求地址:
http://192.168.1.100:8080/callBack -
请求体:JSON 格式(示例) json
{ "orderId": "TEST123456", "amount": 99.9 } -
请求头:
Content-Type: application/json
-
- 查看安卓 Logcat,能看到 "接收到的 JSON 数据" 日志,说明接口正常工作。
四、注意事项
- 端口冲突:如果 8080 端口被占用,可修改服务器构造方法中的端口(比如 8081、9090);
- 网络环境:测试时确保请求端(比如电脑)和安卓设备在同一局域网;
- HTTPS 支持:NanoHttpd 默认是 HTTP,如需 HTTPS,需配置 SSL 证书(安卓端可生成自签名证书);
- 线程安全 :如果接口并发请求多,需在
serve()中处理线程同步; - 安卓版本适配:安卓 10 + 限制后台网络,前台服务可规避此问题。
总结
- 安卓端搭建接收 POST (JSON) 的服务器,首选 NanoHttpd 库,轻量且易集成;
- 核心是重写
serve()方法,判断请求方式 / 路径、解析 JSON、处理业务并返回响应; - 服务器需放在前台服务中运行,避免被安卓系统后台回收,同时要配置网络权限。
通过以上代码,你可以实现类似 https://opnqiaryuankejinet/prod-api/pos/kPayNotify 的接口(仅协议为 HTTP,如需 HTTPS 可扩展 SSL 配置),成功接收并解析 POST 的 JSON 数据。