要把看不见的星星写在纸上~

全国职业院校技能大赛2019智能家居安装与维护项目整理文件

Loading...

📝简介

  • <由于我在武汉,所以暂时去不了学校,学校机房电脑里还有不少我的项目,所以等开学之后我再更新吧>
  • 我是参加了2019全国职校技能大赛智能家居项目的其中一名选手,最终获得了国赛三等奖的成绩。
  • 这个repo是我整理的所有我用到的文件,包括题库,说明文档,企想提供的Demo项目文件,我自己写的项目以及我参考过的项目,还有2017届的题目,题库以及Demo。
  • 2019年抽取的是E卷作为最终试题。
  • 由于现在高三,准备参加技能高考了,所以可能这个repo整理的有点仓促,但是该写的我都写了,应该还是能看的。

✏️部分重要代码

千万不要太过于在意代码规范,毕竟就三个小时,时间会不够用的!(除非你觉得还有多的时间)

比赛中,部分重要代码记得写注释,听说可以加分。
  • IP连接并登陆

    在Eclipse中导入企想提供的jar包,或直接将jar文件拖到项目的libs目录中,包名为com.bizideal.smarthome
    包结构:

    |-- BuildConfig.class
    |-- socket

    |-- Utils
        |--SpUtils.class
    |-- ConstantUtil.class
    |-- ControlUtils.class
    |-- DataCallback.class
    |-- DeviceBean.class
    |-- LoginCallback.class
    |-- SocketClient.class
    

    SpUtils是一个sharedPreferences的操作类,可以直接用于存储数据,但是不要当作数据库使用!可以用于存储账号密码,使用方法:
    存数据:
    SpUtils.putValue(context, key, value);

    • 第一个参数为上下文Context,比如MainActivity.this;
    • 第二个参数为键值String,比如"account";
    • 第三个参数为键值对应的值String,比如"bizideal";

    取数据:
    SpUtils.getValue(context, key, defValue);

    • 第一个参数为上下文Context,比如MainActivity.this;
    • 第二个参数为需要取的键值String,比如"account";
    • 第三个参数为默认值String,比如"0";
    • 最后会返回一个String值;

    ControlUtils是一个控制类,用于控制智能家居并获取数据,使用前先设置用户名密码:ControlUtils.setUser("用户名", "密码", "IP地址");三个参数均为String;

    SocketClient是一个创连接用的类,先使用SocketClient.getInstance().creatConnect();获取实例化对象并创建连接,然后使用SocketClient.getInstance().login(new LoginCallback());来获取返回数据,在LoginCallback内重写onEvent方法,必须创建一个runOnUiTread,因为连接是需要一定时间的,需要使用其他线程来获取结果,返回值为String类型,使用.equals();来判断是否连接成功;

    DeviceBean是一个组件类,作用是将功能、值和其他任何可以用代码创造的对象进行打包,方便调用。

    ConstantUtil是一个不知道啥类,存了所有智能家居英文对应的id。

    DataCallback是一个用来返回所有传感器数据的类。

    LoginCallback是一个用来返回登陆成功与否的类。

    登陆连接部分示例代码:

    //将值放入SpUtil中
    SpUtils.putValue( this, "Account", mAccountEt.getText().toString() );
    SpUtils.putValue( this, "Password", mPasswordEt.getText().toString() );
    SpUtils.putValue( this, "Ip", mIpEt.getText().toString() );
    //设置账号密码
    ControlUtils.setUser( mAccountEt.getText().toString(), mPasswordEt.getText().toString(), mIpEt.getText().toString() );
    //进行socket连接
    SocketClient.getInstance().creatConnect();
    //连接回调
    SocketClient.getInstance().login( new LoginCallback() {
        @Override
        public void onEvent(final String status) {
            runOnUiThread( new Runnable() {
                @Override
                public void run() {
                      if (status.equals( ConstantUtil.SUCCESS )) {
                          startActivity( new Intent( MainActivity.this, MainActivity.class));
                    finish();
                    }else {
                        Toast.makeText( MainActivity.this, "失败!", Toast.LENGTH_SHORT ).show();
                    }
                  }
            });
          }
        });

    备注:在反编译后的库文件中,发现了好几个demo中没有使用到的方法,我感觉其中有一个可能会用到的就是SocketClient.disConnect();这个方法,看方法名和代码,作用应该是断开连接.

  • 滑动验证

部分题目中要求滑动验证,可以直接使用SeekBar,通过设置android:progressDrawable属性来设置背景资源,通过android:thumb属性来设置拖动滑块的资源;甚至还有一套题需要滑动拼图验证,也可以使用这种方法,通过android:padding来设置内边距,就可以让滑块到指定的位置,例子:

<SeekBar
    android:id="@+id/sb_load"
      android:layout_width="match_parent"
      android:layout_height="wrap_content" 
      android:minHeight="40dp"
      android:minWidth="40dp"
      android:paddingTop="15dp"
      android:layout_marginLeft="5dp"
      android:layout_marginRight="5dp"
      android:progressDrawable="@drawable/custom_progress"
      android:thumb="@drawable/a"/>
  • 进度条加载

    进度条加载是个假的,只需要达到加载动画的效果就可以了,要新开一个线程用来计数,在主线程中计数会导致UI界面卡死:

    new Thread(new Runnable() {
        @Override
        public void run() {
        //使用for循环计数
        for (int i = 0; i < 101; i++) {
            //使用Message向主线程传递计数
            Message msg=new Message();
            msg.what=i;
            mHandler.sendMessage(msg);
            mainBar.setProgress(i);
            //线程操作部分记得用trycatch括起来
            try {
                //线程休眠10ms,随后继续计数
                Thread.sleep(10);
                } catch (InterruptedException e) {
                e.printStackTrace();
                }
            }
        }
    }).start();

    然后在主线程内使用Handler接收数据:

    Handler mHandler=new Handler(){
        public void handleMessage(Message msg){
            super.handleMessage(msg);
            //通过其他线程传进来的Message对象,获取其中的msg的值,随后设置UI文本
            loadnum.setText(msg.what+"%");
            //当msg传进来的值到达100时,新建弹窗并设置弹窗按钮监听,跳转到下一个界面。
            switch (msg.what) {
                case 100:
                    AlertDialog.Builder dialog=new AlertDialog.Builder(LoadActivity.this);
                    dialog.setTitle("加载完毕");
                    dialog.setNegativeButton("OK", new OnClickListener() {
                        @Override
                        public void onClick(DialogInterface dialog, int which) {
                            dialog.dismiss();
                            startActivity(new Intent(LoadActivity.this,MainActivity.class));
                            finish();
                        }
                    });
                    dialog.show();
                    break;
                default:
                    break;
            }
        }
    };
  • 数据库的使用

    在安卓里,系统自带sqlite数据库,在某些题目里需要使用到数据库,首先你得写一个SqlHelper继承SQLiteOpenHelper类,在这个类里面咱们得实现三种方法:构造函数,onCreate,onUpgrade:

    构造函数:

    //构造函数,必须得有,dbName为你需要创建的数据库名
    public DatabaseHelper(Context context, String dbName, CursorFactory factory, int version) {
        super(context, name, factory, version);
    }

    onCreate:

    //可以理解为初始化数据库,使用sql语句创建数据库
    public void onCreate(SQLiteDatabase db) {
        db.execSQL("sql语句");
    }

    onUpgrade:

    //实现数据库升级方法,可以暂时不用管
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
        
    }

    来一段示例代码:MyDatabaseHelper.java

    package com.example.sqlitedb;
    
    import android.content.Context;
    import android.database.sqlite.SQLiteDatabase;
    import android.database.sqlite.SQLiteDatabase.CursorFactory;
    import android.database.sqlite.SQLiteOpenHelper;
    
    public class MyDatabaseHelper extends SQLiteOpenHelper{
        //创建表UserData_1的sql语句
        public static final String CREATE_ST_STRING = "CREATE TABLE UserData_1" +
             "(" +
             "_id INTEGER PRIMARY KEY AUTOINCREMENT," +       //序号,键值,int类型,自增
             "userName TEXT," +                  //用户名,text类型
             "passWord TEXT," +                       //密码,text类型
             "tempData TEXT," +                  //温度传感器数据,text类型
             "curtainStatus INT" +               //窗帘状态,int类型
             ")";
    
        //构造方法,可在其他类中调用
        public MyDatabaseHelper(Context context, String name,CursorFactory factory, int version) {
            super(context, name, factory, version);
        }
    
        @Override
        public void onCreate(SQLiteDatabase db) {
             //执行sql语句
            db.execSQL(CREATE_ST_STRING);
        }
    
        @Override
        public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
            
        }
    
    }

    然后在主类中使用这个MyDatabaseHelper类:

    //新建一个MyDatabaseHelper对象,main_data是数据库名,factory使用默认factory构造,所以可为null,version随便写一个就行
    MyDatabaseHelper dbHelper = new MyDatabaseHelper(this, "main_data", null, 1);
    //获取可读写数据库
    SQLiteDatabase dbMain = dbHelper.getWritableDatabase();

    可能需要自己实现数据库的增删改查功能,我自己写了一个SqliteDatabaseUtil工具类,可以作为参考:

    import android.content.ContentValues;
    import android.database.Cursor;
    import android.database.sqlite.SQLiteDatabase;
    import android.os.Message;
    import android.util.Log;
    import android.widget.SimpleCursorAdapter;
    
    import com.icezx.subbook.MainActivity;
    
    import java.util.ArrayList;
    import java.util.HashMap;
    import java.util.List;
    import java.util.Map;
    import java.util.concurrent.LinkedBlockingQueue;
    import java.util.concurrent.ThreadPoolExecutor;
    import java.util.concurrent.TimeUnit;
    
    /**
     * @author Yili(yili)
     * @description
     * @package com.icezx.subbook
     * @date 2020-02-12
     */
    public class SqliteDatabaseUtil {
    
        private static final String TAG = "SqliteDatabaseUtil";
    
        /**
         * Sqlite数据库增加记录
         *
         * @param db        数据库对象
         * @param tableName 数据表名字
         * @param keys      要插入的数据的列的名字
         * @param values    与列对应的值
         */
        public static void insertData(SQLiteDatabase db, String tableName, String[] keys, String[] values) {
          ContentValues mContentValues = new ContentValues();
          for (int i = 0; i < keys.length; i++) {
                mContentValues.put(keys[i], values[i].trim());
          }
          db.insert(tableName, null, mContentValues);
          mContentValues.clear();
          Log.i(TAG, "执行了增加记录操作");
        }
    
        /**
         * Sqlite数据库删除记录,根据_id删除
         *
         * @param adapter   SimpleCursorAdapter适配器对象适配器对象
         * @param db        数据库对象
         * @param tableName 数据表名字
         * @param positon   在列表中对应的位置
         */
        public static void deleteData(SimpleCursorAdapter adapter, SQLiteDatabase db, String tableName, int positon) {
            Cursor mCursor = adapter.getCursor();
            mCursor.moveToPosition(positon);
            int itemId = mCursor.getInt(mCursor.getColumnIndex("_id"));
            db.delete(tableName, "_id=?", new String[]{itemId + ""});
            mCursor.close();
            Log.i(TAG, "执行了删除记录操作");
        }
    
        /**
         * Sqlite数据库修改记录
         *
         * @param adapter   SimpleCursorAdapter适配器对象
         * @param db        数据库对象
         * @param tableName 数据表名字
         * @param positon   在列表中对应的位置
         * @param keys      要插入的数据的列的名字
         * @param values    与列对应的值
         */
        public static void updateData(SimpleCursorAdapter adapter, SQLiteDatabase db, String tableName, int positon, String[] keys, String[] values) {
            Cursor mCursor = adapter.getCursor();
            mCursor.moveToPosition(positon);
            int itemId = mCursor.getInt(mCursor.getColumnIndex("_id"));
            ContentValues mContentValues = new ContentValues();
            for (int i = 0; i < keys.length; i++) {
                mContentValues.put(keys[i], values[i].trim());
            }
            db.update(tableName, mContentValues, "_id=?", new String[]{itemId + ""});
            mContentValues.clear();
            mCursor.close();
            Log.i(TAG, "执行了修改记录操作");
        }
    
        /**
         * Sqlite数据库查询记录,返回一个List对象
         *
         * @param db          数据库对象
         * @param tableName   数据表名字
         * @param whichColumn 想要查询的列,这是一个String[]
         * @param keyWord     想要查询的关键词
         * @param whichSelect 想要查询的这个关键词对应的列名字
         */
        public static List<Map<String, String>> queryData1(SQLiteDatabase db, String tableName, String[] whichColumn, String keyWord, String whichSelect) {
            List<Map<String, String>> mStringList = new ArrayList<>();
            //第二个参数是你需要查找的列
            //第三和第四个参数确定是从哪些行去查找第二个参数的列
            Cursor mCursor1 = db.query(tableName, whichColumn, whichSelect + "=?", new String[]{keyWord}, null, null, null);
            Log.d(TAG, "得到了" + mCursor1.getCount() + "条结果");
            if (mCursor1.getCount() > 0) {
                mStringList.clear();
                //游标总是在查询到的上一行
                while (mCursor1.moveToNext()) {
                    Map<String, String> mMap = new HashMap<>();
                    for (int i = 0; i < whichColumn.length; i++) {
                        mMap.put(whichColumn[i], mCursor1.getString(mCursor1.getColumnIndex(whichColumn[i])));
                    }
                    mStringList.add(mMap);
                }
                mCursor1.close();
            } else {
                mStringList.clear();
                Map<String, String> mMap = new HashMap<>();
                mMap.put(whichSelect, "无结果");
                mStringList.add(mMap);
            }
            Log.d(TAG, "查询结果" + mStringList.toString());
            return mStringList;
        }
    }
    

    数据库这部分可能会有些复杂,慢慢来吧。

  • 获取登陆或数据回调

    这一部分我遇到过坑,所以一定要写!!!

    在整个App中,获取回调的时候,这些代码一定只能出现一次:

    这是获取登陆状态回调:

    SocketClient.getInstance().login( new LoginCallback() {
        @Override
          public void onEvent(final String status) {
              runOnUiThread( new Runnable() {
                      @Override
                            public void run() {
                              if (status.equals( ConstantUtil.SUCCESS  )) {
                                        Toast.makeText( MainActivity.this, "重连成功!", Toast.LENGTH_SHORT ).show();
                                }else if (status.equals( ConstantUtil.FAILURE  )) {
                                        Toast.makeText( MainActivity.this, "重连失败!", Toast.LENGTH_SHORT ).show();
                                }else {
                                        Toast.makeText( MainActivity.this, "重连中!", Toast.LENGTH_SHORT ).show();
                                }
                            }
            });

    这是获取传感器数据回调:

    ControlUtils.getData();
    SocketClient.getInstance().getData(new DataCallback<DeviceBean>() {
        @Override
        public void onResult(final DeviceBean bean) {
            // TODO Auto-generated method stub
            runOnUiThread(new Runnable() {            
                @Override
                public void run() {
                    // TODO Auto-generated method stub
                    if (!TextUtils.isEmpty(bean.getTemperature())) {
                        wendu.setText(bean.getTemperature());
                    }
                    if (!TextUtils.isEmpty(bean.getHumidity())) {
                        shidu.setText(bean.getHumidity());
                    }
                    if (!TextUtils.isEmpty(bean.getGas())) {
                        ranqi.setText(bean.getGas());
                    }
                    if (!TextUtils.isEmpty(bean.getIllumination())) {
                        guangzhao.setText(bean.getIllumination());
                    }
                    if (!TextUtils.isEmpty(bean.getPM25())) {
                        pm25.setText(bean.getPM25());
                    }
                    if (!TextUtils.isEmpty(bean.getAirPressure())) {
                        qiya.setText(bean.getAirPressure());
                    }
                    if (!TextUtils.isEmpty(bean.getSmoke())) {
                        yanwu.setText(bean.getSmoke());
                    }
                    if (!TextUtils.isEmpty(bean.getCo2())) {
                        co2.setText(bean.getCo2());
                    }
                    if (!TextUtils.isEmpty( bean.getStateHumanInfrared() ) && bean.getStateHumanInfrared().equals( ConstantUtil.CLOSE )){
                        renti.setText( "无人" );
                        }else {
                              renti.setText( "有人" );
                        }
                    if (!TextUtils.isEmpty( bean.getLamp() ) && bean.getLamp().equals( ConstantUtil.CLOSE )) {
                              shedeng.setChecked( false );
                              shedeng.setBackgroundResource(R.drawable.shedeng);
                        }else {
                              shedeng.setChecked( true );
                              shedeng.setBackgroundResource(R.drawable.shedeng_press);
                        }
                        if (!TextUtils.isEmpty( bean.getFan() ) && bean.getFan().equals( ConstantUtil.CLOSE )) {
                              fengshan.setChecked( false );
                              fengshan.setBackgroundResource(R.drawable.fengshan);
                        }else {
                              fengshan.setChecked( true );
                              fengshan.setBackgroundResource(R.drawable.fengshan_press);
                        }
                        if (!TextUtils.isEmpty( bean.getCurtain() ) && bean.getCurtain().equals( ConstantUtil.CHANNEL_3 )) {
                              Toast.makeText(MainActivity.this, "窗帘开", Toast.LENGTH_SHORT).show();
                        }else if (!TextUtils.isEmpty( bean.getCurtain() ) && bean.getCurtain().equals( ConstantUtil.CHANNEL_1 )) {
                              Toast.makeText(MainActivity.this, "窗帘停", Toast.LENGTH_SHORT).show();
                        }else if (!TextUtils.isEmpty( bean.getCurtain() ) && bean.getCurtain().equals( ConstantUtil.CHANNEL_2 )) {
                              Toast.makeText(MainActivity.this, "窗帘关", Toast.LENGTH_SHORT).show();
                        }
                        if (!TextUtils.isEmpty( bean.getWarningLight() ) && bean.getWarningLight().equals( ConstantUtil.CLOSE )) {
                              baojing.setChecked( false );
                              baojing.setBackgroundResource(R.drawable.baojing);
                        }else {
                              baojing.setChecked( true );
                              baojing.setBackgroundResource(R.drawable.baojing_press);
                        }
                }
            });
        }
    });

    这些代码在整个App中一定只能出现一次,不同界面间的数据传输请使用全局变量的方法(java的全部变量可以自行百度),比如我在“MainActivity”中使用了这些代码获取回调数据,我想在“SecondActivity”中也想使用“MainActivity”中获取到的数据,那就在“MainActivity”中传值给全局变量的类。千万不能重复使用上面的代码,那样会导致每刷新一次数据,界面就会重载一次!

  • 绘图界面

    具体项目请参考:

    需要自定义View,然后使用Canvas绘图,可供参考的代码:

    import android.content.Context;
    import android.graphics.Canvas;
    import android.graphics.Color;
    import android.graphics.Paint;
    import android.util.AttributeSet;
    import android.view.View;
    
    public class MyView extends View {
    
        public MyView(Context context, AttributeSet attrs) {
            super(context, attrs);
            // TODO Auto-generated constructor stub
        }
        
        // 默认边距
        private int Margin = 40;
        // 原点坐标
        private int Xpoint;
        private int Ypoint;
        // X,Y轴的单位长度
        private int Xscale = 20;
        private int Yscale = 20;
        // X,Y轴上面的显示文字
        private String[] Xlabel = { "0", "1", "2", "3", "4", "5", "6", "7", "8" };
        private String[] Ylabel = { "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "10" };
        // 标题文本
        private String Title;
        // 曲线数据
        private int[] Data = { 1,2,3,4,5,6,7,8,9 };
    
        public MyView(Context context, String[] xlabel, String[] ylabel,
                String title, int[] data) {
            super(context);
            this.Xlabel = xlabel;
            this.Ylabel = ylabel;
            this.Title = title;
            this.Data = data;
        }
    
        public MyView(Context context) {
            super(context);
        }
    
        // 初始化数据值
        public void init() {
            Xpoint = this.Margin;
            Ypoint = this.getHeight() - this.Margin;
            Xscale = (this.getWidth() - 2 * this.Margin) / (this.Xlabel.length - 1);
            Yscale = (this.getHeight() - 2 * this.Margin)
                    / (this.Ylabel.length - 1);
        }
    
        public int getMargin() {
            return Margin;
        }
    
        public void setMargin(int margin) {
            Margin = margin;
        }
    
        @Override
        protected void onDraw(Canvas canvas) {
            canvas.drawColor(Color.WHITE);
            Paint p1 = new Paint();
            p1.setStyle(Paint.Style.STROKE);
            p1.setAntiAlias(true);
            p1.setColor(Color.BLACK);
            p1.setStrokeWidth(2);
            init();
            this.drawXLine(canvas, p1);
            this.drawYLine(canvas, p1);
            // this.drawTable(canvas);
            this.drawData(canvas);
        }
    
        // // 画表格
        // private void drawTable(Canvas canvas) {
        // Paint paint = new Paint();
        // paint.setStyle(Paint.Style.STROKE);
        // paint.setColor(Color.GRAY);
        // Path path = new Path();
        // PathEffect effects = new DashPathEffect(new float[] { 5, 5, 5, 5 }, 1);
        // paint.setPathEffect(effects);
        // // 纵向线
        // for (int i = 1; i * Xscale <= (this.getWidth() - this.Margin); i++) {
        // int startX = Xpoint + i * Xscale;
        // int startY = Ypoint;
        // int stopY = Ypoint - (this.Ylabel.length - 1) * Yscale;
        // path.moveTo(startX, startY);
        // path.lineTo(startX, stopY);
        // canvas.drawPath(path, paint);
        // }
        // // 横向线
        // for (int i = 1; (Ypoint - i * Yscale) >= this.Margin; i++) {
        // int startX = Xpoint;
        // int startY = Ypoint - i * Yscale;
        // int stopX = Xpoint + (this.Xlabel.length - 1) * Xscale;
        // path.moveTo(startX, startY);
        // path.lineTo(stopX, startY);
        // paint.setColor(Color.DKGRAY);
        // canvas.drawPath(path, paint);
        // paint.setColor(Color.WHITE);
        // paint.setTextSize(this.Margin / 2);
        // canvas.drawText(this.Ylabel[i], this.Margin / 4, startY
        // + this.Margin / 4, paint);
        // }
        // }
    
        // 画横纵轴
        private void drawXLine(Canvas canvas, Paint p) {
            canvas.drawLine(Xpoint, Ypoint, this.Margin, this.Margin, p);
            //canvas.drawLine(Xpoint, this.Margin, Xpoint - Xpoint / 3, this.Margin+ this.Margin / 3, p);
            //canvas.drawLine(Xpoint, this.Margin, Xpoint + Xpoint / 3, this.Margin+ this.Margin / 3, p);
        }
    
        private void drawYLine(Canvas canvas, Paint p) {
            canvas.drawLine(Xpoint, Ypoint, this.getWidth() - this.Margin, Ypoint,p);
            //canvas.drawLine(this.getWidth() - this.Margin, Ypoint, this.getWidth()- this.Margin - this.Margin / 3, Ypoint - this.Margin / 3, p);
            //canvas.drawLine(this.getWidth() - this.Margin, Ypoint, this.getWidth()- this.Margin - this.Margin / 3, Ypoint + this.Margin / 3, p);
        }
    
        // 画数据
        private void drawData(Canvas canvas) {
            Paint p = new Paint();
            p.setAntiAlias(true);
            p.setColor(Color.BLACK);
            p.setTextSize(this.Margin / 2);
            // 纵向线
            for (int i = 1; i * Xscale <= (this.getWidth() - this.Margin); i++) {
                int startX = Xpoint + i * Xscale;
                canvas.drawText(this.Xlabel[i], startX - this.Margin / 4,
                        this.getHeight() - this.Margin / 4, p);
                canvas.drawCircle(startX, calY(Data[i]), 4, p);
                canvas.drawLine(Xpoint + (i - 1) * Xscale, calY(Data[i - 1]),
                        startX, calY(Data[i]), p);
            }
        }
    
        /**
         * 
         * @param y
         * @return
         */
        private int calY(int y) {
            int y0 = 0;
            int y1 = 0;
            // Log.i("zzzz", "y:"+y);
            try {
                y0 = Integer.parseInt(Ylabel[0]);
                // Log.i("zzzz", "y0"+y0);
                y1 = Integer.parseInt(Ylabel[1]);
                // Log.i("zzzz","y1"+y1);
            } catch (Exception e) {
                // Log.i("zzzz", "string changed is err");
                return 0;
            }
            try {
                // Log.i("zzzz", "返回数据"+(Ypoint-(y-y0)*Yscale/(y1-y0)) );
                return Ypoint - ((y - y0) * Yscale / (y1 - y0));
            } catch (Exception e) {
                // Log.i("zzzz", "return is err");
                return 0;
            }
        }
    
    }

    然后在layout文件中使用这些代码来使用这个自定义View:

    <com.example.testview.MyView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content">
    </com.example.testview.MyView>

    这只是参考代码,实际在项目中使用的话,需要使用到大量变量,数组,然后在主线程中设置定时,隔一段时间刷新一次,数组中填充新数据,替换掉旧数据。

    绘图这部分可能需要很多时间,所以尽力完成吧,要是时间实在不够就别做了。(毕竟我就没时间做了.....)

📖相关说明

  • 在eclipse的设置中,记得打开auto-import,详细:百度经验-Eclipse自动导包
  • 也请记住Eclipse的部分常用快捷键:菜鸟教程-Eclipse快捷键
  • 在这两个目录下:【2017年智能家居安卓Demo2019年智能家居安卓Demo】是企想提供的安卓Demo文件,提供最基础的智能家居控制功能,可直接导入eclipse。
  • 在这两个目录下:【2017年题库2019年题库】是题库文件,在正式比赛时会由比赛组委会从中随机抽取一套,作为比赛试题,2017年我不知道抽取了哪一套,2019年抽取的是E卷作为最终试题,我感觉不算特别难,就是时间不咋够。。。
  • 在这个目录下:2019年自己写的项目文件是我自己写的项目(有几个项目没找着,等开学了去学校电脑上再找找),要是嫌弃我的代码很辣鸡也能理解哈哈哈,项目名字对应的就是那一套题,基本完全按照试题要求的来,可直接导入eclipse。
  • 在这个目录下:2019年我参考过的项目文件是我参考过的项目文件,解释一下每个项目大概是什么内容吧,可直接导入eclipse。

    • Login_Sqlite是sqlite数据库的相关使用,主要被我用于实现账号登录,数据记录的相关功能。
    • A-J套试题参考Demo在这个目录下的DemoA-DemoJ项目是当时我们的参考项目Demo,实现了绝大部分试题要求的功能(听说是找人做的),我当时主要参考了Fragment的使用,生命周期管理,Canvas的绘制等等,这些项目都完整的实现了试题要求的效果,但最大的问题就是,这些项目并不能正常控制智能家居设备,也就是说,做这套题的人应该并没有实体的设备,仅从理论上做出了这些项目,但这些项目对我帮助也算是很大的了,感谢。
    • 绘制折线图顾名思义,这个项目是我用来实现折线图绘制的参考。
  • 其他文件这个是其他的一些文件,比如说明文档啥的,还有lib库文件。

📱联系方式

Email: miaococoo@gmail.com

QQ:2510355993

🔔最后

好了,也再没有什么好说的了,希望这个repo可以被用上吧,最后祝以后参加这个比赛的同学可以取得一个理想的成绩咯,干巴爹!

全国职业院校技能大赛2019智能家居安装与维护项目整理文件

https://blog.mapotofu.cn/archives/megagame2019_smarthome_organized.html

作者

麻婆豆腐

发布时间

2020-03-04

添加新评论