Android 练习 :智能农业项目
一.项目需求:
1、应用需要登录后才能进入应用首页。
2、工作台为用户展示最新的功能轮播图
3、展示沙盘中Co2、光照、空气、土壤等情况
4、用户可在详情页设置沙盘设备的开关来改变沙盘内的Co2、光照、空气、土壤等情况
5、用户可在阀值设置页,设置Co2、光照、空气、土壤等阀值。
二.项目实现:
1.整个项目分为两个主要界面(一个登陆界面,一个主体界面)
1)登陆界面:只是一个用来输入ip值的地方,没有太多的技术含量,这里主要是用正则表达式来判断输入的是否是一个正确的ip地址。
private boolean isIP(String ip) {
boolean b = false;
/**
* 可以直接百度正则表达式 Java ip
*/
boolean matches = ip.matches("\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}");
if (matches) {
String[] split = ip.split("\\.");
if (Integer.parseInt(split[0]) <= 255) {
if (Integer.parseInt(split[1]) <= 255) {
if (Integer.parseInt(split[2]) <= 255) {
if (Integer.parseInt(split[3]) <= 255) {
b = true;
}
}
}
}
}
return b;
}
2)主界面:主界面里又分为最重要的三个页面,这里我将 ViewPager和Fragement结合 起来使用。以此让这三个页面既可以滑动也可以点击切换。
这里为了防止误点返回键退出程序,我设置了点击两次退出:
public boolean onKeyDown(int keyCode, KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_BACK) {
/**
* //第一次点击
* 获取系统时间
*/
if (System.currentTimeMillis() - mExitTime > 2000) {
Toast.makeText(this, "再次点击返回键退出程序", Toast.LENGTH_SHORT).show();
mExitTime = System.currentTimeMillis();
} else {
finish();
}
//return true 是为了停止返回功能
return true;
}
return super.onKeyDown(keyCode, event);
}
进入第一个fragement:上方的图片是可以自动轮播的图片上还有三个小圆点跟随图片变化而变化
小圆点随图片滑动变化
index 数组索引 0 1 2
public void setTipsBack(int index) {
for (int i = 0; i < tips.length; i++) { //i: 0 1 2
if (i == index) {
tips[i].setBackgroundResource(R.mipmap.page_indicator_focused);
} else {
tips[i].setBackgroundResource(R.mipmap.page_indicator_unfocused);
}
}
}`
写一个Adapter适配器用来加载图片
public class MyAdapter extends PagerAdapter {
@Override
public int getCount() {
return Integer.MAX_VALUE;
}
@Override
public boolean isViewFromObject(View view, Object object) {
return view == object;
}
@Override
public void destroyItem(ViewGroup container, int position, Object object) {
}
@Override
//提前预加载
public Object instantiateItem(ViewGroup container, int position) {
/**
* 取余进行循环播放
*/
int i = position % ivTemp.length;
ImageView imageView = ivTemp[i]; //i=0 1 2
ViewParent vp = imageView.getParent(); //父容器
if (vp != null) {
//如果父容器不是空的 把父容器里的东西remove掉
//只要有imageview 父容器就不是空的
ViewGroup group = (ViewGroup) vp;
group.removeView(imageView);
}
container.addView(ivTemp[i]);//循环加载 要加载不一样的图片
return ivTemp[i];
}
}
进入第二个fragement:
这里就是一些简单的点击跳转,用Intent就可以实现。
进入第三个fragement:
这里的菜单下拉我用了动画Animator来写
展开页面:
private void open(final int i, ObjectAnimator scaleY) {
if (timer == null) {
timer = new Timer();
} else {
timer.cancel();
timer = new Timer();
}
timer.schedule(new TimerTask() {
private float dipValue = 0;
@Override
public void run() {
dipValue += 1;
if (dipValue > 150) {
timer.cancel();
} else {
Message msg = new Message();
msg.what = i;
msg.obj = dipValue;
handler.sendMessage(msg);
}
}
}, 1, 1);
scaleY.start();
}
收起页面:
private void close(final int i, ObjectAnimator scaleY) {
if (timer == null) {
timer = new Timer();
} else {
timer.cancel();
timer = new Timer();
}
timer.schedule(new TimerTask() {
private float dipValue = 150;
@Override
public void run() {
dipValue -= 1;
if (dipValue < 0) {
timer.cancel();
} else {
Message msg = new Message();
msg.what = i;
msg.obj = dipValue;
handler.sendMessage(msg);
}
}
}, 1, 1);
scaleY.start();
}
判断页面是展开还是收起:
private ObjectAnimator setAnimation(boolean b, View view) {
ObjectAnimator scaleY;
if (b) {
scaleY = ObjectAnimator.ofFloat(view, "scaleY", 0.01f, 1f);
scaleY.setDuration(250);
} else {
scaleY = ObjectAnimator.ofFloat(view, "ScaleY", 1f, 0.01f);
scaleY.setDuration(300);
}
return scaleY;
}
3) 对沙盘进行一些操作 如:打开关闭风扇,水泵等 还有获取和设定沙盘的数值。
这里因为要连接Json接口,所以我用了okhttp架包来写(第三方架包,只需要会用就行)。
这里我把所有的沙盘数据都封装在了一个工具类MyApp里。
这里所有的okhttp我也封装在了一个MyOkHttp工具类里。
这样哪里需要这些方法我就可以直接去调用。
1.连接沙盘:
public String getData(MyApp myApp, String value, String action) throws IOException {
OkHttpClient client = new OkHttpClient();
RequestBody body = new FormBody.Builder().add("username", value).build();
Request request = new Request.Builder().url(getAbsoluteUrl(myApp, action)).post(body).build();
Response response = client.newCall(request).execute();
String data = response.body().string();
return data;
}
2.获取沙盘传感器最大值和最小值
public void getConfig(MyApp myApp) throws Exception {
String data = getData(myApp, "", "getConfig");
JSONObject jsonObject = new JSONObject(data);
myApp.setMinCo2(String.valueOf(jsonObject.getInt("minCo2")));//co2
myApp.setMaxCo2(String.valueOf(jsonObject.getInt("maxCo2")));
myApp.setMinLight(String.valueOf(jsonObject.getInt("minLight")));//灯光强度
myApp.setMaxLight(String.valueOf(jsonObject.getInt("maxLight")));
myApp.setMinSoilHumidity(String.valueOf(jsonObject.getInt("minSoilHumidity")));//土壤湿度
myApp.setMaxSoilHumidity(String.valueOf(jsonObject.getInt("maxSoilHumidity")));
myApp.setMinAirHumidity(String.valueOf(jsonObject.getInt("minAirHumidity")));//空气湿度
myApp.setMaxAirHumidity(String.valueOf(jsonObject.getInt("maxAirHumidity")));
myApp.setMinAirTemperature(String.valueOf(jsonObject.getInt("minAirTemperature")));//空气温度
myApp.setMaxAirTemperature(String.valueOf(jsonObject.getInt("maxAirTemperature")));
myApp.setMinSoilTemperature(String.valueOf(jsonObject.getInt("minSoilTemperature")));//土壤温度
myApp.setMaxSoilTemperature(String.valueOf(jsonObject.getInt("maxSoilTemperature")));
}
3.获取沙盘传感器的值
public String[] getSensor(MyApp myApp) throws IOException, JSONException {
String data = getData(myApp, "admin", "getSensor");
JSONObject jsonObject = new JSONObject(data);
String co2 = String.valueOf(jsonObject.getInt("co2")); //co2
String airHumidity = String.valueOf(jsonObject.getInt("airHumidity")); //空气湿度
String airTemperature = String.valueOf(jsonObject.getInt("airTemperature")); //空气温度
String soilTemperature = String.valueOf(jsonObject.getInt("soilTemperature"));//土壤温度
String soilHumidity = String.valueOf(jsonObject.getInt("soilHumidity"));//土壤湿度
String light = String.valueOf(jsonObject.getInt("light"));//灯光强度
String [] dataAarr = {co2,light,soilTemperature,soilHumidity,airTemperature,airHumidity};
return dataAarr;
}
4.获取控制器状态的协议
public int[] getContorllerStatus(MyApp myApp) throws IOException, JSONException {
String data = getData(myApp, "", "getContorllerStatus");
JSONObject jsonObject = new JSONObject(data);
int waterPump = jsonObject.getInt("WaterPump"); //水泵控制器开关
int Blower = jsonObject.getInt("Blower"); //风扇控制器开关
int Roadlamp = jsonObject.getInt("Roadlamp"); //灯光控制器开关
int Buzzer = jsonObject.getInt("Buzzer"); //蜂鸣器控制开关
int[] dataArr = {waterPump,Blower,Roadlamp,Buzzer};
return dataArr;
}
5.控制器协议
public void control(MyApp myApp,String controlName,int controlStatus) throws JSONException, IOException {
String url = getAbsoluteUrl(myApp, "control");
OkHttpClient client = new OkHttpClient();
JSONObject jsonObject=new JSONObject();
jsonObject.put(controlName,controlStatus);
RequestBody body = RequestBody.create(MediaType.parse("application/json"), String.valueOf(jsonObject));
Request request = new Request.Builder().url(url).post(body).build();
client.newCall(request).execute();
}
比如这里需要打开风扇
我只需要去调用MyOkHttp()里的方法来获取控制器状态,然后改变状态就行。
private void getContorllerStatus(int i){
new Thread(new Runnable() {
@Override
public void run() {
try {
int[] dataArr = myOkHttp.getContorllerStatus(myApp);
switch (i){
case 0:
Message message = new Message();
if (dataArr[1]==0){
myOkHttp.control(myApp,"Blower",1);
message.what=1001;
handler.sendMessage(message);
}else {
myOkHttp.control(myApp,"Blower",0);
message.what=1002;
handler.sendMessage(message);
}
break;
case 1:
Message message2 = new Message();
if (dataArr[3]==0){
myOkHttp.control(myApp,"Buzzer",1);
message2.what=2001;
handler.sendMessage(message2);
}else {
myOkHttp.control(myApp,"Buzzer",0);
message2.what=2002;
handler.sendMessage(message2);
}
break;
}
} catch (IOException e) {
e.printStackTrace();
} catch (JSONException e) {
e.printStackTrace();
}
}
}).start();
}
因为这里的图片再点击时也会更改,这是一个耗时操作,所以开了一个子线程来写,改图片用handle来写。
Handler handler = new Handler() {
@Override
public void handleMessage(Message msg) {
switch (msg.what){
case 1001:
include_dkfs.setImageResource(R.mipmap.dakaifengshan2);
break;
case 1002:
include_dkfs.setImageResource(R.mipmap.dakaifengshan);
break;
case 2001:
include_dkbj.setImageResource(R.mipmap.dakaibaojing2);
break;
case 2002:
include_dkbj.setImageResource(R.mipmap.dakaibaojing);
break;
case 3000:
String dataArr[] = (String[]) msg.obj;
f1_co2time.setText(dataArr[0]);
break;
}
}
};
小结:
因为是第一次使用json来连接沙盘,所以主要的难点就在于学习OkHttp去连接沙盘获取各种的数据,其他的东西基本上都是接触过的,比较基本的东西,只是要组合起来使用的熟练度还需要多多提升,写这个项目也用很多的错误发生,但是在debug的同时技术也会变得越来越好。加油