在之前的帖子中,我想实现在 PC 端(也就是网页上)控制大疆无人机 https://www.v2ex.com/t/823520
在和大疆的客服沟通后,发现只能通过手机 APP 接遥控器的方式控制无人机
然后在网上找到了一个 NanoHTTPD 的库,心想我只要在网页上实现无人机的起飞降落和获取图传就可以了,那么是不是在 APP 里实现一个小型的 Web Server ,然后发送 Post 请求到手机 APP 是不是就可以了呢?
然后开始自学 Java 和 Android ,买了一台最便宜的大疆无人机 Mini SE
终于参照大疆的 Mobile SDK ,做了一个可以起飞降落和获取图传的 APP 。
心想接下去就是把 NanoHTTPD 库跟 APP 结合就可以了。
public class MainActivity extends AppCompatActivity {
private App myApp;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button startButton = (Button) findViewById(R.id.start_httpd);
Button stopButton = (Button) findViewById(R.id.stop_httpd);
Button take_off = (Button) findViewById(R.id.take_off);
Button landing = (Button) findViewById(R.id.landing);
startButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
try{
myApp = new App(this);
Log.e("onClick", "WebServer started");
}catch (IOException e){
e.printStackTrace();
Log.e("onClick", "WebServer start failed" + e.getMessage());
}
}
});
stopButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
if(myApp != null)
{
myApp.closeAllConnections();
myApp = null;
Log.e("onClick", "Web server close");
}
}
});
}
}
class App extends NanoHTTPD{
private String commandName;
private String operator;
public String getCommandName()
{
return commandName;
}
public String getOperator()
{
return operator;
}
public App(View.OnClickListener onClickListener) throws IOException {
super(8080);
start(NanoHTTPD.SOCKET_READ_TIMEOUT,false);
}
public void starting() throws IOException {
new App((View.OnClickListener) this);
}
private void requestBodyProcess(Map<String, String> map,String requestBody)
{
String requestBodyRegex = "\\w+=\\w+&\\w+=\\w+";
boolean isRequestBodyMatch = Pattern.matches(requestBodyRegex, requestBody);
if(isRequestBodyMatch)
{
Pattern command = Pattern.compile("(?<=\\bcommandName=)\\w+");
Matcher command_matcher = command.matcher(requestBody);
if(command_matcher.find())
{
map.put("commandName", command_matcher.group(0));
}
command = Pattern.compile("(?<=\\boperator=)\\w+");
command_matcher = command.matcher(requestBody);
if(command_matcher.find())
{
map.put("operator", command_matcher.group(0));
}
}
else
{
map = null;
}
}
@Override
public Response serve(IHTTPSession session) {
Map<String, String> files = new HashMap<String, String>();
Map<String, String> map = new HashMap<String, String>();
// HTTP GET
if (session.getMethod() == Method.GET) {
String itemIdRequestParameter = session.getParameters().get("itemId").get(0);
return newFixedLengthResponse("Requested itemId = " + itemIdRequestParameter);
}
// HTTP POST
if (session.getMethod() == Method.POST) {
try {
session.parseBody(files);
String requestBody = session.getQueryParameterString();
requestBodyProcess(map,requestBody);
commandName = map.get("commandName");
operator = map.get("operator");
return newFixedLengthResponse("Command Name = " + map.get("commandName") + "\n" + "Operator = "
+ map.get("operator") );
} catch (IOException | ResponseException e) {
// handle
}
}
return newFixedLengthResponse(Response.Status.NOT_FOUND, MIME_PLAINTEXT,
"The requested resource does not exist");
}
}
我在 APP 类里实现了获取 Post 发送过来的是起飞还是降落commandName
,但是我在MainActivity
根本不知道myApp
这个对象在哪里了,startButton
的onClick
执行后,myApp
被创建了,但是之后去了哪里?我又能在哪里再次操作它呢。。。
我怎么才能在获取到起飞的 Post 请求后,调用起飞按钮呢?
请教一下我应该去补充什么知识呢?感谢了!
这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。
V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。
V2EX is a community of developers, designers and creative people.