这是我项目的架构:
1)Android应用 - > 2)RPi上的Apache服务器 - > 3)控制的Python脚本 - > 4)我的设备
1)Android应用 - 2个简单的开关,每个开关在RPi上向Apache发送不同的请求:
public class MainActivity extends Activity{
private static final String TAG = "MainActivity";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Switch switch_auto = findViewById(R.id.switch_auto);
Switch switch_manual = findViewById(R.id.switch_manual);
switch_auto.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
if (isChecked) {
new Background_get().execute("led1=1");
} else {
new Background_get().execute("led1=0");
}
}
});
switch_manual.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
if (isChecked) {
Log.d(TAG, "onCheckedChanged: SET TO TRUE");
new Background_get().execute("led2=1");
Log.d(TAG, "onCheckedChanged: EXIT");
} else {
Log.d(TAG, "onCheckedChanged: SET TO FALSE");
new Background_get().execute("led2=0");
Log.d(TAG, "onCheckedChanged: EXIT");
}
}
});
}
private class Background_get extends AsyncTask<String, Void, String> {
@Override
protected String doInBackground(String... params) {
try {
URL url = new URL("http://192.168.0.248/?" + params[0]);
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
BufferedReader in = new BufferedReader(new InputStreamReader(connection.getInputStream()));
StringBuilder result = new StringBuilder();
String inputLine;
while ((inputLine = in.readLine()) != null)
result.append(inputLine).append("\n");
in.close();
connection.disconnect();
return result.toString();
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
}
}
2)RPi上的Apache服务器 - 非常简单的PHP代码:
time.sleep(10)
)while True: time.sleep(1)
)我的问题:我可以通过网络浏览器使用这些脚本正确控制我的设备,例如:
出于测试目的,这是Apache2的 led1 的access.log(= 1使其工作10秒,= 0只会打印一行):
192.168.0.10 - - [01 / Mar / 2018: 10:42:01 +0100]&#34; GET /? led1 = 1 HTTP / 1.1 &#34; 200 411&#34; - &#34; &#34; Mozilla / 5.0(Windows NT 6.1; Win64; x64) AppleWebKit / 537.36(KHTML,与Gecko一样)Chrome / 64.0.3282.186 Safari浏览器/ 537.36&#34;
(它开始工作)
192.168.0.10 - - [01 / Mar / 2018: 10:42:05 +0100]&#34; GET /? led1 = 0 HTTP / 1.1 &#34; 200 233&#34; - &#34; &#34; Mozilla / 5.0(Windows NT 6.1; Win64; x64) AppleWebKit / 537.36(KHTML,与Gecko一样)Chrome / 64.0.3282.186 Safari浏览器/ 537.36&#34;
(4秒后获得led1 = 0并且led1 = 1&s;脚本仍然可以工作几秒钟没问题)
很遗憾,我不能对我的Android应用做同样的事情。这是Apache的日志:
192.168.0.66 - - [01 / Mar / 2018: 10:36:53 +0100]&#34; GET /? led1 = 1 HTTP / 1.1 &#34; 200 411&#34; - &#34; &#34; Dalvik / 2.1.0(Linux; U; Android 8.1.0; Nexus 5X 建立/ OPM3.171019.014)&#34;
(我制作一个&#34;关闭&#34; 5秒后但...... )
192.168.0.66 - - [01 / Mar / 2018: 10:37:07 +0100]&#34; GET /? led1 = 0 HTTP / 1.1 &#34; 200 232&#34; - &#34; &#34; Dalvik / 2.1.0(Linux; U; Android 8.1.0; Nexus 5X 建立/ OPM3.171019.014)&#34;
(它没有!注意差异14秒(它启动大约3秒,然后工作10秒)。在led1 = 1脚本完成工作后收到GET )。
当脚本工作10秒(led1)时,这是一个问题,但是当脚本在无限循环(led2)中工作时出现了一个大问题 - 我无法在第一个脚本停止之前将其破坏(但它是在真正的循环......)
我在第二个脚本中考虑使用Python subprocess.check_call()
来杀掉第一个脚本,但它似乎没什么帮助。
任何想法如何解决这个问题?
答案 0 :(得分:0)
最后,我设法做到了。杀死无限循环的想法是正确的,但首先我考虑在Python脚本上做错,这是错误的。
我注意到,当本地.php网站加载时(由于while循环),这些GET响应没有出现在日志中,因此需要中止当前的GET。它可以用Apache的httpcomponents完成。
因此经过一些修改后,我的代码看起来像这样:
public class MainActivity extends AppCompatActivity {
private static final String TAG = "MainActivity";
boolean flagToggle = true;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Switch switch_auto = findViewById(R.id.switch_auto);
Switch switch_manual = findViewById(R.id.switch_manual);
switch_auto.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
HttpGet requestOn = new HttpGet();
HttpGet requestOff = new HttpGet();
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
if (!flagToggle) {
requestOn = new HttpGet();
requestOff = new HttpGet();
flagToggle = true;
}
Background_get switchOn = new Background_get(requestOn);
Background_get switchOff = new Background_get(requestOff);
if (isChecked) {
switchOn.execute("led1=1");
}
else {
requestOn.abort();
switchOff.execute("led1=0");
flagToggle = false;
}
}
});
switch_manual.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
HttpGet requestOn = new HttpGet();
HttpGet requestOff = new HttpGet();
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
if (!flagToggle) {
requestOn = new HttpGet();
requestOff = new HttpGet();
flagToggle = true;
}
Background_get switchOn = new Background_get(requestOn);
Background_get switchOff = new Background_get(requestOff);
if (isChecked) {
switchOn.execute("led2=1");
}
else {
requestOn.abort();
switchOff.execute("led2=0");
flagToggle = false;
}
}
});
}
public class Background_get extends AsyncTask<String, Void, String> {
private HttpGet mRequest = new HttpGet();
public Background_get(HttpGet newRequest) {
mRequest = newRequest;
}
public HttpGet getRequest() {
return mRequest;
}
public void setRequest(HttpGet newRequest) {
mRequest = newRequest;
}
@Override
protected String doInBackground(String... params) {
try {
URI url = new URI("http://192.168.0.248/?" + params[0]);
// HttpURLConnection connection = (HttpURLConnection) url.openConnection();
HttpClient httpclient = new DefaultHttpClient();
getRequest().setURI(url);
HttpResponse response = httpclient.execute(getRequest());
BufferedReader in = new BufferedReader(new InputStreamReader(response.getEntity().getContent()));
StringBuilder result = new StringBuilder();
String inputLine;
while ((inputLine = in.readLine()) != null)
result.append(inputLine).append("\n");
in.close();
// response.close();
// httpclient.close();
return result.toString();
} catch (IOException e) {
e.printStackTrace();
} catch (URISyntaxException e) {
e.printStackTrace();
}
return null;
}
}
}
值得注意的事情: