模拟操作智能农业项目
程序员文章站
2022-04-18 08:27:48
...
一、模拟智能农业项目简介
通过手机APP操作模拟智能农业系统。通过手机来获取农业沙盘数据,例如:温度、湿度等。实现对沙盘设备的控制,例如:开、关灯,开、关水泵等等。
二、功能需求及可行性分析:
功能需求:
可以获取沙盘数据;
可以控制沙盘设备;
获取设备开关状态;
可行性分析:
通过API文档获取JSON数据接口:
例如获取传感器的值:http://192.168.1.119:8890/type/jason/action/getSensor
注意:接口文档中的IP需改为开发时实际对应的IP
10.44.1.104
这样就能够获取到传感器的数据了。
三、代码实现:
首先将各个页面布局做好:
欢迎界面:
效果:
打开程序、跳出对话框,获取对应沙盘IP
代码如下:
public class WelcomeActivity extends AppCompatActivity {
public static String url;
public EditText input_edt;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_welcome);
AlertDialog.Builder builder = new AlertDialog.Builder(WelcomeActivity.this);
View view = View.inflate(WelcomeActivity.this, R.layout.alertdialog, null);
builder.setView(view);
builder.setCancelable(true);
TextView title = (TextView) view.findViewById(R.id.title);//设置标题
input_edt = (EditText) view.findViewById(R.id.dialog_edit);//输入内容
Button btn_comfirm = (Button) view.findViewById(R.id.btn_comfirm);//确定按钮
//取消或确定按钮监听事件处理
AlertDialog dialog = builder.create();
btn_comfirm.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
//传输IP
url=input_edt.getText().toString();
Intent intent = new Intent(WelcomeActivity.this, MainActiviy.class);
startActivity(intent);
}
});
dialog.show();
}
}
主页面:
效果图:
头部图片使用ViewPager与Fragment结合实现图片滑动效果
创建MainFargmentAdapter继承自FragmentPagerAdapter:
public class MainFargmentAdapter extends FragmentPagerAdapter {
private List<Fragment> fragmentList;
public MainFargmentAdapter(FragmentManager fm,List<Fragment> fragments) {
super(fm);
this.fragmentList=fragments;
}
@Override
public Fragment getItem(int position) {
return fragmentList.get(position);
}
@Override
public int getCount() {
return fragmentList.size();
}
}
创建三个PicFragment,放入图片,代码简单,所以省略。
然后在MainActivity里修改代码如下:
private ViewPager viewPager;
private Pic1Fragment pic1Fragment;
private Pic2Fragment pic2Fragment;
private Pic3Fragment pic3Fragment;
private List<Fragment> fragmentList = new ArrayList<>();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_mian2);
bindId();
pic1Fragment = new Pic1Fragment();
pic2Fragment = new Pic2Fragment();
pic3Fragment = new Pic3Fragment();
fragmentList.add(pic1Fragment);
fragmentList.add(pic2Fragment);
fragmentList.add(pic3Fragment);
//创建适配器、绑定适配器
MainFargmentAdapter adapter = new MainFargmentAdapter(getSupportFragmentManager(), fragmentList);
viewPager.setAdapter(adapter);
}
获取传感器的值:
首先,创建一个公共的OKHttPClint类,连接数据接口,创建两个方法,get和Post方法:
//获取WelcomeActivity中传过来的IP
public static final String BASE_URL = "http://"+WelcomeActivity.url+":8890/type/jason/action/";
public static OkHttpClient client = new OkHttpClient();
public static void getOkHttp(String address, okhttp3.Callback callback) {
Request request = new Request.Builder().url(getAbsoluteUrl(address)).build();
client.newCall(request).enqueue(callback);
}
public static void postOkHttp(String url, JSONObject jsonObject, Callback callback){
MediaType mediaType=MediaType.parse("application/json;charset=UTF-8");
RequestBody requestBody=RequestBody.create(mediaType,jsonObject.toString());
Request request=new Request.Builder().url(getAbsoluteUrl(url)).post(requestBody).build();
client.newCall(request).enqueue(callback);
}
private static String getAbsoluteUrl(String relation) {
return BASE_URL + relation;
}
}
修改MainActivity的代码,获取传感器的值使用的是get方法:
获取数据是耗时操作,要使用runOnUiThread方法更新UI。
HttpUtilOk.getOkHttp("getSensor", new Callback() {
@Override
public void onResponse(Call call, Response response) throws IOException {
cancleProgress();
String url = response.body().string();
try {
JSONObject object = new JSONObject(url);
co2 = object.getString("co2");
light = object.getString("light");
soilwen = object.getString("soilTemperature");
soilshi = object.getString("soilHumidity");
airwen = object.getString("airTemperature");
airshi = object.getString("airHumidity");
//将解析下来的数据放入控件中
runOnUiThread(new Runnable() {
@Override
public void run() {
co2Tv.setText("co2:" + co2 );
lightTv.setText("光照: " + light);
soilwenTv.setText("温度: " + soilwen);
soilshiTv.setText(" 湿度:" + soilshi);
airwenTv.setText("温度:" + airwen);
airshiTv.setText(" 湿度:" + airshi);
}
});
} catch (JSONException e) {
e.printStackTrace();
}
}
@Override
public void onFailure(Call call, IOException e) {
cancleProgress();
}
});
以上代码就能够在主页上获取沙盘的数据;
控制沙盘设备
以CO2界面为例,控制风扇和警报设备:
效果图:
由于其余三个界面都需要实现相同的设备控制,
所以在这里我将控制风扇、警报、灯光、水泵四个方法单独封装起来:
例如开、关风扇的方法,其余几个方法同下:
public class Blower {
private int number=0;
private Context mcontext;
HttpUtil util=new HttpUtil();
final String url = util.BASE_URL;
public void kaiFengShan() {
JSONObject object=new JSONObject();
try {
object.put("Blower",1);
} catch (JSONException e) {
e.printStackTrace();
}
HttpUtilOk.postOkHttp("control", object, new Callback() {
@Override
public void onFailure(Call call, IOException e) {
}
@Override
public void onResponse(Call call, Response response) throws IOException {
}
});
}
public void guanFengShan() {
JSONObject object=new JSONObject();
try {
object.put("Blower",0);
} catch (JSONException e) {
e.printStackTrace();
}
HttpUtilOk.postOkHttp("control", object, new Callback() {
@Override
public void onFailure(Call call, IOException e) {
}
@Override
public void onResponse(Call call, Response response) throws IOException {
}
});
}
}
获取沙盘设备当前状态
创建一个Status类,封装一个获取状态的方法controlAll,定义四个公共的静态变量,用来传当前设备状态:
public class Status {
public static int waterPumpStatus ;
public static int roadLampStatus;
public static int buzzerStatus;
public static int blowerStatus;
public static void controlAll(){
HttpUtilOk.getOkHttp("getContorllerStatus", new Callback() {
@Override
public void onFailure(Call call, IOException e) {
}
@Override
public void onResponse(Call call, Response response) throws IOException {
String result=response.body().string();
JSONObject object = null;
try {
object = new JSONObject(result);
waterPumpStatus = object.getInt("WaterPump");
roadLampStatus = object.getInt("Roadlamp");
buzzerStatus = object.getInt("Buzzer");
blowerStatus = object.getInt("Blower");
} catch (JSONException e) {
e.printStackTrace();
}
}
});
}
}
公共的方法已经封装好了,接下来就可以根据页面需求使用:
获取Buzzer 、Blower 对象,
定义标志位:buzzerInt和blowerInt获取Status传过来的设备状态
更新图标
public class Co2Activity extends AppCompatActivity implements View.OnClickListener {
private ImageView fengShanIm;
private ImageView jingbaoIm;
Buzzer buzzer=new Buzzer();
Blower blower=new Blower();
private int buzzerInt;
private int blowerInt;
private TextView nongduTV;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_co2);
bindId();
//进入页面就获取当前设备状态
Status.controlAll();
//获取设备状态
buzzerInt = Status.buzzerStatus;
blowerInt = Status.blowerStatus;
//进入页面就更新图标
queryBlower();
queryBuzzerImage();
}
private void bindId() {
fengShanIm = findViewById(R.id.Co2_dakaifengshan);
jingbaoIm = findViewById(R.id.Co2_dakaijingbao);
nongduTV=findViewById(R.id.Co2_nongdu);
fengShanIm.setOnClickListener(this);
jingbaoIm.setOnClickListener(this);
}
@Override
public void onClick(View view) {
switch (view.getId()) {
case R.id.Co2_dakaifengshan:
blowerInt++;
queryBlower();
if (blowerInt%2==1){
blower.kaiFengShan();
}else if (blowerInt%2==0){
blower.guanFengShan();
}
break;
case R.id.Co2_dakaijingbao:
buzzerInt++;
queryBuzzerImage();
if (buzzerInt%2==1){
buzzer.kaiJingbao();
}else if (buzzerInt%2==0){
buzzer.guanJingbao();
}
break;
}
}
//根据状态更新图标
public void queryBlower(){
if (blowerInt % 2 == 0) {
fengShanIm.setImageResource(R.drawable.dakaifengshan);
} else if (blowerInt % 2 == 1) {
fengShanIm.setImageResource(R.drawable.dakaifengshan2);
}
}
private void queryBuzzerImage() {
if (buzzerInt % 2 == 0) {
jingbaoIm.setImageResource(R.drawable.dakaibaojing);
} else if (buzzerInt % 2 == 1) {
jingbaoIm.setImageResource(R.drawable.dakaibaojing2);
}
}
}
以上就可以实现三个最核心的功能,其余页面可以根据以上代码继续完善。