文档章节

从头开始敲代码之《从BaseApplication/Activity开始(二)》

王亟亟
 王亟亟
发布于 2015/09/16 13:31
字数 2029
阅读 22
收藏 0

【推荐】2019 Java 开发者跳槽指南.pdf(吐血整理) >>>

转载请注明出处:王亟亟的大牛之路

愿意花时间写东西不容易,人啊,都是有血有肉有思想的,借鉴是学习,纯Copy就不好了,谢谢
部分资料参考于网上。

《赠梁任父同年》黄遵宪
 

寸寸河山寸寸金,侉离分裂力谁任?
杜鹃再拜忧天泪,精卫无穷填海心。

上一篇我们讲到了简易的封装 对我们提高效率的好处,这一篇继续写下去,如果第一篇没看过的希望能看下,方便理解。链接亟亟在安卓的进阶实例

这一次我们利用最基本的Activity生命周期中的方法,来对用户蓝牙进行识别操作,并在过程中考虑用户层面的操作理解,顺便补充下安卓手机的蓝牙知识。

什么是蓝牙?
一种无线技术标准,可实现固定设备、移动设备和楼宇个人域网之间的短距离数据交换(使用2.4—2.485GHz的ISM波段的UHF无线电波)。
白话:安卓对各个版本的蓝牙其实都有一定的支持,从1.5的Cupcake就支持了蓝牙耳机,但是自从安卓4.3版本之后Google对蓝牙4.0的支持,又进一步的提升,所以对4.3前后的适配又成了我们的工作(现在已经普遍以5.0为开发环境低版本的手机已经不多,工作量其实已经不大了)

OK,简单介绍完了,开始今天的代码

写一个工具类BluetoothMgr,把蓝牙一些相关的操作,放在里面

/** * Created by Ezreal on 2015/9/14. */public class BluetoothMgr {private static BluetoothMgr oneInstance = null;public static BluetoothAdapter mBluetoothAdapter = null;public boolean available = false;private static List<BluetoothDevice> devList = new ArrayList<BluetoothDevice>();private BluetoothMgr() { }@TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR2)private BluetoothMgr(Context context) {int sdkInt = Build.VERSION.SDK_INT;if (sdkInt <= Build.VERSION_CODES.JELLY_BEAN_MR1) {

            mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();

        } else {

            BluetoothManager manager = (BluetoothManager) context.getSystemService(Context.BLUETOOTH_SERVICE);
            mBluetoothAdapter = manager.getAdapter();

        }

        available = (null != mBluetoothAdapter);
    }//判断BluetoothMgr是否可用public boolean available() {return available;

    }//获得实例public static BluetoothMgr getInstance(Context context) {if (null == oneInstance) {

            oneInstance = new BluetoothMgr(context);

        }return oneInstance;

    }//搜索设备public static boolean startDiscovery(){if (null == mBluetoothAdapter) {return false;

        }if (!mBluetoothAdapter.isEnabled()) {

            mBluetoothAdapter.enable();while (!mBluetoothAdapter.isEnabled()) {try {

                    Thread.sleep(1000);

                } catch (InterruptedException e) {

                    e.printStackTrace();

                }
            }
        }if (mBluetoothAdapter.isDiscovering()) {return true;

        }return mBluetoothAdapter.startDiscovery();

    }//取消搜索public static boolean cancelDiscovery() {if (mBluetoothAdapter == null) {return false;

        }if (mBluetoothAdapter.isDiscovering()){return mBluetoothAdapter.cancelDiscovery();

        }return false;

    }//添加设备public static void addOne(BluetoothDevice device) {if (null == device) {return;

        }if (devList.contains(device)) {return;

        }

        devList.add(device);

    }//删除设备public static void deleteOne(String mac) {if (null == mac || mac.length()==0) {return;

        }for (int i = 0; i < devList.size(); ++i) {

            BluetoothDevice device = devList.get(i);if (device.getAddress().equalsIgnoreCase(mac)) {

                devList.remove(i);break;

            }

        }

    }//清空集合public static void clearAllDevices() {

        devList.clear();

    }public static BluetoothDevice findOne(int pos) {if (pos < 0 || pos >= devList.size()) {return null;

        }return devList.get(pos);

    }public static List<BluetoothDevice> getDevList() {return devList;

    }public static boolean isDevListEmpty() {return (null == devList || devList.isEmpty());

    }//获取状态public static int getState(){if(mBluetoothAdapter!=null){
            LogUtils.d("BluetoothMgr","mBluetoothAdapter.getState()"+mBluetoothAdapter.getState());return mBluetoothAdapter.getState();
        }else{return -1;
        }
    }
}

分析:对蓝牙的一些基本方法进行了封装,以及版本的判断,这边在例举下蓝牙相关的一些具体代码的内容
(这部分网上资料还算有,也可以找找)

在安卓要使用蓝牙,先要授权

    <uses-permission android:name="android.permission.BLUETOOTH" /><uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />

不然你项目一运行就是异常。

要使用蓝牙必须声明一个BluetoothAdapter

在4.3之前
mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();获取系统默认蓝牙。

4.3之后
BluetoothManager manager = (BluetoothManager) context.getSystemService(Context.BLUETOOTH_SERVICE);
mBluetoothAdapter = manager.getAdapter();

列举一些常用的方法

disable()关闭蓝牙

enable()打开蓝牙(用户将不会收到提示)

下面是另一种打开蓝牙的方式,但是会提醒用户手动去打开

Intent enabler=new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
startActivityForResult(enabler,reCode);//同startActivity(enabler);

cancelDiscovery() 取消搜索设备

startDiscovery() 开始搜索设备

getAddress()获取本地蓝牙地址

getName()获取本地蓝牙名称

getRemoteDevice(Stringaddress)根据蓝牙地址获取远程蓝牙设备

getState()获取本地蓝牙适配器当前状态

isDiscovering()判断当前是否正在查找设备,是返回true

isEnabled()判断蓝牙是否打开,已打开返回true,否则,返回false

再列举下蓝牙的状态值
BluetoothAdapter STATE 状态值

          int STATE_OFF        蓝牙已经关闭
          int STATE_ON        蓝牙已经打开
          int STATE_TURNING_OFF      蓝牙处于关闭过程中 ,关闭ing
          int STATE_TURNING_ON        蓝牙处于打开过程中 ,打开ing

BluetoothAdapter SCAN_MOD状态值=扫描状态

可以扫描其他设备的,当然它同时能被其他蓝牙设备扫码。

     int  SCAN_MODE_CONNECTABLE         表明该蓝牙可以扫描其他蓝牙设备
     int  SCAN_MODE_CONNECTABLE_DISCOVERABLE     可以扫描其他蓝牙设备,并且可以被其他蓝牙设备扫描到。
     int  SCAN_MODE_NONE : 该蓝牙不能扫描以及被扫描。

更多资料可参考BluetoothAdapter[蓝牙]

铺垫做的差不多了,我们开始今天的代码。

需求:我有一个Activity,我需要进入他的时候让用户开启手机蓝牙,然后对我们的另外一个蓝牙硬件进行操作,如果用户不愿意去开,那就停留在原有界面,如果用户去开蓝牙了并且成功了那么就进入下一步操作,如果没开成功,那么继续提示。

包结构:
这里写图片描述

代码的基类都是在我们之前的Demo中继续添加的,更有延续性。

直接贴 MainActivity

public class MainActivity extends BaseActivity implements View.OnClickListener{Button button;private MyPromptDlg btNotOpenDlg = null;
    BluetoothMgr bleMgr;@Overrideprotected void findById() {
        button=(Button)findViewById(R.id.button);

        bleMgr=BluetoothMgr.getInstance(this);


    }@Overrideprotected void setListener() {
        button.setOnClickListener(this);
    }@Overrideprotected void logic() {


    }@Overrideprotected int getLayout() {return R.layout.activity_main;
    }@Overridepublic void onClick(View v) {if (v.getId()==R.id.button){
            Toast.makeText(MainActivity.this,"NFC是否可用?? "+NFCisAvailable(),Toast.LENGTH_SHORT).show();
            openBlueToothSetting();
        }
    }@Overrideprotected void onResume() {super.onResume();
        LogUtils.d("------>onResume");if(bleMgr.isEnabled()){
            Toast.makeText(MainActivity.this,"蓝牙已经打开",Toast.LENGTH_SHORT).show();
        }else{
            OpenBlueTooth();
        }
    }//打开蓝牙private void OpenBlueTooth(){//判断Activity的状态if (this.isFinishing()) {return;

        }if (null == btNotOpenDlg) {

            MyPromptDlg.Builder builder = new MyPromptDlg.Builder(this);

            builder.setTitle(res.getString(R.string.prompt_dlg_title))
                    .setText(res.getString(R.string.bt_check_message))
                    .setPositiveButton(res.getString(R.string.common_ok),new DialogInterface.OnClickListener() {@Overridepublic void onClick(DialogInterface dialog,int which) {
                                    dialog.dismiss();
                                    openBlueToothSetting();
                                }

                            })
                    .setNegativeButton(res.getString(R.string.common_cancel),new DialogInterface.OnClickListener() {@Overridepublic void onClick(DialogInterface dialog,int which) {

                                    dialog.dismiss();//finish();}

                            });

            btNotOpenDlg = builder.create();
            btNotOpenDlg.setCancelable(false);
            btNotOpenDlg.setCanceledOnTouchOutside(false);
        }if (!btNotOpenDlg.isShowing()) {

            btNotOpenDlg.show();

        }

    }//打开系统蓝牙设置菜单private void openBlueToothSetting(){
        Intent intent = new Intent(Settings.ACTION_BLUETOOTH_SETTINGS);
        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        startActivity(intent);
    }
}

分析:
首先我们在我们的onCreate方法中初始化一个BluetoothMgr并且让其获得了系统蓝牙的实例(包中的BluetoothMgr是一个Demo版的,具体更多的通用方法封装在JAR包中了)

用户进入App 依次调用onCreate–onStart–onResume–Activity进入运行状态。
我们在onCreate时并没有对用户的蓝牙状态进行判断,而是在onResume方法中判断,这是为什么?看下图
这里写图片描述
因为onResume会多次调用,而onCreate在不被回收过或者onStop的情况下永远就调用一次,我们需要每一次用户焦点在我们App中的时候都去判断蓝牙的状态,那就是为什么我们要这么做的原因。

为了提高我们App的友好度,在判断用户没有开启蓝牙的时候,我们弹出一个Dialog提示用户要不要去开蓝牙,如图
这里写图片描述
如果用户点击取消我们会回到界面,但是不会调用onResume方法,不然我们的用户 就一直在那里选啊选了,不符合逻辑。
点击是,调用openBlueToothSetting()方法去手动开启,当然如果你觉得你需要强势一些可以用enable()方法,直接就开启了,但是要记得做短暂的等待,因为开启蓝牙会有一定的异步操作。
因为你代码调用开启蓝牙所以用户回到界面之后不会再判断时候开启蓝牙,也符合我们的业务需求。

当用户点击确定的时候我们开启了蓝牙设置菜单界面(系统的)
这里写图片描述

回来之后又调用了onResume,弹出了我们的吐司
这里写图片描述

OK我们的业务就完成了,还有别的实现方法么?有!!

可以用Service,开一个现成一直在那里判断也能达到效果 但是不是最理想的实现方式

还有是BroadcastReceiver 去监听手机蓝牙的变化,实现如下

BroadcastReceiver bluetoothState = new BroadcastReceiver() {public void onReceive(Context context, Intent intent) {
    String stateExtra = BluetoothAdapter.EXTRA_STATE;       int state = intent.getIntExtra(stateExtra, -1);       switch(state) {case BluetoothAdapter.STATE_TURNING_ON:break;case BluetoothAdapter.STATE_ON:break;case BluetoothAdapter.STATE_TURNING_OFF:break;case BluetoothAdapter.STATE_OFF:break;
    }
    }
}

registerReceiver(bluetoothState,new IntentFilter(BluetoothAdapter.ACTION_STATE_CHANGED));

记得注销哦!!

午休午休!!源码地址:http://yunpan.cn/cmCaaRkzc2UV6 访问密码 4894

版权声明:本文为博主原创文章,未经博主允许不得转载。

© 著作权归作者所有

王亟亟
粉丝 1
博文 4
码字总数 7977
作品 0
杨浦
程序员
私信 提问
利用Application对象存储登录用户信息

Application对象非常适合用于存储一些与整个应用相关数据,例如应用版本,应用登录账户,数据缓存等。 如activity的切换是很频繁的,差不多可以和一个网站中不同网页之间的切换一样,那么不同...

40岁的青春
2015/04/21
949
0
Android之Application使用总结

android使用Application 配置全局Context步骤: 1、写一个全局的单例模式的类BaseApplication继承自Application 并覆盖onCreate()方法,在这个方法里面实例化Application; 2、配置全局的C...

未来程序员
2018/06/29
0
0
从零开始搭建Android组件化框架

问题 在已经开发过几个项目的童鞋,如果这时需要重新开发一个新项目,是否需要自己重新搭建框架呢,还是从老项目中拷贝粘贴? 我们是否可以封装一个底层的lib库,这个底层的公共基础库 包括了一些...

tome869535144
2018/06/06
0
0
android接入原生第三方登录(微信登录、QQ登录、新浪微博登录)

第一步:去对应的平台上注册app的相关信息,这一步,可参考我的另外一个篇,关于接入亲加通信云的文章 各个平台注册应用信息的地址如下: 新浪微博 http://open.weibo.com 腾讯微博 http://d...

鹭明
2018/06/26
0
0
说说在 Android 如何在全局获取 Context

Android 提供了一个 Application 类,每当应用启动时,系统就会初始化该类。我们可以定制一个基础的 Application 类,以便管理应用内的一些全局信息。 定义 BaseApplication: 配置: Androi...

deniro
2018/11/03
0
0

没有更多内容

加载失败,请刷新页面

加载更多

dynamic-connectivity 动态连通性问题之 quick-union 算法

quick-union 的思想是:若对象 p 的 root_id 和对象 q 的 root_id 相等,则认为 p 和 q 连通。 若要将对象 p 和对象 q 连通(已知两对象未连通),则将 p 的 root_id 的值设为 q 的 root_id ...

Phpythoner_Alei
今天
40
0
OSChina 周六乱弹 —— 实在选不出来就唱国歌

Osc乱弹歌单(2020)请戳(这里) 【今日歌曲】 @花间小酌 :#今日歌曲推荐# 分享阿冗的单曲《你的答案》。--祝大家在2020年都找到自己答案。 《你的答案》- 阿冗 手机党少年们想听歌,请使劲...

小小编辑
今天
25
1
Maven打包可执行Jar包的方法

在使用Java开发中,会使用到将工程打包成可执行的jar包的情况,那么在maven中怎么将项目中的依赖包都添加到jar中呢。在pom.xml中添加一下插件: <build><plugins><plugin><ar...

CapJes
今天
13
0
使用vue 开发地图类系统(openlayers.js)的注意。

使用vue 开发地图类系统的注意。 1、使用地图应该创建的对象 少使用 vue 的data 和计算属性(comments)存数据或是vuex。 为什么要要注意这个问题呢? 答:这个就要了解到vue的实现原理 。原理...

DY-Tao
昨天
10
0
web移动端学习:高德地图demo(一)

在高德地图开发中申请开发者资格,然后在控制台中新建应用,获得KEY; 新建模板HTML文件; <!DOCTYPE html><html lang="en"><head><meta charset="UTF-8"><title>地图demo</title><scri......

dxiya
昨天
10
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部