视频课:https://edu.csdn.net/course/play/7621

学习内容

Ø 蓝牙的基本概念

Ø Android中蓝牙的应用

能力目标

Ø 了解蓝牙的基本概念

Ø 掌握Android中蓝牙的应用

Ø 掌握如何使用Android中Wi-Fi

本章简介

蓝牙是一种重要的短距离无线通信技术,它被广泛应用于各种设备,比如计算机、手机、汽车等,支持设备之间的近距离通信,从而是数据传输更加快捷有效。Wi-Fi是一种高速的无线通信协议,它具有传输速度高,传输距离长的特点。通过WiFi,手机、PDA、电脑等移动设备可以以无线方式连接网络。本节中我们主要来学习Android开发中如何调用系统中蓝牙以及wifi的功能。

核心技能部分

11.1 蓝牙简介

蓝牙(Bluettoth)是目前使用最广泛的一种短距离(10M)无线通信协议之一,广泛应用于各种设备中,比如手机、计算机、耳机、鼠标、键盘等。

蓝牙采用了分散式网络结构以及快跳频和短包技术,支持点对点及点对多点的通信,工作在全球通用的2.4GHz频度。根据不同的蓝牙版本,传输速度会差很多,例如:最新的蓝牙3.0传输速度为3Mb/s,而未来的蓝牙4.0技术从理论上可达到60Mb/s。

蓝牙协议分为核心协议层、电缆替代协议层、电话控制协议层、采纳的其它协议层等4层,蓝牙的核心协议包括基带、链路管理、逻辑链路控制和适应协议四部分。其中链路管理(LMP)负责蓝牙组件间连接的建立。逻辑链路控制与适应协议(L2CAP)位于基带协议层上,属于数据链路层,是一个为高层传输和应用层协议屏蔽基带协议的适配协议。

蓝牙技术作为目前比较常用的无线通信技术,早已经成为手机的标配之一,基于Android的手机设备也不例外。但遗憾的是模拟器不支持蓝牙程序的调试,蓝牙程序必须运行在真机上,且必须是在Android版本2.0以上的真机上。

Android中蓝牙有关的类和接口都位于android.bluetooth包中,如下表11-1-1所示。

表11-1-1 蓝牙功能包

功能包

说明

BluetoothAdapter

本地蓝牙适配器

BluetoothClass

蓝牙类,主要包括服务和设备

BluetoothClass.Device

蓝牙设备类

BluetoothClass.Device.Major

蓝牙设备管理器

BluetoothClass.Service

有关蓝牙的服务类

BluetoothDevice

远程蓝牙设备

BluetoothServerSocket

监听蓝牙连接的类

BluetoothSocket

蓝牙连接类

这些蓝牙API允许应用程序扫描、连接和断开其它蓝牙设备,包括编写和修改本地服务的SDP协议数据库和查询其它蓝牙设备上的SDP协议数据库,以及在Android上建立RFCOMM协议的连接并连接到其它指定设备上。

11.2 蓝牙的打开、关闭及搜索

通过11.1小节的学习我们知道Android中与蓝牙相关的类和接口都定义在了android.bluetooth包中,我们常用的主要是BluetoothAdapter和BluetoothDevice两个类。其中BluetoothAdapter类的对象代表了本地的蓝牙适配器;BluetoothDevice代表了一个远程的Bluetooth设备。

扫描已经配对的蓝牙设备时,包括手机和电脑配对,必须得通过手动完成,不能通过代码完成,我们应该把主要的精力放在配对完成之后的操作上来。核心步骤如下:

(1) 获得BluetoothAdapter对象;

(2) 判断当前设备中是否拥有蓝牙设备;

(3) 判断当前设备中的蓝牙设备是否已经打开,如果没有打开的话,要打开;

(4) 得到所有已经配对的蓝牙设备对象BluetoothDevice;

在使用蓝牙之前,需要在功能清单文件AndroidManifest.xm中添加如下权限,

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

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

BluetoothAdapter是蓝牙的核心类,下面的代码创建了BluetoothAdapter对象:

adapter = BluetoothAdapter.getDefaultAdapter();

通过代码还可以直接打开系统的蓝牙设置界面,代码如下:

Intent enable = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);

startActivityForResult(enable, 22);

或直接使用enable()方法打开蓝牙功能,代码如下:

adapter.enable();

要关闭蓝牙,可以使用如下的代码:

adapter.disable();

蓝牙设备打开之后,还需要让其它的蓝牙设备可以搜索到自己,蓝牙才能使用,要想让别人能够搜索到自己,需要在程序中加入如下代码:

Intent discoveryIntent =

new Intent(BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE);

startActivityForResult(discoveryIntent,22);

每一个蓝牙设备由BluetoothDevice描述,需要定义一个List对象,来保存搜索到的蓝牙设备,具体代码如下:

private List<BluetoothDevice> devices = new ArrayList<BluetoothDevice>();

接着调用BluetoothAdapter的startDiscovery()方法就可以搜索附近的蓝牙设备了。系统会在每搜索到一个蓝牙设备时发送一个广播,通过接收这个广播,可以获得搜索到的蓝牙设备信息。当搜索完成时还会发送一个广播,可以在该广播接收器中做一些收尾工作。

示例11.1:

演示了上述蓝牙的常用操作,Activity类的详细代码如下所示:

public class DiscoveryActivity extends ListActivity {

private Handler handler = null;

private BluetoothAdapter adapter = null;// 蓝牙适配器对象

private List<BluetoothDevice> devices = null;// 用来存储搜索到的蓝牙设备

private volatile boolean discoveryFinished;// 表示搜索是否完成

private Runnable discoveryWorkder = new Runnable() {

public void run() {

adapter.startDiscovery();// 开始搜索

while (true) {

if (discoveryFinished) {

break;

}

try {

Thread.sleep(100);

} catch (InterruptedException e) {

}

}

}

};

// 搜索蓝牙设备时调用

private BroadcastReceiver foundReceiver = new BroadcastReceiver() {

public void onReceive(Context context, Intent intent) {

// 获得搜索结果数据

BluetoothDevice device =

intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);

// 将结果添加到设备列表中

devices.add(device);

// 显示列表

showDevices();

}

};

// 搜索完成时调用

private BroadcastReceiver discoveryReceiver = new BroadcastReceiver() {

@Override

public void onReceive(Context context, Intent intent) {

// 卸载注册的接收器

unregisterReceiver(foundReceiver);

unregisterReceiver(this);

discoveryFinished = true;

}

};

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

getWindow().setFlags(LayoutParams.FLAG_BLUR_BEHIND, LayoutParams.FLAG_BLUR_BEHIND);

setContentView(R.layout.discovery);

devices = new ArrayList<BluetoothDevice>();

adapter = BluetoothAdapter.getDefaultAdapter();

handler = new Handler();

if (adapter != null) {

System.out.println("本机拥有蓝牙设备");

// 如果蓝牙适配器没有打开,则打开

if (!adapter.isEnabled()) {

adapter.enable();

}

// 注册discoveryReceiver接收器

IntentFilter discoveryFilter = new IntentFilter(BluetoothAdapter.ACTION_DISCOVERY_FINISHED);

registerReceiver(discoveryReceiver, discoveryFilter);

// 注册foundReceiver接收器

IntentFilter foundFilter = new IntentFilter(BluetoothDevice.ACTION_FOUND);

registerReceiver(foundReceiver, foundFilter);

// 显示一个对话框,正在搜索蓝牙设备

SamplesUtils.indeterminate(DiscoveryActivity.this,

handler, "正在扫描...",

discoveryWorkder,

new OnDismissListener() {

public void onDismiss(DialogInterface dialog) {

for (; adapter.isDiscovering();) {

adapter.cancelDiscovery();

}

discoveryFinished = true;

}

}, true);

}else {

System.out.println("本机没有蓝牙设备");

}

}

// 显示搜索设备列表

protected void showDevices() {

List<String> list = new ArrayList<String>();

for (int i = 0, size = devices.size(); i < size; ++i) {

StringBuilder builder = new StringBuilder();

BluetoothDevice device = devices.get(i);

builder.append(device.getName()).append("  :  ") .append(device.getAddress());

list.add(builder.toString());

}

final ArrayAdapter<String> adapter =  new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, list);

handler.post(new Runnable() {

public void run() {

setListAdapter(adapter);

}

});

}

protected void onListItemClick(ListView l, View v, int position, long id) {

Intent result = new Intent();

result.putExtra(BluetoothDevice.EXTRA_DEVICE, devices.get(position));

setResult(RESULT_OK, result);

finish();

}

}

将程序部署到真机上运行测试程序,结果如下图10.1.1和图10.1.2所示。

11.3 Wi-Fi入门

Wi-Fi的全称是Wireless Fidelity,是一种高速的无线通信协议。Wi-Fi最大的优点是传输速度高,传输速度可以达到11M/S,另外Wi-Fi的有效传输距离也很长。

Wi-Fi的频段在世界范围内是无需任何电信运营执照就可以免费使用,因此WLAN无线设备提供了一个世界范围内可用的、费用极低且数据带宽极高的无线空中接口。用户可以在Wi-Fi覆盖区域内快速浏览网页、随时随地接听、拨打电话。而其它一些基于WLAN的宽带数据应用,如流媒体、网络游戏等功能更是值得用户期待。有了Wi-Fi功能,我们打电话(包括国际长途)、浏览网页、收发电子邮件、音乐下载、数码照片传递等,再也无需担心速度慢和花费高的问题。现在Wi-Fi在国内的覆盖范围越来越广泛,比如高级宾馆、豪华住宅区、飞机场以及咖啡厅之类的场所都有Wi-Fi接口。当我们去旅游、办公时,就可以在这些场所使用我们的移动设备尽情网上冲浪了。

实际上,对于Wi-Fi并不需要过多的控制,当成功连接Wi-Fi后,就可以直接通过IP在Wi-Fi设备之间进行通信了。一般只需要控制打开或关闭Wi-Fi以及获得一些与Wi-Fi相关的信息,基本上来自请求端的信息都是可见的,比如连接速度、IP地址、完成状态等。不幸的是Wi-Fi功能不能在Android模拟器上测试,得使用支持Wi-Fi功能的Android真机才行,就算在有Wi-Fi功能的真机上也需要先通过Wi-Fi和其它Wi-Fi设备连接后,才能获得Wi-Fi相关的信息。

Android中编写Wi-Fi程序,主要涉及以下几个类和接口。

Ø ScanResult:主要用来描述已经检测出的接入点,包括接入点的地址、接入点的名称、身份认证、频率、信号强度等信息。

Ø WifiConfiguration:Wi-Fi网络的配置,包括安全配置等。

Ø WifiManager:提供了管理Wi-Fi连接的大部分API,它主要包括如下内容

(1) 已经配置好的网络清单。这个清单可以查看和修改,而且可以修改个别记录的属性。

(2) 当连接中有活动的Wi-Fi网络时,可以建立或关闭这个连接,并且可以查询有关网络的状态信息。

(3) 对接入点的扫描结果包含足够的信息来决定需要与什么接入点建立连接。

(4) 定义了许多常量来表示Wi-Fi状态的改变。

Ø WifiInfo:Wi-Fi无线连接的描述,包括接入点、网络连接状态、隐藏的接入点、IP地址、连接速度、MAC地址、网络ID、信号强度等信息。

示例11.2

演示如何开关闭Wi-Fi以及获取Wi-Fi相关信息,这些信息包括:MAC地址、接入点的BSSID、IP地址、网络ID等。

布局文件的详细代码如下:

<?xml version="1.0" encoding="utf-8"?>

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"

android:layout_width="fill_parent"

android:layout_height="fill_parent"

android:orientation="vertical" >

<CheckBox

android:id="@+id/chkOpenCloseWifi"

android:layout_width="fill_parent"

android:layout_height="wrap_content" />

<TextView

android:id="@+id/tvScanResult"

android:layout_width="wrap_content"

android:layout_height="wrap_content" />

<TextView

android:id="@+id/tvWifiInfo"

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:textSize="20sp" />

<TextView

android:id="@+id/tvWifiConfigurations"

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:layout_marginTop="20dp"

android:textSize="20sp" />

</LinearLayout>

Activity类代码如下:

public class WIFIActivity extends Activity implements OnCheckedChangeListener {

private WifiManager manager;

private WifiInfo wifiInfo;

private CheckBox chkOpenCloseWifiBox;

private List<WifiConfiguration> wifiConfigurations;

@Override

public void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.wifi);

manager = (WifiManager) getSystemService(Context.WIFI_SERVICE);

wifiInfo = manager.getConnectionInfo();

chkOpenCloseWifiBox = (CheckBox) findViewById(R.id.chkOpenCloseWifi);

TextView tvWifiConfigurations =  (TextView) findViewById(R.id.tvWifiConfigurations);

TextView tvWifiInfo = (TextView) findViewById(R.id.tvWifiInfo);

chkOpenCloseWifiBox.setOnCheckedChangeListener(this);

if (manager.isWifiEnabled()) {

chkOpenCloseWifiBox.setText("Wifi已开启");

chkOpenCloseWifiBox.setChecked(true);

} else {

chkOpenCloseWifiBox.setText("Wifi已关闭");

chkOpenCloseWifiBox.setChecked(false);

}

// 获得Wifi信息

StringBuffer sb = new StringBuffer();

sb.append("Wifi信息\n");

sb.append("MAC地址:" + wifiInfo.getMacAddress() + "\n");

sb.append("接入点的BSSID:" + wifiInfo.getBSSID() + "\n");

sb.append("IP地址(int):" + wifiInfo.getIpAddress() + "\n");

sb.append("IP地址(Hex):"     + Integer.toHexString(wifiInfo.getIpAddress()) + "\n");

sb.append("IP地址:" + ipIntToString(wifiInfo.getIpAddress()) + "\n");

sb.append("网络ID:" + wifiInfo.getNetworkId() + "\n");

tvWifiInfo.setText(sb.toString());

// 得到配置好的网络

wifiConfigurations = manager.getConfiguredNetworks();

tvWifiConfigurations.setText("已连接的无线网络\n");

for (WifiConfiguration wifiConfiguration : wifiConfigurations) {

tvWifiConfigurations.setText(tvWifiConfigurations.getText() + wifiConfiguration.SSID + "\n");

}

}

private String ipIntToString(int ip) {

try {

byte[] bytes = new byte[4];

bytes[0] = (byte) (0xff & ip);

bytes[1] = (byte) ((0xff00 & ip) >> 8);

bytes[2] = (byte) ((0xff0000 & ip) >> 16);

bytes[3] = (byte) ((0xff000000 & ip) >> 24);

return Inet4Address.getByAddress(bytes).getHostAddress();

} catch (Exception e) {

return "";

}

}

@Override

public void onCheckedChanged(CompoundButton buttonView, boolean isChecked){

if (isChecked) {

manager.setWifiEnabled(true);

chkOpenCloseWifiBox.setText("Wifi已开启");

} else {

manager.setWifiEnabled(false);

chkOpenCloseWifiBox.setText("Wifi已关闭");

}

}

}

在有Wi-Fi接入点的环境中,将本程序部署到真机上进行测试,程序运行效果如下图11.1.3所示。

任务实训部分

1:实现一个蓝牙搜索程序

训练技能点

利用BluetoothDevice实现蓝牙设备搜索

需求说明

蓝牙实现的功能是在两台或多台设备之间传传输数据,因此我们要想使用蓝牙设备,首先需要能够搜索到对应的蓝牙设备,然后才能完成数据的传输。本实训要求大家参考11.2节的内容实现一个蓝牙搜索程序,当搜索到别的蓝牙设备后,要求以Toast的形式给用户弹出提示信息。

2:获取Wi-Fi相关信息

训练技能点

如何获取Wi-Fi相关信息

需求说明

Wi-Fi的连接信息在实际的应用中是很有用的,以连接速度为例,当我们可以在程序中根据连接速度的快慢做不同的工作,比如速度比较快时上传或下载资源、慢时浏览网页等。再比如,当我们的程序需要网络时,可以根据Wi-Fi的完成状态,来判断用户是否联网,如果没有联网给用户以相应的提示。本示例要实现的功能就是获取Wi-Fi的所有信息,然后显现给用户。


巩固练习

一、选择题

1. 蓝牙工作的频度是()

A. 1.8GHz

B. 2.4GHz

C. 3.2GHz

D. 3.0GHz

2. 下列说法中正确的是(  )

A. WIFI的全称是Wireless Fidelety

B. WIFI的频段在世界范围内是无需任何电信运营执照就可以免费使用

C. 当成功连接WIFI后,就可以直接通过IP在WIFI设备之间进行通信了

D. ScanResult类主要用来描述已经检测出的接入点

二、上机练习

编写一程序,实现对Wi-Fi和蓝牙开启、关闭状态的控制。

android 十八 蓝牙及Wi-Fi相关推荐

  1. ugui 转轮_Unity3D研究院之Android NDK编译C/C++结合Unity实现本地数据共享(二十八)...

    开始本篇文章之前我先为大家简单的介绍一下Android NDK编程的原理, 我们知道Android开发使用JAVA语言来编程它的运行效率要比C/C++低很多,为了让JAVA语言可以调用 C/C++ 这 ...

  2. (转载)Android项目实战(二十八):使用Zxing实现二维码及优化实例

    Android项目实战(二十八):使用Zxing实现二维码及优化实例 作者:听着music睡 字体:[增加 减小] 类型:转载 时间:2016-11-21 我要评论 这篇文章主要介绍了Android项 ...

  3. Android项目实战(三十八):2017最新 将AndroidLibrary提交到JCenter仓库(图文教程)...

    Android项目实战(三十八):2017最新 将AndroidLibrary提交到JCenter仓库(图文教程) 原文:Android项目实战(三十八):2017最新 将AndroidLibrary ...

  4. Android绘图Canvas十八般武器之Shader详解及实战篇(上)

    本篇文章已授权微信公众号 guolin_blog (郭霖)独家发布 前言 Android中绘图离不开的就是Canvas了,Canvas是一个庞大的知识体系,有java层的,也有jni层深入到Frame ...

  5. Android绘图Canvas十八般武器之Shader详解及实战篇(下)

    前言 上一篇<Android绘图Canvas十八般武器之Shader篇(上)> 我们知道了Bitmap的用法,及TileMode的详细情况.接下来,这一篇作为整个知识体系的下半部要讲的是S ...

  6. 基于eclipse的android项目实战—博学谷(十八)播放不同视频(网络视频)

    相信经过了这么长时间,小伙伴们应该都发现了博学谷这个项目存在问题,播放视频的时候,无论播放任何一个章节,他播放的视频都只是一个,也就是VideoPlayActivity.java里面写死的那个(myv ...

  7. Android简易音乐重构MVVM Java版-新增推荐、雷达歌单详情列表界面(十八)

    Android简易音乐重构MVVM Java版-新增推荐.雷达歌单详情列表界面(十八) 关于 效果 修改ApiService 增加歌单列表实体类RecommendListEntity 新增歌单列表界面 ...

  8. Android版疯狂填字第三关,iOS/安卓版《疯狂填字》答案攻略第三十八关

    <疯狂填字>,最创新的填字玩法,挑战你的脑细胞,现在就下载.疯狂填字是最早的在线中文填字游戏,现在你可以在苹果手机上玩填字也可以在安卓手机上面玩,既打发了时间,又增长了知识,你准备好挑战了 ...

  9. 关闭数字健康 android 魅族,数字体验 篇二十八:精雕细刻,只为给魅友更好的选择,魅族16s Pro体验分享...

    数字体验 篇二十八:精雕细刻,只为给魅友更好的选择,魅族16s Pro体验分享 2019-09-06 17:31:22 14点赞 10收藏 15评论 当我还一直在称赞魅族16s所拥有的舒适手感表现时, ...

最新文章

  1. Python-CSS整理
  2. could not initialize proxy - no Session
  3. 系统架构设计师-软件水平考试(高级)-理论-操作系统
  4. 眼下发展最迅猛的十家网络安全公司
  5. total是什么牌子的电脑_干货!如何用Python在笔记本电脑上分析100GB数据(上)...
  6. linux java gc_Java GC机制及相关
  7. 《深入理解计算机系统》家庭作业
  8. 使用百度Android地图SDK显示地图定位
  9. 在线LOGO的设计工具推荐
  10. 车牌号正则校验(新能源)
  11. Win10系统修改用户名以及C盘下Users用户名实操手册(实测有效)
  12. oh my zsh 的alias文件
  13. 获取中国银行网页中外汇率
  14. 微服务学习总结4(网关和consul结合)
  15. R计算方差膨胀因子(VIF,Variance Inflation Factor)计算并解读VID与共线性(Multicollinearity)的关系实战
  16. c++编程拼图小游戏
  17. 大数据:13个真实世界情景中的数据科学应用
  18. mfcc概念 参数介绍
  19. java excel数据有效性,5个示例,让你重新认识excel数据有效性
  20. SpringCloud Feign重试详解

热门文章

  1. 响应式系统reactive system初探
  2. 如何在Spring boot中修改默认端口
  3. Persistent Memory错误注入测试
  4. Oracle表空间的查询与创建
  5. python多维数据post给php_使用Python中的POST将数据发送到PHP
  6. hdu 4497 GCD and LCM
  7. java面试题(转载其他人,方便日常看)
  8. python链表和树实验报告_关于Python实现树结构和链表结构的一点想法
  9. server php self_PHP 使用 $_SERVER[''PHP_SELF''] 获取当前页面地址及其安全性问题[转载]...
  10. 语言取10的整数倍_C语言结构体用法很多,坑也很多