第四天 魔小灯(蓝牙智能灯)1

来源:互联网 发布:属于结构化数据的是 编辑:程序博客网 时间:2024/05/09 19:35

由于是公司项目,有些东西,我会保留,请您见谅。版权所有,违者必究。

非常抱歉,将近两个月没有写Android每一天了。主要是最近忙着毕业的事情和公司蓝牙灯项目的事情。今天我就共享一下劳动成果,希望对您有一点点帮助。

今天开始蓝牙智能灯项目的编写,一步步,从开始到结束。为了讲解详细,因此会分几节进行讲解。由于是单兵做战,就按照单兵做战的来。

 

一、简单需求

a) 经典蓝牙通信

具有打开开蓝,关闭蓝牙及搜索蓝牙设备基本功能,可选着蓝牙设备进行自动配对连接,保存已连接蓝牙设备,下次进入自动连接。连接成功后可进行数据交互和蓝牙状态改变监听;

b) 开关

基本的开灯关灯功能;

c) 调光

调节当前亮度;

d) 调色

具有调色圆环,通过在圆环上滑动取出相应位置颜色值,编码后发出使灯改变为相应颜色;

e) 延时关灯

用户可以滑动时间条,选择等待时间,到时间后会自动关灯,无需用户再次操作;

f) 音乐律动

随音乐有规律改变颜色值及亮度;

g) 摇一摇

摇一摇开灯关灯,及随机变色;

h) 七彩灯

小游戏功能的随机颜色改变;

i) 闹钟任务

用户可添加闹钟事件,定时开灯播放音乐叫醒用户,也可定时关灯。

j) 其他情景模式

阅读模式,浪漫模式等,且用户可添加自己的模式;

k) 菜单功能

设置密码,更改灯名,退出程序,关于我们及系统设置。


二、需求分析

a) 功能a是贯穿整个项目的通信基础,无界面,重点是通信逻辑;

b) 功能b/c/d/e可以放到一个页面里,为用户最常用的最基本的功能;

c) 功能f/g/h/j为特效功能,可以单独放到一个页面里面;

d) 闹钟任务单独一页;

e) 菜单功能为框架功能;


三、UI框架

常见UI框架,类似微信,类似扣扣,类似百度,类似QQ音乐,等等;

从需求分析,页数比较少且无需多层次交互,故选着类似微信的滑屏,简化;

实现方式:ViewPager+Fragment


四、开发环境

Windows 10 + JDK1.8 + Android Studio 1.4(没线买Mac)


五、项目结构


其中:

activity里放置用到的Activity

adapter里为适配器

ai为接口

bean是模型

Fragment里放置相应的显示内容

Library放置用到的其它的开源库等等(放在这里,是为了可以修改源码,定制开发)

Net里放置的为线程池操作等通信功能

Service是服务

Util为实用工具类和常量

View里为自定义控件

这是最简单最弱智的代码结构组织了,请原谅我的弱智。哈哈


六、项目框架源码

基于以上内容分析,搭建项目框架(步骤如下:)

新建一个项目选择:Tabbed Activity

 

项目自动生成后,添加AppContext.java类,源码如下:主要是为了管理全局内容,并防止系统崩溃;

AppContext.java

/**
 * @author Leo
 * @detail 程序入口点 处理程序异常和全局内容
 @time 2015-10-29
 */
public class AppContext extends Application {
    /**
     * 以下为单例模式
     */
    private volatile static AppContext mAppContext null;

    public static AppContext getInstance() {
        if (mAppContext == null) {
            synchronized (AppContext.class) {
                if (mAppContext == null) {
                    mAppContext new AppContext();
                }
            }
        }
        return mAppContext;
    }

    /**
     * 以下为uncaught exception的处理代码 防止程序崩溃
     */
    private Thread.UncaughtExceptionHandler mDefaultHandler = Thread.getDefaultUncaughtExceptionHandler();
    private Thread.UncaughtExceptionHandler mUncaughtExceptionHandler new Thread.UncaughtExceptionHandler() {
        @Override
        public void uncaughtException(Thread threadThrowable ex) {
            if (!handleException(ex) && mDefaultHandler != null) {
                mDefaultHandler.uncaughtException(threadex);
            else {
                restartApplication();
            }
            System.exit(0);
            android.os.Process.killProcess(android.os.Process.myPid());
        }
    };

    /**
     * 处理异常
     *
     * @param ex
     @return
     */
    private boolean handleException(Throwable ex) {
        if (ex == null) {
            return false;
        }
        new Thread(
                new Runnable() {
                    @Override
                    public void run() {
                        Looper.prepare();
                        Toast.makeText(getApplicationContext()R.string.error_infoToast.LENGTH_SHORT).show();
                        Looper.loop();
                    }
                }
        ).start();
        return true;
    }

    /**
     * 重启程序
     */
    private void restartApplication() {
        Intent intent = getPackageManager().getLaunchIntentForPackage(getPackageName());
        intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
        startActivity(intent);
    }
}

添加SplashActivity.java用于判断蓝牙是否支持,公司宣传等等,加入了点击跳过功能;

/**
 * @author Leo
 * @detail 程序进入时的首页面主要做公司宣传程序版本数据加载操作
 @time 2015-10-30
 */
public class SplashActivity extends AppCompatActivity {
    public static final long DELAY 1500;//等待时延
    private Handler mHandler new Handler();//控制Handler

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_splash);
        BluetoothSPP bt = BluetoothSPP.getInstance();
        if (!bt.isBluetoothAvailable()) {
            Toast.makeText(this, R.string.default_textToast.LENGTH_LONG).show();
            finish();
        else {
            mHandler.postDelayed(mRunnableDELAY);//DELAY后发出线程
            if (!bt.isBluetoothEnabled()) {
                bt.enable();
            }
        }
    }

    /**
     * 要执行的线程
     */
    private Runnable mRunnable new Runnable() {
        @Override
        public void run() {
            startTheActivity();
        }
    };

    /**
     * 启动主Activity
     */

    private void startTheActivity() {
        Intent intent = new Intent(this, MainActivity.class);
        startActivity(intent);
        finish();
    }

    /**
     * 扑捉触屏事件 用户可以点击屏幕快速进入
     *
     * @param event
     @return
     */
    @Override
    public boolean onTouchEvent(MotionEvent event) {
        //return super.onTouchEvent(event);
        int action = event.getAction();
        if (action == MotionEvent.ACTION_UP) {
            mHandler.removeCallbacks(mRunnable);
            startTheActivity();
        }
        return true;
    }
}

注意:这里使用的蓝牙通信是开源的BluetoothSPP项目(https://github.com/akexorcist/Android-BluetoothSPPLibrary/

然后是MainActivity.java

我对生成的代码进行了修改:把Adapter单独放到adapter里,Fragment单独放到fragment

/**
 * @author Leo
 * @detail 项目框架主界面 具有滑动切换功能 各类功能在各自Fragment
 @time 2015-10-29
 */
public class MainActivity extends AppCompatActivity {
    private SectionsStatePagerAdapter mSectionsStatePagerAdapter;//页面适配器
    //private SectionsPagerAdapter mSectionsPagerAdapter;//页面适配器
    private ViewPager mViewPager;//滑动控件
    private Toolbar mToolbar;//页面名称显示

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
         init();//初始化数据和控件
    }

    /**
     * 初始化操作
     */
    private void init() {
        //设置ToolBar
        mToolbar = (Toolbar) findViewById(R.id.toolbar);
        mToolbar.setSubtitle(getString(R.string.subtitle_disconnected));
        setSupportActionBar(mToolbar);
        //获取页面适配器
        mSectionsStatePagerAdapter new SectionsStatePagerAdapter(getSupportFragmentManager());
        mSectionsStatePagerAdapter.addPage(MainFragment.getInstance());
        mSectionsStatePagerAdapter.addPage(SceneFragment.getInstance());
        //mSectionsPagerAdapter.addPage(TimerFragment.getInstance());
        mSectionsStatePagerAdapter.addPage(StatusFragment.getInstance());
        //设置ViewPager
        mViewPager = (ViewPager) findViewById(R.id.container);
        mViewPager.setAdapter(mSectionsStatePagerAdapter);
    }
    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.menu_mainmenu);
        return true;
    }
    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        return true;
        //return super.onOptionsItemSelected(item);
    }

}

SectionsPagerAdapter.java

public class SectionsPagerAdapter extends FragmentPagerAdapter {
    private ArrayList<Fragment> pages;//保存页面

    public SectionsPagerAdapter(FragmentManager fm) {
        super(fm);
        pages new ArrayList<>();//生成
    }

    @Override
    public Fragment getItem(int position) {
        return pages.get(position);
    }

    @Override
    public int getCount() {
        return pages.size();
    }

    /**
     * 此接口是为了添加页面
     *
     * @param page
     */
    public void addPage(Fragment page) {
        this.pages.add(page);
    }
}

各个Fragment的代码我就不发出来了,后续继续更新

欧了,框架搭建完成,效果如下:

 

时间差不多了,明天继续。明天任务蓝牙通信,后台运行,菜单(显示图标)。

总结:完成一个项目,首先是需求,需求确定后就是UI框架了,然后就是对要做的项目进行知识点预演,查找解决方案,因为有些代码,别人已经帮我们写好了,我们没有必要再去做重复的工作,再说咱们自己做的也不一定就比别人做的好,既然是开源,可以直接拿来用,如果有问题,我们可以对其时行更正。come on.本项目中,应用了开源的BluetoothSpp进行蓝牙通信。


3 0