智能

蓝牙灯泡步骤:

1.打开蓝牙->打开成功
2.开始扫描->扫描到设备->停止扫描
3.开始连接->连接成功
4.发送请求->打开or关闭。
这里写图片描述

开灯 : 1 -103 16 16 -103
光灯 : 1 -103 17 17 -103
点动 : 1 -103 25 25 -103
//要存储5个16进制,所以定义一个长度为5的byte数组,接下将十六进制存储到byte数组中(需要强转),因为的byte,byte里存储的是-128-127范围的十进制数值,所以里面实际存储的是16进制以字节形式转换成的十进制数字

蓝牙灯泡疑问

1byte[] b = new byte[5]
b[0] = (byte)0x01
学生会问,为什么这么存储
参考文档中 “智能灯泡byte存储16进制问题”的txt文档
2.蓝牙一个手机配对成功,另一个手机无法扫描到的问题
答:蓝牙模块是socket进行连接的,我们的蓝牙模块是通过单连接进行连接的
3.looper问题
参考ppt中的注释
4.蓝牙版本问题,在低版本中不使用Uid也可以连接,高版本中必须使用
兼容性,参考ppt中的注释

蓝牙API

1.指令格式:
帧头 帧头 端口号 状态 帧尾
A1 FD xx xx DF

帧头、帧尾:为固定的开头和结尾的数据,不可修改
端口号:指当前控制的端口序号,01-0A共10个端口
状态:值当前被控制的端口要执行的状态,分别有00,01,02,Ax,Cx,对应,自锁的 状态,地电平,高电平,点动查询、状态查询
其中点动延时数值Ax,A代表点动标识符(固定),x代表要延时的时间1-F共15秒可 选(可修改),状态查询数值Cx,C代表查询标识符,x代表要查询的的端口号1-A共 10个端口
2.接上电源,灯会闪烁
3.蓝牙广播接受者 BluetoothAdapter的作用
通过getDefaultAdapter获取该适配器对象,你可以通过getBondedDevices();获取配对的设备,或者创建一个BluetoothServerSocket和listenUsingRfcommWithServiceRecord(String, UUID);传入连接请求

蓝牙API笔记

  • 常用API BluetoothAdapter BluetoothDevice BluetoothSocket

  • BluetoothAdapter 代表一个蓝牙适配器硬件

  • 通过BluetoothAdapter 可以打开/关闭蓝牙适配器 扫描周边蓝牙设备…

    bluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
    
  • 打开/关闭 蓝牙设备

    bluetoothAdapter.enable();  bluetoothAdapter.disable();
    
  • 操作蓝牙设备需要权限

    <uses-permission android:name="android.permission.BLUETOOTH"/>
    <uses-permission android:name="android.permission.BLUETOOTH_ADMIN"/>
    
  • 扫描/停止扫描蓝牙设备

    扫描二维码关注公众号,回复: 2271187 查看本文章
    bluetoothAdapter.startDiscovery();
    bluetoothAdapter.cancelDiscovery();
    
  • 系统发现周边的蓝牙设备会发一个广播

    BluetoothDevice.ACTION_FOUND
    
  • 监听BluetoothDevice.ACTION_FOUND广播 收到广播后可以从intent中获取到蓝牙设备

  • BluetoothDevice 代表一个可以连接的蓝牙硬件对象
  • 通过BluetoothDevice可以获得 BluetoothSocket对象

    socket = device.createRfcommSocketToServiceRecord(UUID.fromString(
                        "00001101-0000-1000-8000-00805f9b34fb"));
    
  • 获得BluetoothSocket对象之后可以调用 connect();方法跟服务端创建连接
  • 连接创建后可以通过 BluetoothSocket对象获得输入输出流

  • 创建蓝牙连接步骤

    ① 通过BluetoothAdapter打开蓝牙适配器
    ② 通过bluetoothAdapter.startDiscovery();扫描硬件
    ③ 创建广播接收者监听BluetoothDevice.ACTION_FOUND广播 获得BluetoothDevice对象
    ④ 通过device.createRfcommSocketToServiceRecord(UUID.fromString(
                                "00001101-0000-1000-8000-00805f9b34fb"));获得BluetoothSocket
    ⑤ BluetoothSocket 的connect();方法 连接到蓝牙设备
    ⑥ 通过BluetoothSocket获得输入输出流 通过流传递数据
    

蓝牙官方API

Bluetooth —— 蓝牙
The Android platform includes support for the Bluetooth network stack, which allows a device to wirelessly exchange data with other Bluetooth devices. The application framework provides access to the Bluetooth functionality through the Android Bluetooth APIs. These APIs let applications wirelessly connect to other Bluetooth devices, enabling point-to-point and multipoint wireless features.
Android平台包含了对蓝牙网络栈的支持,它允许一个设备与其他蓝牙设备进行无线数据传输。该应用程序框架通过Android Bluetooth APIs提供了一个蓝牙编程接口。这些接口使得应用可以与其他蓝牙设备进行无线连接,完成点对点以及多点的无线特点。
Using the Bluetooth APIs, an Android application can perform the following:
• Scan for other Bluetooth devices
• Query the local Bluetooth adapter for paired Bluetooth devices
• Establish RFCOMM channels
• Connect to other devices through service discovery
• Transfer data to and from other devices
• Manage multiple connections
使用蓝牙接口,一个Android应用可以执行以下功能:
• 扫描其他蓝牙设备
• 为配对的蓝牙设备查询本地蓝牙适配器
• 建立RFCOMM串口
• 通过服务发现连接到其他设备
• 和其他设备之间进行数据传输
• 控制多重连接
The Basics —— 基础


This document describes how to use the Android Bluetooth APIs to accomplish the four major tasks necessary to communicate using Bluetooth: setting up Bluetooth, finding devices that are either paired or available in the local area, connecting devices, and transferring data between devices.
本文档描述了怎样使用Android Bluetooth APIs来完成以下使用蓝牙进行交互的所必要的四个主要任务:建立蓝牙,查找设备(配对的或是在当前区域可用的),连接设备,以及在设备间传输数据。
All of the Bluetooth APIs are available in the android.bluetoothpackage. Here’s a summary of the classes and interfaces you will need to create Bluetooth connections:
所有的蓝牙接口在android.bluetooth包内都是可用的。对于你将要需要创建的蓝牙连接,下面展示了一些类和接口的总结:
BluetoothAdapter
Represents the local Bluetooth adapter (Bluetooth radio). TheBluetoothAdapter is the entry-point for all Bluetooth interaction. Using this, you can discover other Bluetooth devices, query a list of bonded (paired) devices, instantiate aBluetoothDevice using a known MAC address, and create aBluetoothServerSocket to listen for communications from other devices.
代表本地蓝牙适配器(蓝牙无线电)。BluetoothAdapter是所有蓝牙交互的入口。使用这个你可以发现其他蓝牙设备,查询已配对的设备列表,使用一个已知的MAC地址来实例化一个BluetoothDevice,以及创建一个BluetoothServerSocket来为监听与其他设备的通信。
BluetoothDevice
Represents a remote Bluetooth device. Use this to request a connection with a remote device through aBluetoothSocket or query information about the device such as its name, address, class, and bonding state.
代表一个远程蓝牙设备,使用这个来请求一个与远程设备的BluetoothSocket连接,或者查询关于设备名称、地址、类和连接状态等设备信息。
BluetoothSocket
Represents the interface for a Bluetooth socket (similar to a TCPSocket). This is the connection point that allows an application to exchange data with another Bluetooth device via InputStream and OutputStream.
代表一个蓝牙socket的接口(和TCP Socket类似)。这是一个连接点,它允许一个应用与其他蓝牙设备通过InputStream和OutputStream交换数据。
BluetoothServerSocket
Represents an open server socket that listens for incoming requests (similar to a TCPServerSocket). In order to connect two Android devices, one device must open a server socket with this class. When a remote Bluetooth device makes a connection request to the this device, theBluetoothServerSocket will return a connectedBluetoothSocket when the connection is accepted.
代表一个开放的服务器socket,它监听接受的请求(与TCP ServerSocket类似)。为了连接两台Android设备,一个设备必须使用这个类开启一个服务器socket。当一个远程蓝牙设备开始一个和该设备的连接请求,BluetoothServerSocket将会返回一个已连接的BluetoothSocket,接受该连接。
BluetoothClass
Describes the general characteristics and capabilities of a Bluetooth device. This is a read-only set of properties that define the device’s major and minor device classes and its services. However, this does not reliably describe all Bluetooth profiles and services supported by the device, but is useful as a hint to the device type.
描述一个蓝牙设备的基本特性和性能。这是一个只读的属性集合,它定义了设备的主要和次要的设备类以及它的服务。但是,它没有描述所有的蓝牙配置和设备支持的服务,它只是暗示了设备的类型。
BluetoothProfile
An interface that represents a Bluetooth profile. A Bluetooth profile is a wireless interface specification for Bluetooth-based communication between devices. An example is the Hands-Free profile. For more discussion of profiles, seeWorking with Profiles
一个表示蓝牙配置文件的接口。一个Bluetooth profile是一个基于蓝牙的通信无线接口定义。一个例子是Hands-Free profile。更多的讨论请见Working with Profiles。
BluetoothHeadset
Provides support for Bluetooth headsets to be used with mobile phones. This includes both Bluetooth Headset and Hands-Free (v1.5) profiles.
提供对移动手机使用的蓝牙耳机的支持。它包含了Headset and Hands-Free (v1.5)配置文件。
BluetoothA2dp
Defines how high quality audio can be streamed from one device to another over a Bluetooth connection. “A2DP” stands for Advanced Audio Distribution Profile.
定义高品质的音频如何通过蓝牙连接从一个设备传输到另一个设备。”A2DP“是Advanced Audio Distribution Profile的缩写。
BluetoothHealth
Represents a Health Device Profile proxy that controls the Bluetooth service.
表示一个Health Device Profile代理,它控制蓝牙服务。
BluetoothHealthCallback
An abstract class that you use to implement BluetoothHealth callbacks. You must extend this class and implement the callback methods to receive updates about changes in the application’s registration state and Bluetooth channel state.
一个抽象类,你可以使用它来实现BluetoothHealth的回调函数。你必须扩展这个类并实现回调函数方法来接收应用程序的注册状态改变以及蓝牙串口状态的更新。
BluetoothHealthAppConfiguration
Represents an application configuration that the Bluetooth Health third-party application registers to communicate with a remote Bluetooth health device.
表示一个应用程序配置,Bluetooth Health第三方应用程序注册和一个远程Bluetooth Health设备通信。
BluetoothProfile.ServiceListener
An interface that notifies BluetoothProfile IPC clients when they have been connected to or disconnected from the service (that is, the internal service that runs a particular profile).
一个接口,当BluetoothProfile IPC客户端从服务器上建立连接或断开连接时,它负责通知它们(也就是,运行在特性配置的内部服务)。
Bluetooth Permissions —— 蓝牙权限


In order to use Bluetooth features in your application, you need to declare at least one of two Bluetooth permissions:BLUETOOTHandBLUETOOTH_ADMIN.
为了在你的应用中使用蓝牙特性,你需要至少声明一种蓝牙权限:BLUETOOTH 和BLUETOOTH_ADMIN。
You must request the BLUETOOTH permission in order to perform any Bluetooth communication, such as requesting a connection, accepting a connection, and transferring data.
为了执行任何蓝牙通信,例如请求一个连接、接受一个连接以及传输数据,你必须请求BLUETOOTH 权限。
You must request the BLUETOOTH_ADMINpermission in order to initiate device discovery or manipulate Bluetooth settings. Most applications need this permission solely for the ability to discover local Bluetooth devices. The other abilities granted by this permission should not be used, unless the application is a “power manager” that will modify Bluetooth settings upon user request.Note: If you use BLUETOOTH_ADMIN permission, then must also have theBLUETOOTH permission.
为了初始化设备查找或控制蓝牙设置,你必须请求BLUETOOTH_ADMIN权限。大多数应用需要这个权限,仅仅是为了可以发现本地蓝牙设备。这个权限授权的其他功能不应该被使用,除非该应用是一个“强大的控制器”,来通过用户请求修改蓝牙设置。注意:如果你使用BLUETOOTH_ADMIN权限,那么必须拥有BLUETOOTH权限。
Declare the Bluetooth permission(s) in your application manifest file. For example:
在你的应用程序清单文件中声明蓝牙权限。例如:

Before your application can communicate over Bluetooth, you need to verify that Bluetooth is supported on the device, and if so, ensure that it is enabled.
在你的应用可以通过蓝牙进行通信之前,你需要验证该设备是否支持蓝牙,如果支持,确保它被打开了。
If Bluetooth is not supported, then you should gracefully disable any Bluetooth features. If Bluetooth is supported, but disabled, then you can request that the user enable Bluetooth without leaving your application. This setup is accomplished in two steps, using the BluetoothAdapter.
如果不支持蓝牙,那么你应该优雅地关掉所有蓝牙特性,如果支持蓝牙,但是没有开启,那么你可以请求用户在不离开你的应用前提下开启蓝牙。这个过程使用BluetoothAdapter用两步完成。
1. Get the BluetoothAdapter 得到BluetoothAdapter
The BluetoothAdapter is required for any and all Bluetooth activity. To get theBluetoothAdapter, call the staticgetDefaultAdapter() method. This returns aBluetoothAdapter that represents the device’s own Bluetooth adapter (the Bluetooth radio). There’s one Bluetooth adapter for the entire system, and your application can interact with it using this object. IfgetDefaultAdapter() returns null, then the device does not support Bluetooth and your story ends here. For example: 所有的蓝牙活动都需要请求BluetoothAdapter。为了得到BluetoothAdapter,调用静态的getDefaultAdapter()方法。它返回一个BluetoothAdapter,代表设备本身的蓝牙适配器(蓝牙无线电)。一个完整的系统只有一个蓝牙适配器,而且你的应用可以使用BluetoothAdapter与它进行交互。如果BluetoothAdapter返回为null,那么设备不支持蓝牙而你的故事将在此结束。例如:
1. BluetoothAdapter mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
2. if (mBluetoothAdapter == null) { // Device does not support Bluetooth
3. }

2.Enable Bluetooth 开启蓝牙
Next, you need to ensure that Bluetooth is enabled. Call isEnabled() to check whether Bluetooth is currently enable. If this method returns false, then Bluetooth is disabled. To request that Bluetooth be enabled, call startActivityForResult()with theACTION_REQUEST_ENABLE action Intent. This will issue a request to enable Bluetooth through the system settings (without stopping your application). For example: 接下来,你需要保证蓝牙是开启的。调用isEnabled()来检查蓝牙最近是否是开启的。如果这个方法返回false,那么蓝牙没有开启。为了请求开启蓝牙,调用startActivityForResult()并使用ACTION_REQUEST_ENABLE方法Intent。这将发出一个请求来利用系统设置开启蓝牙(不需要停止你的应用)。例如:
1. if (!mBluetoothAdapter.isEnabled()) {
2. Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
3. startActivityForResult(enableBtIntent, REQUEST_ENABLE_BT);
4. }
1.A dialog will appear requesting user permission to enable Bluetooth, as shown in Figure 1. If the user responds “Yes,” the system will begin to enable Bluetooth and focus will return to your application once the process completes (or fails).
1.一个对话框将会出现,请求用户开启蓝牙,像在图1中展示的那样。如果用户相应”是“,系统将会开启蓝牙,而且一旦完成进程(或失败)就返回你的应用。
2.The REQUEST_ENABLE_BT constant passed to startActivityForResult() is a locally defined integer (which must be greater than 0), that the system passes back to you in youronActivityResult() implementation as therequestCode parameter.
传给startActivityForResult()的REQUEST_ENABLE_BT常量是一个本地定义的整型(必须大于0),系统在你的onActivityResult()实现中返回给你作为requestCode参数。
If enabling Bluetooth succeeds, your activity receives the RESULT_OK result code in theonActivityResult()callback. If Bluetooth was not enabled due to an error (or the user responded “No”) then the result code isRESULT_CANCELED.
如果开启蓝牙成功,你的activity在onActivityResult()回调函数中接受一个RESULT_OK结果代码。如果蓝牙因为一个错误(或者用户相应”否“)没有开启,那么结果代码就是RESULT_CANCELED。
Optionally, your application can also listen for theACTION_STATE_CHANGED broadcast Intent, which the system will broadcast whenever the Bluetooth state has changed. This broadcast contains the extra fields EXTRA_STATE andEXTRA_PREVIOUS_STATE, containing the new and old Bluetooth states, respectively. Possible values for these extra fields areSTATE_TURNING_ON,STATE_ON,STATE_TURNING_OFF, andSTATE_OFF. Listening for this broadcast can be useful to detect changes made to the Bluetooth state while your app is running.
可选的,你的应用也可以监听ACTION_STATE_CHANGED广播Intent,任何时候蓝牙状态改变了系统将会广播该Intent。这个广播包含了额外的变量EXTRA_STATE 和EXTRA_PREVIOUS_STATE,分别包含了新的和老的蓝牙状态。这些额外的变量可能值是STATE_TURNING_ON,STATE_ON,STATE_TURNING_OFF和STATE_OFF。监听这个广播对于检测你的应用运行时蓝牙状态的变化是非常有用的。
Tip: Enabling discoverability will automatically enable Bluetooth. If you plan to consistently enable device discoverability before performing Bluetooth activity, you can skip step 2 above. Read aboutenabling discoverability, below.
提示:开启可发现性将会自动开启蓝牙。如果你打算在执行蓝牙activity之前长期开启设备的可发现性,你可以跳过上面的第二步。阅读下面的enabling discoverability。
Finding Devices


Using the BluetoothAdapter, you can find remote Bluetooth devices either through device discovery or by querying the list of paired (bonded) devices.
使用BluetoothAdapter,你可以通过设备检测或者查询已配对的设备来找到远程蓝牙设备。
Device discovery is a scanning procedure that searches the local area for Bluetooth enabled devices and then requesting some information about each one (this is sometimes referred to as “discovering,” “inquiring” or “scanning”). However, a Bluetooth device within the local area will respond to a discovery request only if it is currently enabled to be discoverable. If a device is discoverable, it will respond to the discovery request by sharing some information, such as the device name, class, and its unique MAC address. Using this information, the device performing discovery can then choose to initiate a connection to the discovered device.
设备检测是一个浏览流程,它查找附近的蓝牙可用设备,然后请求每个设备的相关信息(这有时被称为“检测”“查询”或“浏览”等)。虽然,附近的蓝牙设备仅在它目前是可被检测的状态下时才会回应发现请求。如果一个设备是可被检测的,它将通过分享一些数据来相应检测请求,例如设备名称,类,以及他的唯一的MAC地址。使用这个信息,进行检测的设备可以选择和检测到的的设备初始化一个连接。
Once a connection is made with a remote device for the first time, a pairing request is automatically presented to the user. When a device is paired, the basic information about that device (such as the device name, class, and MAC address) is saved and can be read using the Bluetooth APIs. Using the known MAC address for a remote device, a connection can be initiated with it at any time without performing discovery (assuming the device is within range).
一旦一个连接第一次和一个远程设备进行连接,一个匹配的请求会自动呈现在用户面前。当一个设备配对后,设备的基本信息(例如设备名称、类、MAC地址)将被保存,并且可以使用蓝牙接口进行访问。使用已知的MAC地址,一个连接可以在任何时间被初始化,而不需要执行检测(假设设备在可检测范围内)。
Remember there is a difference between being paired and being connected. To be paired means that two devices are aware of each other’s existence, have a shared link-key that can be used for authentication, and are capable of establishing an encrypted connection with each other. To be connected means that the devices currently share an RFCOMM channel and are able to transmit data with each other. The current Android Bluetooth API’s require devices to be paired before an RFCOMM connection can be established. (Pairing is automatically performed when you initiate an encrypted connection with the Bluetooth APIs.)
记住,配对和连接之间有一点是不同的。配对以为着两台设备是知道彼此的存在的,它们有一个共享的链接密匙,可以用于授权以及建立一个加密的连接。而连接意味着设备目前共享一个RFCOMM通道,并且可以彼此传输数据。目前的安卓蓝牙接口要求设备在建立一个RFCOMM连接之前先进行配对。(当你使用蓝牙接口初始化一个加密的连接时,配对是自动执行的)。
The following sections describe how to find devices that have been paired, or discover new devices using device discovery.
下面的章节描述了如何查找已配对的设备,或者使用设备检测找到新的设备。
Note: Android-powered devices are not discoverable by default. A user can make the device discoverable for a limited time through the system settings, or an application can request that the user enable discoverability without leaving the application. How to enable discoverability is discussed below.
注意:安卓设备默认是不可检测的。一个用户可以通过系统设置使设备在一定时间内是可检测的,或者一个应用可以请求用户开启可检测功能而不需要离开应用。下面描述了怎样开启可检测功能。
Querying paired devices —— 查询已配对的设备
Before performing device discovery, its worth querying the set of paired devices to see if the desired device is already known. To do so, callgetBondedDevices(). This will return a Set ofBluetoothDevices representing paired devices. For example, you can query all paired devices and then show the name of each device to the user, using an ArrayAdapter:
1. Set pairedDevices = mBluetoothAdapter.getBondedDevices();
2. // If there are paired devices
3. if (pairedDevices.size() > 0) {
4. // Loop through paired devices
5. for (BluetoothDevice device : pairedDevices) {
6. // Add the name and address to an array adapter to show in a ListView
7. mArrayAdapter.add(device.getName() + “\n” + device.getAddress());
8. }
9. }
All that’s needed from the BluetoothDevice object in order to initiate a connection is the MAC address. In this example, it’s saved as a part of an ArrayAdapter that’s shown to the user. The MAC address can later be extracted in order to initiate the connection. You can learn more about creating a connection in the section aboutConnecting Devices.
Discovering devices
To start discovering devices, simply call startDiscovery(). The process is asynchronous and the method will immediately return with a boolean indicating whether discovery has successfully started. The discovery process usually involves an inquiry scan of about 12 seconds, followed by a page scan of each found device to retrieve its Bluetooth name.
Your application must register a BroadcastReceiver for theACTION_FOUND Intent in order to receive information about each device discovered. For each device, the system will broadcast theACTION_FOUND Intent. This Intent carries the extra fieldsEXTRA_DEVICEandEXTRA_CLASS, containing aBluetoothDevice and a BluetoothClass, respectively. For example, here’s how you can register to handle the broadcast when devices are discovered:
[java] view plaincopyprint?
1. // Create a BroadcastReceiver for ACTION_FOUND
2. private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
3. public void onReceive(Context context, Intent intent) {
4. String action = intent.getAction();
5. // When discovery finds a device
6. if (BluetoothDevice.ACTION_FOUND.equals(action)) {
7. // Get the BluetoothDevice object from the Intent
8. BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
9. // Add the name and address to an array adapter to show in a ListView
10. mArrayAdapter.add(device.getName() + “\n” + device.getAddress());
11. }
12. }
13. };
14. // Register the BroadcastReceiver
15. IntentFilter filter = new IntentFilter(BluetoothDevice.ACTION_FOUND);
16. registerReceiver(mReceiver, filter); // Don’t forget to unregister during onDestroy

All that’s needed from the BluetoothDevice object in order to initiate a connection is the MAC address. In this example, it’s saved as a part of an ArrayAdapter that’s shown to the user. The MAC address can later be extracted in order to initiate the connection. You can learn more about creating a connection in the section aboutConnecting Devices.
Caution: Performing device discovery is a heavy procedure for the Bluetooth adapter and will consume a lot of its resources. Once you have found a device to connect, be certain that you always stop discovery withcancelDiscovery() before attempting a connection. Also, if you already hold a connection with a device, then performing discovery can significantly reduce the bandwidth available for the connection, so you should not perform discovery while connected.
Enabling discoverability
If you would like to make the local device discoverable to other devices, callstartActivityForResult(Intent, int) with theACTION_REQUEST_DISCOVERABLE action Intent. This will issue a request to enable discoverable mode through the system settings (without stopping your application). By default, the device will become discoverable for 120 seconds. You can define a different duration by adding theEXTRA_DISCOVERABLE_DURATION Intent extra. The maximum duration an app can set is 3600 seconds, and a value of 0 means the device is always discoverable. Any value below 0 or above 3600 is automatically set to 120 secs). For example, this snippet sets the duration to 300:
Intent discoverableIntent = newIntent(BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE);
discoverableIntent.putExtra(BluetoothAdapter.EXTRA_DISCOVERABLE_DURATION, 300);
startActivity(discoverableIntent);
Figure 2: The enabling discoverability dialog.
A dialog will be displayed, requesting user permission to make the device discoverable, as shown in Figure 2. If the user responds “Yes,” then the device will become discoverable for the specified amount of time. Your activity will then receive a call to theonActivityResult()) callback, with the result code equal to the duration that the device is discoverable. If the user responded “No” or if an error occurred, the result code will be RESULT_CANCELED.
Note: If Bluetooth has not been enabled on the device, then enabling device discoverability will automatically enable Bluetooth.
The device will silently remain in discoverable mode for the allotted time. If you would like to be notified when the discoverable mode has changed, you can register a BroadcastReceiver for theACTION_SCAN_MODE_CHANGEDIntent. This will contain the extra fieldsEXTRA_SCAN_MODE andEXTRA_PREVIOUS_SCAN_MODE, which tell you the new and old scan mode, respectively. Possible values for each areSCAN_MODE_CONNECTABLE_DISCOVERABLE,SCAN_MODE_CONNECTABLE, or SCAN_MODE_NONE, which indicate that the device is either in discoverable mode, not in discoverable mode but still able to receive connections, or not in discoverable mode and unable to receive connections, respectively.
You do not need to enable device discoverability if you will be initiating the connection to a remote device. Enabling discoverability is only necessary when you want your application to host a server socket that will accept incoming connections, because the remote devices must be able to discover the device before it can initiate the connection.
Connecting Devices —— 连接设备


In order to create a connection between your application on two devices, you must implement both the server-side and client-side mechanisms, because one device must open a server socket and the other one must initiate the connection (using the server device’s MAC address to initiate a connection). The server and client are considered connected to each other when they each have a connected BluetoothSocket on the same RFCOMM channel. At this point, each device can obtain input and output streams and data transfer can begin, which is discussed in the section about Managing a Connection. This section describes how to initiate the connection between two devices.
为了在两台设备上创建一个连接,你必须实现服务器端和客户端两头的机制,因为一个设备必须打开一个服务器socket,而另一个设备初始化创建(使用服务器设备的MAC地址来初始化一个连接)。当他们在相同的RFCOMM通道上有一个已连接的 BluetoothSocket 时,服务器和客户被认为是互相连接了。这时,每一个设备可以包含输入和输出流,而且可以开始数据传输,这在Managing a Connection课程中将会讨论。本节课描述了怎样在两台设备之间初始化连接。
The server device and the client device each obtain the required BluetoothSocket in different ways. The server will receive it when an incoming connection is accepted. The client will receive it when it opens an RFCOMM channel to the server.
服务器设备和客户端设备使用不同的方法来得到需要的 BluetoothSocket 。服务器在接受外来的连接的将会接收到它。客户端在向服务器端打开一个RFCOMM通道时会接收到它。
Figure 3: The Bluetooth pairing dialog.
图3:蓝牙配对对话框
One implementation technique is to automatically prepare each device as a server, so that each one has a server socket open and listening for connections. Then either device can initiate a connection with the other and become the client. Alternatively, one device can explicitly “host” the connection and open a server socket on demand and the other device can simply initiate the connection.
一种实现技术使得每一个设备都可以成为一个服务器,因此每一个都有一个打开的服务器socket,并且随时监听连接。然后另一个设备可以初始化连接,并且成为客户端。对应的,一个设备可以显式地“发起”连接,并且在需要时打开一个服务器socket,而另一个设备可以简单地初始化连接即可。
Note: If the two devices have not been previously paired, then the Android framework will automatically show a pairing request notification or dialog to the user during the connection procedure, as shown in Figure 3. So when attempting to connect devices, your application does not need to be concerned about whether or not the devices are paired. Your RFCOMM connection attempt will block until the user has successfully paired, or will fail if the user rejects pairing, or if pairing fails or times out.
注意:如果两台设备之前没有配对过,那么Android框架将会自动显示一个请求配对的通知或对话框,正如图3中显示的那样。因此,当尝试连接设备时,你的应用不需要考虑设备是否配对过。你的RFCOMM连接尝试将会阻塞,知道用户成功配对,或者用户拒绝失败时,或者配对失败,或者超时。
Connecting as a server —— 作为服务器端连接
When you want to connect two devices, one must act as a server by holding an open BluetoothServerSocket. The purpose of the server socket is to listen for incoming connection requests and when one is accepted, provide a connected BluetoothSocket. When theBluetoothSocket is acquired from the BluetoothServerSocket, the BluetoothServerSocket can (and should) be discarded, unless you want to accept more connections.
当你想要连接两台设备时,一个必须通过持有一个打开的 BluetoothServerSocket 来作为服务器端。服务器socket的目的是为了监听外来的连接请求,当一个请求被接受后,提供一个连接的BluetoothSocket。当该BluetoothSocket被BluetoothServerSocket请求时,BluetoothServerSocket 可以(而且应当)被舍弃,除非你想要接收更多的连接。
About UUID —— 关于UUID
A Universally Unique Identifier (UUID) is a standardized 128-bit format for a string ID used to uniquely identify information. The point of a UUID is that it’s big enough that you can select any random and it won’t clash. In this case, it’s used to uniquely identify your application’s Bluetooth service. To get a UUID to use with your application, you can use one of the many random UUID generators on the web, then initialize a UUID with fromString(String).
一个全局唯一的标识符(UUID)是一个标准的128-bit格式的string ID,它被用于唯一标识信息。一个UUID的关键点是它非常大以至于你可以随机选择而不会发生崩溃。在这种情况下,它被用于唯一地指定你的应用中的蓝牙服务。为了得到一个UUID以在你的应用中使用,你可以使用网络上的任何一种随机UUID产生器,然后使用 fromString(String)初始化一个UUID。
Here’s the basic procedure to set up a server socket and accept a connection:
下面是创建一个服务器socket并且接受一个连接的基本过程:
1.Get a BluetoothServerSocket by calling the listenUsingRfcommWithServiceRecord(String, UUID). 通过调用 listenUsingRfcommWithServiceRecord(String, UUID)得到一个BluetoothServerSocket。
The string is an identifiable name of your service, which the system will automatically write to a new Service Discovery Protocol (SDP) database entry on the device (the name is arbitrary and can simply be your application name). The UUID is also included in the SDP entry and will be the basis for the connection agreement with the client device. That is, when the client attempts to connect with this device, it will carry a UUID that uniquely identifies the service with which it wants to connect. These UUIDs must match in order for the connection to be accepted (in the next step).
这个String是你的服务的标志名称,系统将会把它写入设备中的一个新的服务发现协议(SDP)数据库条目中(名字是任意的,并且可以只是你应用的名字)。UUID同样被包含在SDP条目中,并且将会成为和客户端设备连接协议的基础。也就是说,当客户端尝试连接这个设备时,它将会携带一个UUID用于唯一指定它想要连接的服务器。这些UUIDs必须匹配以便该连接可以被接受(在下一步中)。
2.Start listening for connection requests by calling accept(). 通过调用accept()开始监听连接请求。
This is a blocking call. It will return when either a connection has been accepted or an exception has occurred. A connection is accepted only when a remote device has sent a connection request with a UUID matching the one registered with this listening server socket. When successful, accept() will return a connected BluetoothSocket.
这一个阻塞调用。在一个连接被接受或一个异常出现时,它将会返回。只有当一个远程设备使用一个UUID发送了一个连接请求,并且该UUID和正在监听的服务器socket注册的UUID相匹配时,一个连接才会被接受。成功后,accept() 将会返回一个已连接的 BluetoothSocket。
3.Unless you want to accept additional connections, call close(). 调用close(),除非你想要接受更多的连接。
This releases the server socket and all its resources, but does not close the connected BluetoothSocket that’s been returned by accept(). Unlike TCP/IP, RFCOMM only allows one connected client per channel at a time, so in most cases it makes sense to call close() on the BluetoothServerSocket immediately after accepting a connected socket.
这将释放服务器socket和它所有的资源,但是不会关闭 accept()返回的已连接的 BluetoothSocket。不同于TCP/IP,RFCOMM仅仅允许每一个通道上在某一时刻只有一个已连接的客户端,因此在大多数情况下在接受一个已连接的socket后,在BluetoothServerSocket上调用 close() 是非常必要的。
The accept() call should not be executed in the main activity UI thread because it is a blocking call and will prevent any other interaction with the application. It usually makes sense to do all work with a BluetoothServerSocket or BluetoothSocket in a new thread managed by your application. To abort a blocked call such as accept(), call close() on the BluetoothServerSocket(orBluetoothSocket) from another thread and the blocked call will immediately return. Note that all methods on a BluetoothServerSocket or BluetoothSocketare thread-safe.
accept() 不应该再主活动UI线程上执行,因为它是一个阻塞调用,并且将会阻止任何与应用的交互行为。它通常在你的应用管理的一个新的线程中使用一个BluetoothServerSocket 或 BluetoothSocket 来完成所有工作。为了中止一个阻塞调用,例如accept(),从你的其他线程里在BluetoothServerSocket (或 BluetoothSocket) 上调用 close() ,然后阻塞调用就会立即返回。注意在 BluetoothServerSocket 或 BluetoothSocket 上所有的方法都是线程安全的。
Example —— 例子
Here’s a simplified thread for the server component that accepts incoming connections:
下面是一个简单的线程,用于服务器端接受外来的连接:
[java] view plaincopyprint?
1. private class AcceptThread extends Thread {
2. private final BluetoothServerSocket mmServerSocket;
3.
4. public AcceptThread() {
5. // Use a temporary object that is later assigned to mmServerSocket,
6. // because mmServerSocket is final
7. BluetoothServerSocket tmp = null;
8. try {
9. // MY_UUID is the app’s UUID string, also used by the client code
10. tmp = mBluetoothAdapter.listenUsingRfcommWithServiceRecord(NAME, MY_UUID);
11. } catch (IOException e) { }
12. mmServerSocket = tmp;
13. }
14.
15. public void run() {
16. BluetoothSocket socket = null;
17. // Keep listening until exception occurs or a socket is returned
18. while (true) {
19. try {
20. socket = mmServerSocket.accept();
21. } catch (IOException e) {
22. break;
23. }
24. // If a connection was accepted
25. if (socket != null) {
26. // Do work to manage the connection (in a separate thread)
27. manageConnectedSocket(socket);
28. mmServerSocket.close();
29. break;
30. }
31. }
32. }
33.
34. /* Will cancel the listening socket, and cause the thread to finish /
35. public void cancel() {
36. try {
37. mmServerSocket.close();
38. } catch (IOException e) { }
39. }
40. }

In this example, only one incoming connection is desired, so as soon as a connection is accepted and the BluetoothSocket is acquired, the application sends the acquired BluetoothSocket to a separate thread, closes the BluetoothServerSocket and breaks the loop.
在这个例子里,只接受一个外来的连接,因此一旦一个连接被接受了并且需要一个BluetoothSocket ,应用将会发送需要的 BluetoothSocket 给另一个线程,关闭 BluetoothServerSocket 然后打破循环。
Note that when accept()returns the BluetoothSocket, the socket is already connected, so you should not call connect() (as you do from the client-side).
注意当accept()返回一个 BluetoothSocket是,该socket已经被连接了,因此你不应该调用connect()(正如你在客户端里所做的)。
manageConnectedSocket() is a fictional method in the application that will initiate the thread for transferring data, which is discussed in the section about Managing a Connection.
manageConnectedSocket()是一个虚构的方法,它将会初始化线程来传输数据,这在 Managing a Connection 中将会讨论。
You should usually close your BluetoothServerSocket as soon as you are done listening for incoming connections. In this example,close() is called as soon as the BluetoothSocket is acquired. You may also want to provide a public method in your thread that can close the private BluetoothSocket in the event that you need to stop listening on the server socket.
你通常应该关闭你的 BluetoothServerSocket,一旦你已经监听到了外来的连接。在这个例子里, 一旦得到了 BluetoothSocket 就会调用close()。你也可能想要在你的线程中提供一个公共的方法来关闭事件中私有的 BluetoothSocket ,以便你需要停止在服务器socket上监听。
Connecting as a client —— 作为客户端连接
In order to initiate a connection with a remote device (a device holding an open server socket), you must first obtain a BluetoothDevice object that represents the remote device. (Getting a BluetoothDevice is covered in the above section about Finding Devices.) You must then use the BluetoothDevice to acquire a BluetoothSocket and initiate the connection.
为了和一个远程设备(一个持有服务器socket的设备)初始化一个连接,你必须首先得到一个 BluetoothDevice 对象来表示这个远程设备。(上面的课程Finding Devices讲述了如何得到一个 BluetoothDevice )。然后你必须使用BluetoothDevice来得到一个 BluetoothSocket ,然后初始化该连接。
Here’s the basic procedure: 下面是基本的过程:
1.Using the BluetoothDevice, get a BluetoothSocket by calling createRfcommSocketToServiceRecord(UUID). 使用 BluetoothDevice,通过调用createRfcommSocketToServiceRecord(UUID)来得到一个 BluetoothSocket 。
This initializes a BluetoothSocket that will connect to the BluetoothDevice. The UUID passed here must match the UUID used by the server device when it opened its BluetoothServerSocket (withlistenUsingRfcommWithServiceRecord(String, UUID)). Using the same UUID is simply a matter of hard-coding the UUID string into your application and then referencing it from both the server and client code.
这将初始化一个BluetoothSocket,它连接到该BluetoothDevice。这里传递的UUID必须和服务器设备开启它的 BluetoothServerSocket时使用的UUID相匹配。
2.Initiate the connection by calling connect(). 通过调用connect()初始化一个连接。
Upon this call, the system will perform an SDP lookup on the remote device in order to match the UUID. If the lookup is successful and the remote device accepts the connection, it will share the RFCOMM channel to use during the connection and connect() will return. This method is a blocking call. If, for any reason, the connection fails or the connect() method times out (after about 12 seconds), then it will throw an exception.
执行这个调用时,系统将会在远程设备上执行一个SDP查找工作,来匹配UUID。如果查找成功,并且远程设备接受了连接,它将会在连接过程中分享RFCOMM通道,而 connect() 将会返回。这个方法是阻塞的。如果,处于任何原因,该连接失败了或者connect()超时了(大约12秒以后),那么它将会抛出一个异常。
Because connect() is a blocking call, this connection procedure should always be performed in a thread separate from the main activity thread.
因为connect()是一个阻塞调用,这个连接过程应该总是在一个单独的线程中执行。
Note: You should always ensure that the device is not performing device discovery when you callconnect(). If discovery is in progress, then the connection attempt will be significantly slowed and is more likely to fail.
注意:你应该总是确保在你调用connect()时设备没有执行设备查找工作。如果正在查找设备,那么连接尝试将会很大程度的减缓,并且很有可能会失败。
Example —— 例子
Here is a basic example of a thread that initiates a Bluetooth connection:
下面是初始化一个蓝牙连接的基本例子:
[java] view plaincopyprint?
1. private class ConnectThread extends Thread {
2. private final BluetoothSocket mmSocket;
3. private final BluetoothDevice mmDevice;
4.
5. public ConnectThread(BluetoothDevice device) {
6. // Use a temporary object that is later assigned to mmSocket,
7. // because mmSocket is final
8. BluetoothSocket tmp = null;
9. mmDevice = device;
10.
11. // Get a BluetoothSocket to connect with the given BluetoothDevice
12. try {
13. // MY_UUID is the app’s UUID string, also used by the server code
14. tmp = device.createRfcommSocketToServiceRecord(MY_UUID);
15. } catch (IOException e) { }
16. mmSocket = tmp;
17. }
18.
19. public void run() {
20. // Cancel discovery because it will slow down the connection
21. mBluetoothAdapter.cancelDiscovery();
22.
23. try {
24. // Connect the device through the socket. This will block
25. // until it succeeds or throws an exception
26. mmSocket.connect();
27. } catch (IOException connectException) {
28. // Unable to connect; close the socket and get out
29. try {
30. mmSocket.close();
31. } catch (IOException closeException) { }
32. return;
33. }
34.
35. // Do work to manage the connection (in a separate thread)
36. manageConnectedSocket(mmSocket);
37. }
38.
39. /* Will cancel an in-progress connection, and close the socket /
40. public void cancel() {
41. try {
42. mmSocket.close();
43. } catch (IOException e) { }
44. }
45. }

Notice that cancelDiscovery() is called before the connection is made. You should always do this before connecting and it is safe to call without actually checking whether it is running or not (but if you do want to check, call isDiscovering()).
manageConnectedSocket() is a fictional method in the application that will initiate the thread for transferring data, which is discussed in the section about Managing a Connection.
注意到在创建一个连接之前调用了cancelDiscovery()。你应该在连接前总是这样做,而不需要考虑是否真的有在执行查询任务(但是如果你想要检查,调用 isDiscovering())。manageConnectedSocket()是一个虚拟的方法,它将会初始化一个线程用于传输数据,这在Managing a Connection课程中将会讨论。
When you’re done with your BluetoothSocket, always call close() to clean up. Doing so will immediately close the connected socket and clean up all internal resources.
当你使用完你的 BluetoothSocket后,总是调用close()来清除资源。这样做将会立即关闭已连接的socket,然后清除所有的内部资源。
Managing a Connection —— 管理一个连接


When you have successfully connected two (or more) devices, each one will have a connected BluetoothSocket. This is where the fun begins because you can share data between devices. Using the BluetoothSocket, the general procedure to transfer arbitrary data is simple:
当你成功连接两个(或更多)设备后,每一个都将有一个已连接的 BluetoothSocket。这就是乐趣开始的地方,因为你可以在不同的设备之间共享数据了!使用 BluetoothSocket,常见的二进制数据传输是很简单的:
1. Get the InputStream and OutputStream that handle transmissions through the socket, via getInputStream()and getOutputStream(), respectively. 分别通过getInputStream() 和 getOutputStream()来得到 InputStream 和 OutputStream 来控制socket之间的传输。
2. Read and write data to the streams with read(byte[]) and write(byte[]). 使用 read(byte[]) 和 write(byte[])来向数据流中读取和写入数据。
That’s it. 就是这样啦!
There are, of course, implementation details to consider. First and foremost, you should use a dedicated thread for all stream reading and writing. This is important because both read(byte[]) and write(byte[]) methods are blocking calls. read(byte[]) will block until there is something to read from the stream. write(byte[]) does not usually block, but can block for flow control if the remote device is not calling read(byte[]) quickly enough and the intermediate buffers are full. So, your main loop in the thread should be dedicated to reading from the InputStream. A separate public method in the thread can be used to initiate writes to the OutputStream.
当然,实现的细节需要考虑。首先并且最重要的是,你应该为所有输入和输出的数据流使用一个专属的线程。这是十分重要的,因为read(byte[]) 和 write(byte[])方法都是阻塞调用。 read(byte[])将会发生阻塞知道送数据流中读取到了一些东西。 write(byte[])不经常发生阻塞,但是当远程设备没有足够迅速地调用 read(byte[])而中间缓冲区已经负载时可以阻塞。因此,你的线程中的主要循环应该是专门从InputStream中读取数据的。一个单独的公共方法可以被用于初始化向 OutputStream 中写入数据。
Example —— 例子
Here’s an example of how this might look:
它看起来可能像下面这个例子,:
[java] view plaincopyprint?
1.
2. private class ConnectedThread extends Thread {
3. private final BluetoothSocket mmSocket;
4. private final InputStream mmInStream;
5. private final OutputStream mmOutStream;
6.
7. public ConnectedThread(BluetoothSocket socket) {
8. mmSocket = socket;
9. InputStream tmpIn = null;
10. OutputStream tmpOut = null;
11.
12. // Get the input and output streams, using temp objects because
13. // member streams are final
14. try {
15. tmpIn = socket.getInputStream();
16. tmpOut = socket.getOutputStream();
17. } catch (IOException e) { }
18.
19. mmInStream = tmpIn;
20. mmOutStream = tmpOut;
21. }
22.
23. public void run() {
24. byte[] buffer = new byte[1024]; // buffer store for the stream
25. int bytes; // bytes returned from read()
26.
27. // Keep listening to the InputStream until an exception occurs
28. while (true) {
29. try {
30. // Read from the InputStream
31. bytes = mmInStream.read(buffer);
32. // Send the obtained bytes to the UI activity
33. mHandler.obtainMessage(MESSAGE_READ, bytes, -1, buffer)
34. .sendToTarget();
35. } catch (IOException e) {
36. break;
37. }
38. }
39. }
40.
41. /* Call this from the main activity to send data to the remote device */
42. public void write(byte[] bytes) {
43. try {
44. mmOutStream.write(bytes);
45. } catch (IOException e) { }
46. }
47.
48. /* Call this from the main activity to shutdown the connection */
49. public void cancel() {
50. try {
51. mmSocket.close();
52. } catch (IOException e) { }
53. }
54. }

The constructor acquires the necessary streams and once executed, the thread will wait for data to come through the InputStream. When read(byte[]) returns with bytes from the stream, the data is sent to the main activity using a member Handler from the parent class. Then it goes back and waits for more bytes from the stream.
构造器需要必须的数据流,并且一旦执行,线程将会等待InputStream 中来的数据。当 read(byte[]) 返回一些数值时,数据将会使用一个父类的一个成员变量句柄发送给主活动。然后它返回并继续等待更多的数据。
Sending outgoing data is as simple as calling the thread’s write() method from the main activity and passing in the bytes to be sent. This method then simply calls write(byte[]) to send the data to the remote device.
发送数据只需要在主活动中调用线程的 write()方法,并将需要发送数据传递给它即可。这个方法然后调用 write(byte[])来向远程设备发送数据。
The thread’s cancel() method is important so that the connection can be terminated at any time by closing the BluetoothSocket. This should always be called when you’re done using the Bluetooth connection.
线程的cancel() 方法是重要的,以便连接可以在任何时间被中断(通过关闭BluetoothSocket)。这个方法应该在你完成蓝牙连接后总是被调用。
For a demonstration of using the Bluetooth APIs, see the Bluetooth Chat sample app.
使用蓝牙APIs的更多例子,详见Bluetooth Chat sample app。
Working with Profiles —— 使用配置文件


Starting in Android 3.0, the Bluetooth API includes support for working with Bluetooth profiles. A Bluetooth profile is a wireless interface specification for Bluetooth-based communication between devices. An example is the Hands-Free profile. For a mobile phone to connect to a wireless headset, both devices must support the Hands-Free profile.
从Android 3.0开始,蓝牙API包含了对蓝牙配置文件的支持。一个蓝牙配置文件是一个对设备之间依赖蓝牙交互的无线接口定义。一个例子是Hands-Free 配置文件。对于一个和蓝牙耳机相连接的移动电话,两个设备都必须支持Hands-Free 配置文件。
You can implement the interface BluetoothProfile to write your own classes to support a particular Bluetooth profile. The Android Bluetooth API provides implementations for the following Bluetooth profiles:
你可以实现BluetoothProfile接口来定义你自己的类,以便支持特定的蓝牙配置文件。Android蓝牙API提供了以下蓝牙配置文件的实现:
• Headset. The Headset profile provides support for Bluetooth headsets to be used with mobile phones. Android provides the BluetoothHeadset class, which is a proxy for controlling the Bluetooth Headset Service via interprocess communication (IPC). This includes both Bluetooth Headset and Hands-Free (v1.5) profiles. The BluetoothHeadset class in cludes support for AT commands. For more discussion of this topic, see Vendor-specific AT commands
耳机:耳机配置文件提供了对于移动设备使用的蓝牙耳机的支持。Android提供了 BluetoothHeadset 类,它是一个通过进程间的交互(IPC)来控制蓝牙耳机服务的代理。它包含了 Bluetooth Headset 和 Hands-Free (v1.5) 配置文件。 BluetoothHeadset类包含了对AT命令的支持。更多的信息,详见 Vendor-specific AT commands 。
• A2DP. The Advanced Audio Distribution Profile (A2DP) profile defines how high quality audio can be streamed from one device to another over a Bluetooth connection. Android provides the BluetoothA2dp class, which is a proxy for controlling the Bluetooth A2DP Service via IPC.
A2DP:Advanced Audio Distribution Profile (A2DP)配置文件定义了高质量的音频可以如何通过蓝牙连接从一台设备上传输到另一台设备上。Android提供了 BluetoothA2dp 类,它是一个通过IPC管理蓝牙A2DP服务的代理。
• Health Device. Android 4.0 (API level 14) introduces support for the Bluetooth Health Device Profile (HDP). This lets you create applications that use Bluetooth to communicate with health devices that support Bluetooth, such as heart-rate monitors, blood meters, thermometers, scales, and so on. For a list of supported devices and their corresponding device data specialization codes, refer to Bluetooth Assigned Numbers at www.bluetooth.org. Note that these values are also referenced in the ISO/IEEE 11073-20601 [7] specification as MDC_DEV_SPEC_PROFILE_* in the Nomenclature Codes Annex. For more discussion of HDP, see Health Device Profile.
保健设备:Android 4.0(API level 14)介绍了对于蓝牙保健设备配置文件(HDP)。它允许你使用蓝牙和支持蓝牙的保健设备进行交互来创建应用,例如心跳监控器,血压,温度计,直尺等。参见Bluetooth Assigned Numbers atwww.bluetooth.org得到支持设备的列表和它们对应的设备数据定义代码。注意,这些值也可以在 ISO/IEEE 11073-20601 [7] 定义中查找。更多关于HDP的讨论,详见 Health Device Profile。
Here are the basic steps for working with a profile:
下面是操作一个配置文件的基本步骤:
1. Get the default adapter, as described in Setting Up Bluetooth. 得到默认的适配器,正如 Setting Up Bluetooth描述的那样。
2. Use getProfileProxy() to establish a connection to the profile proxy object associated with the profile. In the example below, the profile proxy object is an instance of BluetoothHeadset. 使用 getProfileProxy() 来建立一个和配置代理对象的连接。这下面的实例代码中,配置代理对象是一个 BluetoothHeadset的实例。
3. Set up a BluetoothProfile.ServiceListener. This listener notifies BluetoothProfile IPC clients when they have been connected to or disconnected from the service. 建立一个 BluetoothProfile.ServiceListener。这个监听器通知 BluetoothProfile IPC客户端,当它们已经和服务器连接或取消连接时。
4. In onServiceConnected(), get a handle to the profile proxy object. 在 onServiceConnected()里,得到一个配置代理对象的句柄。
5. Once you have the profile proxy object, you can use it to monitor the state of the connection and perform other operations that are relevant to that profile. 一旦你有了配置代理对象,你可以使用它来监视连接状态,并且执行和配置文件相关的其他操作。
For example, this code snippet shows how to connect to a BluetoothHeadset proxy object so that you can control the Headset profile:
例如,下面的代码片段展示了如何和一个BluetoothHeadset代理进行连接,以便你可以控制 Headset profile:
[java] view plaincopyprint?
1. BluetoothHeadset mBluetoothHeadset;
2.
3. // Get the default adapter
4. BluetoothAdapter mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
5.
6. // Establish connection to the proxy.
7. mBluetoothAdapter.getProfileProxy(context, mProfileListener, BluetoothProfile.HEADSET);
8.
9. private BluetoothProfile.ServiceListener mProfileListener = new BluetoothProfile.ServiceListener() {
10. public void onServiceConnected(int profile, BluetoothProfile proxy) {
11. if (profile == BluetoothProfile.HEADSET) {
12. mBluetoothHeadset = (BluetoothHeadset) proxy;
13. }
14. }
15. public void onServiceDisconnected(int profile) {
16. if (profile == BluetoothProfile.HEADSET) {
17. mBluetoothHeadset = null;
18. }
19. }
20. };
21.
22. // … call functions on mBluetoothHeadset
23.
24. // Close proxy connection after use.
25. mBluetoothAdapter.closeProfileProxy(mBluetoothHeadset);

Vendor-specific AT commands —— 厂商特定的AT命令
Starting in Android 3.0, applications can register to receive system broadcasts of pre-defined vendor-specific AT commands sent by headsets (such as a Plantronics +XEVENT command). For example, an application could receive broadcasts that indicate a connected device’s battery level and could notify the user or take other action as needed. Create a broadcast receiver for the ACTION_VENDOR_SPECIFIC_HEADSET_EVENT intent to handle vendor-specific AT commands for the headset.
从Android 3.0开始,应用可以注册来接收系统广播的、耳机发送的、预定义的、厂商特定的AT命令(例如一个Plantronics +XEVENT 命令)。例如,一个应用可以接收广播,来表明一个已连接的设备的电池等级,并且可以告知用于或者采取其他需要的动作。为 ACTION_VENDOR_SPECIFIC_HEADSET_EVENT Intent 创建一个广播接收器来为耳机控制厂商特定的AT命令。
Health Device Profile —— 保健设备配置文件
Android 4.0 (API level 14) introduces support for the Bluetooth Health Device Profile (HDP). This lets you create applications that use Bluetooth to communicate with health devices that support Bluetooth, such as heart-rate monitors, blood meters, thermometers, and scales. The Bluetooth Health API includes the classes BluetoothHealth,BluetoothHealthCallback, andBluetoothHealthAppConfiguration, which are described in The Basics.
Android 4.0(API level 14) 介绍了对蓝牙保健设备配置文件(HDP)的支持。它允许你使用蓝牙和支持蓝牙的保健设备进行交互来创建应用,例如心跳监控器,血压,温度计,直尺等。蓝牙保健设备API包含了BluetoothHealth,BluetoothHealthCallback 和 BluetoothHealthAppConfiguration 类,The Basics.描述了它们。
In using the Bluetooth Health API, it’s helpful to understand these key HDP concepts:
为了使用Bluetooth Health API,理解下面这些关键的HDP概念是有用的:

Concept Description
Source A role defined in HDP. A source is a health device that transmits medical data (weight scale, glucose meter, thermometer, etc.) to a smart device such as an Android phone or tablet.
Sink A role defined in HDP. In HDP, a sink is the smart device that receives the medical data. In an Android HDP application, the sink is represented by aBluetoothHealthAppConfigurationobject.

Registration Refers to registering a sink for a particular health device.
Connection Refers to opening a channel between a health device and a smart device such as an Android phone or tablet.
Creating an HDP Application —— 创建一个HDP应用
Here are the basic steps involved in creating an Android HDP application:
下面是创建一个Android HDP应用的基本步骤:
1.Get a reference to the BluetoothHealth proxy object. 得到BluetoothHealth代理对象的引用。Similar to regular headset and A2DP profile devices, you must call getProfileProxy()with a BluetoothProfile.ServiceListenerand the HEALTH profile type to establish a connection with the profile proxy object.
和通常的耳机和A2DP配置文件设备类似,你必须使用BluetoothProfile.ServiceListener和HEALTH 配置文件类型来调用getProfileProxy(),以建立一个和配置代理对象的连接。
2.Create a BluetoothHealthCallback and register an application configuration (BluetoothHealthAppConfiguration) that acts as a health sink. 创建一个BluetoothHealthCallback ,然后注册一个应用配置(BluetoothHealthAppConfiguration)来作为一个health sink。
3.Establish a connection to a health device. Some devices will initiate the connection. It is unnecessary to carry out this step for those devices. 建立一个和保健设备的连接,一些设备将会初始化连接。对于这些设备来说,这一步是不需要的。
4.When connected successfully to a health device, read/write to the health device using the file descriptor. 当成功建立和保健设备的连接后,使用 file descriptor来向保健设备读取/写入数据。
The received data needs to be interpreted using a health manager which implements the IEEE 11073-xxxxx specifications. 接收到的数据需要使用保健管理器(实现了 IEEE 11073-xxxxx定义)来解读。
5.When done, close the health channel and unregister the application. The channel also closes when there is extended inactivity. 完成以后,关闭保健通道,然后注销应用。通道也会在静止时关闭。
For a complete code sample that illustrates these steps, see Bluetooth HDP (Health Device Profile).
完整的实例这些步骤的代码,请见Bluetooth HDP (Health Device Profile)。

猎豹免费WiFi连接摄像头

通过猎豹免费wifi实现手机与摄像头的局域网连接

一.通过网线实现(wifi没有连接的情况下)
1.将电脑和摄像头同时使用网线连接路由器
2.将电脑中猎豹免费wifi打开,用手机连接wifi
3.在app中添加摄像头,并显示为在线状态(期间可能会出现多次离线并自动连线操作)
4.拔出摄像头网线,打开app中的设置,在“高级设置”中的“管理wifi网络”中选择 猎豹免费wifi,后点击“确定”,重新连接摄像头
5.断开电脑网络测试手机和摄像头是否连接

二.通过wifi实现
1.将手机使用wifi连接路由器,摄像头使用网线连接路由
2.在app中添加摄像头,并显示为在线状态
3.拔出摄像头网线,打开猎豹免费wifi,打开app中的设置,在“高级设置”中的“管 理wifi网络”中选择猎豹免费wifi,后点击“确定”,重新连接摄像头
4.将手机wifi网络设置为连接猎豹免费wifi的网络
5.断开电脑网络测试手机和摄像头是否连接

三.设置猎豹wifi名称为liusong,密码为12345678,摄像头即可连接wifi,手机连接wifi进行操作即可

摄像头主要方法注释

Init ();
调用init放的时候会通过jni调用.so文件中的方法去初始化IOTC(物联云联机平台)模块,同时初始化av通道的最大数量(av就是音频audio和视频video,用于信号的输入、输出),为连接做准备
New camera()?
初始化uid和密码(初始化uid和密码为空字符串) uid :20位的一个摄像头的唯一标示,密码 :连接摄像头的密码
registerIOTCListener()?
设置一个监听IOTC指令的回调监听,用于监听指令的返回信息
Connect(uid)?
将我们的uid赋值给camera中uid属性,然后开启一个线程去连接设备,再开启一个线程检验设备的状态
Start()
将通道号(手机和摄像头进行连接的一个通道的编号,必须保持一致,如果不一致会导致指令无法发送成功)、用户名、密码设置到av通道中,并开启一个线程启动设备
sendIOCtrl(channel,type,data[])
将指令添加到指令执行的队列当中去等待执行,类似MessageQueue
Type:AVIOCTRLDEFs.IOTYPE_USER_IPCAM_GETSUPPORTSTREAM_REQ
IOTYPE:IO指令的类型,user:用户,IPCAM :ip camera ,getsupportstream :获取支持的流信息 ,req :request请求
获取用户摄像头支持的流信息的请求指令类型
data[] :指令的参数
attachCamera(Camera,channel)
设置一个回调监听来获取返回的图片信息,同时开启一个渲染线程通过while循环使用Canvas videoCanvas = mSurHolder.lockCanvas();不停的进行图片渲染,
startShow();
开启一个线程接收视频信息,同时在开启一个线程进行视频解码操作

智能监控

1.手机是如何连接摄像头
第一次连接的时候摄像头需要通过网线和路由器连接,会给摄像头分配一个ip地址, 手机使用uid、密码通过ip地址进行连接,类似javaweb中的登陆访问操作
2.第一次怎么连接摄像头
首次连接摄像头需要通过网线去连接摄像头,然后手机通过wifi连接路由器,必须得 到同一个网段下,然后通过手机去添加摄像头,因为我们已经有uid和密码了,所以不用添加,这样就会在手机中存储下摄像头的相关 信息,添加成功,就可以把网线拔了,下次连接的时候会从手机中将摄像头的信息拿出 来,这样就可以实现使用手机在不同网段中连接摄像头了。
3.操作时阻塞现象
手机去连接摄像头的时候,是开了一个子线程通过jni调用.so文件中的方法去连接的,为了避免阻塞现象的发送,sdk中对所有的子线程都做了加锁操作,避免线程阻塞
4.摄像头内部如何实现
摄像头内部封装了一个微型liunx系统和一个微型的web服务器,我们发送指令是发送给web服务器,然后web服务器根据指令,通过一些算法去告诉摄像头执行什么操作,通过在返还给摄像头一些信息
5.移动操作中的指令参数:触控点、辅助设备
触控点:sdk中支持直接用手指在屏幕上滑动实现移动、放大等操作,所有会有一个触 控点的参数,辅助设备:摄像头支持外接麦克风和音响,所以会有一个辅助设备的参数 存在,一般触控点和辅助设备我们都有0表示就可以了,代表使用系统默认的参数

智能家居

智能家居:http://baike.baidu.com/link?url=9MUb6PpQrARSrf593qvutBm3_zZk00muKgIjyjuu8QPSBdsZ-76ZM9Y9WX6RDSvFgsKkKbsFpnXdLUcAnzJJCa

简介

智能家居是在互联网的影响之下物联化体现。智能家居通过物联网技术将家中的各种设备连接到一起,提供各种控制或者定时控制的功能和手段。与普通家居相比,智能家居不仅具有传统的家庭居住功能,同时还兼备建筑、网络通信、信息家电、设备自动化功能,提供全方位的信息交互功能。

发展背景

智能家居的概念起源很早,但是直到1984年美国联合科技公司(United Technologies Building System)将建筑设备信息化、整合化概念应用于美国康涅狄格州(Connecticut)哈特佛市(Hartford)的CityPlaceBuilding时,才出现了首栋的“智能型建筑”,从此揭开了全世界争相建造智能家居派的序幕。智能家居从开始到现在主要经历了四个阶段

家庭自动化
通过一个中央微处理机接受相关电子产品(检测环境变化)的信息,在发送给其他产品
家庭网络
家庭网络是在家庭范围内将家电(安全系统、照明系统)和广域网相连接的一种新技术。
网络家电
利用数字技术、网络技术及智能控制技术设计改进的新型家电产品,比如网络空调。
信息家电
能够通过网络系统交互信息的家电产品。
##国内现状与发展
智能家居在我国还是一个新生产业,处于一个导入期与成长期的临界点,我国政府在2013年8月14日发表了关于促进信息消费扩大内需的若干意见,大力发展宽带业务,也为智能家居打下了坚实的基础,加之智能家居市场消费观念还未形成,市场的消费潜力必然是巨大的,产业前景光明。

萌芽期/智能小区期(1994年-1999年)
概念熟悉、产品认知的阶段,还没有出现专业的智能家居生产厂商。
开创期(2000年-2005年)
成立了五十多家智能家居研发生产企业,没有进入国内市场。
徘徊期(2006-2010年)
过分夸大智能家居的功能,行业用户、媒体开始质疑智能家居的实际效果 ,国内企业转型,国外企业进入(罗格朗、霍尼韦尔)。
融合演变期(2011-2020年)
进入20 14年以来,各大厂商已开始密集布局智能家居,经过一年多产业 磨合,2015年合作企业已普遍进入到出成果时刻,智能家居新品已经层出 不穷的出现了。

智能家电

智能灯泡
智能摄像头
智能空调
智能家电:http://www.af360.com/html/2013/07/23/201307231351598765.shtml

目标

智能监控
通过wifi或者2G、3G、4G网络将手机和智能摄像头连 接起来,实现实时的监控,上下左右移动摄像头等操 作。
智能灯泡
通过蓝牙将手机和智能灯泡连接起来,实现电灯 的打开、关闭、点动等操作。

智能监控

什么是智能监控
智能家居的一部分,主要是通过网络摄像头实现实时监 控,主要包含移动侦测报警、防盗拍照、移动录像等功能和手 段。
应用场景
主要应用于企业办公室、大型超市、大型工厂机房、老人儿童看场所、交通监管、家庭防盗等各方面领域。
优缺点
优点:性价比高、扩展性好、可靠性高
缺点:对网络带宽要求比较高,网络差的情况下界面显示 有延时情况
小蚁智能摄像机:http://www.mi.com/xiaoyi/
360小水滴:http://www.qikoo.com/preorder/jia

基本组成

1.网络摄像头
2.pc或者App
我们今天开发的是包含连接网络摄像头、上下左右移动网络摄 像头功能的简单Demo。

基本流程

这里写图片描述
UID:4V7R8AKW39U6DLZF111A,购买摄像头时厂商提供的摄像头的20位是唯一标示
密码:admin,购买摄像头时厂商初始化好的密码

关键步骤

1.导入jar包和.so文件
这里写图片描述
jar包中所用到的类及参数
Camera:封装了摄像头参数和执行操作的类
例如:
DEFAULT_AV_CHANNEL 默认的渠道号 表示app和摄像头 连接的路线
CONNECTION_STATE_CONNECTING 连接状态中正在连接 的类型
Connect () 连接
Disconnect() 断开连接
registerIOTCListener() 注册iotc指令返回信息监听
startshow() 显示画面
Stopshow () 停止显示画面
sendIOCtrl() 发送指令
IOTC : 物联云联机平台
IRegisterIOTCListener:指令返回信息的监听
例如:
receiveChannelInfo(); 获取渠道返回的信息
receiveIOCtrlData(); 获取操作指令返回的信息

Monitor :监控画面控件继承SurfaceView,初始化一些参数和方法
例如:
DEFAULT_MAX_ZOOM_SCALE 默认最大焦距
PTZ_SPEED 移动速度
PTZ_DELAY 移动延时
FLING_MIN_DISTANCE 转动的最小距离
FLING_MIN_VELOCITY 移动的速率
setMaxZoom() 设置最大的焦距
attachCamera (Camera camera,int channel) 绑定摄像头
deattachCamera() 解除绑定
AVIOCTRLDEFS:封装了各种指令类型以及封装了各种指令类
型参数的内部类
例如:
IOTYPE_USER_IPCAM_GETSUPPORTSTREAM_REQ 获 取流的指令
IOTYPE_USER_IPCAM_PTZ_COMMAND 移动指令
AVIOCTRL_PTZ_UP 上移动指令
内部类:SMsgAVIoctrl…. 封装指令参数内部类
2.连接摄像头
1).显示控件
com.tutk.IOTC.Monitor
2).初始化和连接
初始化
Camera.init();
连接
camera.connect(uid);
camera.start(Camera.DEFAULT_AV_CHANNEL, name, passwrod);
3).注册监听和发送获取连接状态指令
添加权限:

    注册监听
                camera.registerIOTCListener(this);
    发送指令
               camera.sendIOCtrl(Camera.DEFAULT_AV_CHANNEL,     AVIOCTRLDEFs.IOTYPE_USER_IPCAM_GETSUPPORTSTREAM_REQ,SMsgAVIoctrlGetSupportStreamReq.parseContent());

注释:
Camera.DEFAULT_AV_CHANNEL :默认渠道号,默认为0
AVIOCTRLDEFs.IOTYPE_USER_IPCAM_GETSUPPORTSTREAM_REQ :指令类型,表示获取支持流的信息
SMsgAVIoctrlGetSupportStreamReq.parseContent() : 相应指令的参数
3.获取指令信息及连接状态
获取指令信息的方法
@Override
public void receiveChannelInfo(Camera camera, int channel, int resultCode) {
Message message = Message.obtain();
message.what = resultCode;
handler.sendMessage(message);
}
连接状态类型
Camera.CONNECTION_STATE_CONNECTING 连接中
Camera.CONNECTION_STATE_CONNECTED 已连接
Camera.CONNECTION_STATE_CONNECT_FAILED 连接失败
Camera.CONNECTION_STATE_DISCONNECTED 断开连接
Camera.CONNECTION_STATE_TIMEOUT 连接超时
Camera.CONNECTION_STATE_UNKNOWN_DEVICE 没有连接到设备
Camera.CONNECTION_STATE_WRONG_PASSWORD 密码错误
4.显示监控画面

    //判断摄像头是否还在连接状态
    if (camera != null && camera.isSessionConnected() &&            camera.isChannelConnected(Camera.DEFAULT_AV_CHANNEL)) {
        //设置最大焦距
        cameraplay.setMaxZoom(1.0f);
        //绑定摄像头对象
        cameraplay.attachCamera(camera,                         Camera.DEFAULT_AV_CHANNEL);
        //显示
        camera.startShow(Camera.DEFAULT_AV_CHANNEL);
    }

5.上下左右移动指令
PTZ : 在安防监控应用中是 Pan/Tilt/Zoom 的简写,代表云台全方位(左右/上下)移动及镜头变倍、变焦控制

    //移动指令
    camera.sendIOCtrl(Camera.DEFAULT_AV_CHANNEL,                                                    AVIOCTRLDEFs.IOTYPE_USER_IPCAM_PTZ_COMMAND,
    SMsgAVIoctrlPtzCmd.parseContent(
    (byte)AVIOCTRLDEFs.AVIOCTRL_PTZ_UP,
    (byte)0, (byte)0, (byte)0, (byte)0,
    (byte)Camera.DEFAULT_AV_CHANNEL));

参数

AVIOCTRLDEFs.IOTYPE_USER_IPCAM_PTZ_COMMAND       移动指令类型
SMsgAVIoctrlPtzCmd.parseContent(
    (byte)AVIOCTRLDEFs.AVIOCTRL_PTZ_UP, 
    (byte)0, (byte)0, (byte)0, (byte)0, 
    (byte)Camera.DEFAULT_AV_CHANNEL) 指令参数(控制类型,渠道号)              
AVIOCTRLDEFs.AVIOCTRL_PTZ_UP        上移
AVIOCTRLDEFs.AVIOCTRL_PTZ_LEFT   左移
AVIOCTRLDEFs.AVIOCTRL_PTZ_RIGHT     右移
AVIOCTRLDEFs.AVIOCTRL_PTZ_DOWN  下移

6.断开连接
1).解除绑定
cameraplay.deattachCamera(); 解除绑定
camera.stopShow(Camera.DEFAULT_AV_CHANNEL); 结束显示

    2).断开连接
    camera.stop(Camera.DEFAULT_AV_CHANNEL); 停止渠道使用
    camera.disconnect();            断开连接    
    camera.unregisterIOTCListener(this);        注销监听

蓝牙灯泡

iMagic智能蓝牙灯泡:http://www.imagicsmart.com/index.php/Home/Products/index.html
Revogi蓝牙灯泡:http://www.revogi.cn/index.php?route=product/category&path=10_2

什么是蓝牙灯泡
智能家居的一部分,将蓝牙模块和灯泡相结合,通过手机和蓝牙模块进行通讯,控制电灯中的电压板,从而控制灯泡的打开、关闭、点动等操作。

应用场景
住家、卧室、客厅、厨房、浴厕,办公室、会议室、地下 室、汗蒸房、美容院、医院、疗养院等等地方。

优缺点
优点:方便、快捷、能耗低、寿命长、扩展性好
缺点:受距离限制(5-10米),不稳定
基本组成
灯泡
蓝牙模块
手机
目标:通过手机控制灯泡的打开、关闭、点动操作
startDiscovery()和cancelDiscovery()必须在工程中注册一个蓝牙广播接受者

获取本地蓝牙适配器
BluetoothAdapter mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();

打开/关闭手机蓝牙
打开手机蓝牙
mBluetoothAdapter .enable();
关闭手机蓝牙
mBluetoothAdapter.disable();

扫描/取消蓝牙设备
扫描蓝牙设备
mBluetoothAdapter.startDiscovery();
取消扫描蓝牙设备,减少资源的消耗
mBluetoothAdapter.cancelDiscovery();
关键步骤
添加蓝牙广播接受者

IntentFilter filter = new IntentFilter();
// 开始扫描的广播
filter.addAction(BluetoothAdapter.ACTION_DISCOVERY_STARTED);    
// 扫描完成的广播
filter.addAction(BluetoothAdapter.ACTION_DISCOVERY_FINISHED);   
// 发现一个可用的设备的广播
filter.addAction(BluetoothDevice.ACTION_FOUND);
mBluetoothReceiver = new BluetoothReceiver();
//注册监听
registerReceiver(mBluetoothReceiver, filter);

蓝牙广播接受者

class BluetoothReceiver extends BroadcastReceiver {

    @Override
    public void onReceive(Context context, Intent intent) {
        //获取蓝牙设备
    }
}

连接设备
注意:蓝牙2.1版本不用使用匹配的UUID也可以,但不保证准确性,蓝牙4.0版本需要使用匹配的UUID,为了兼容性都使用匹配的UUID
UUID: 00001101-0000-1000-8000-00805f9b34fb
匹配密码:1518(高版本为了低功耗不用密码验证)

Looper :是用来封装消息循环和消息队列的一个类,用于在android线程中进行消息处理
Looper.prepare() :在一个线程中运行一个消息循环,通过perpare开启消息循环
Looper.loop() :循环处理消息,直到循环结束为止

public void connectServer(final BluetoothDevice device) {
    new Thread(new Runnable(){
        @Override
        public void run() {
        try {
                    System.out.println(randomUUID.toString());
                    BluetoothSocket clientSocket = device.
            createRfcommSocketToServiceRecord(
        UUID.fromString("00001101-0000-1000-8000-00805f9b34fb"));
                    clientSocket.connect();
                    out = clientSocket.getOutputStream();
                    System.out.println("连接成功");
                    } catch (IOException e) {
                   e.printStackTrace();
        }
        }}).start();
    }

打开灯泡
开灯:b[2] = (byte) 0x10;
b[3] = (byte) 0x10;
关闭:b[2] = (byte) 0x11;
b[3] = (byte) 0x11;
点动:b[2] = (byte) 0x19;
b[3] = (byte) 0x19;

private void openLight() {
if(out == null) return;
try {
// 向服务端写数据
byte[] b = new byte[5];
b[0] = (byte) 0x01;
b[1] = (byte) 0x99;
b[2] = (byte) 0x10;
b[3] = (byte) 0x10;
b[4] = (byte) 0x99;
out.write(b);
out.flush();
} catch (IOException e) {
Toast.makeText(this, “打开失败”, 0).show();
e.printStackTrace();
}
}

注销广播接受者
@Override
protected void onDestroy() {
super.onDestroy();
unregisterReceiver(mBluetoothReceiver);
}
智能家居简介
智能插座
360小雨滴
小米小蚁
这个阶段就比较牛B了,利用数字技术、网络技术。。。,说白了就是在第二步的基础上,第二步已经实现了家庭网络,也就是说设备已经可以和广域网进行连接了,接下来就是利用数字技术、网络技术。。。对我们的家电设备实现控制,比如说通过网络可以控制电视机、摄像头、冰箱等一些家庭设备,但是这个阶段的时候呢还是有一些局限性的,比如有一个智能空调,我用手机给这个空调发送一个指令,让其打开,那这个指令发送出去之后,空调收没收到我们是不知道,也就是说空调不会给我们反馈,如果空调收到了指令,则打开空调,如果没收到就不会打开。即使收到了指令,它也不会反馈给我们说空调已打开,你只能通过眼睛去看空调是否打开。因为有这样的局限性,所以第四阶段就出来了。
其实就是在网络家电的基础上,实现信息的交互,比如说,我还是用手机给空调发送一个打开的指令,如果打开成功了,空调会返回给我们一个说操作成功,也就是可以互相交换信息了,
可以看一下现在的市场,前几年是没什么人知道智能家居这个概念的,从去年,小米和360就开始推这一块了,因为比较有眼界的一些公司会发现这一块,发现这一块的潜力,所以智能家居目前来说潜力是非常巨大的,因为还处于成长期,所以现在去找智能家居的工作还是比较好找的,因为现在很多产品都处于研发阶段,你一进去就是研发,等你过一段时间之后你就变成大牛了,等你再出来的时候你就是前辈。
中国的玩完了,国外的开始进入中国市场来抢占这个市场,因为中国对于全界面来说都是一个非常大的一个市场,所以他们开始进来抢占市场。
这是一些比较常见的智能家居产品,如果你去一些高档小区的话,你会发现里面有很多的智能产品,像一些明星家里就会有很多的智能家居的产品,
智能监控简介
缺点:比如在地铁上或在地下室等一些网络信号不好的地方,你在查看这个网络摄像头的时候可能会看到画面延迟非常的严重,比如这个画面发生之后你5秒种之后才看到。就是带宽要求比较高,因为画面的传输是比较耗流量的。
今天给大家介绍的这个摄像头是一个比较出名的摄像头。
蓝牙灯泡简介
这个灯光做成这样子,是因为它在里面封装了一个蓝牙模块,当搜上插座的时候蓝牙就通电了,其后在里面还有电源开关,受蓝牙的控制。其实这个跟我们的这个原理也是一样的,只不过是我们的蓝牙模块和电灯泡分开了,把蓝牙和电源开关放到一个独立的装置里面了。
智能家居是在互联网影响之下物联化的体现。智能家居通过物联网技术将家中的各种设备(如音视频设备、照明系统、窗帘控制、空调控制、安防系统、数字影院系统、影音服务器、影柜系统、网络家电等)连接到一起,提供家电控制、照明控制、电话远程控制、室内外遥控、防盗报警、环境监测、暖通控制、红外转发以及可编程定时控制等多种功能和手段。与普通家居相比,智能家居不仅具有传统的居住功能,兼备建筑、网络通信、信息家电、设备自动化,提供全方位的信息交互功能,甚至为各种能源费用节约资金。
智能家居的概念起源很早,但一直未有具体的建筑案例出现,直到1984年美国联合科技公司(United Technologies Building System)将建筑设备信息化、整合化概念应用于美国康涅狄格州(Connecticut)哈特佛市(Hartford)的CityPlaceBuilding时,才出现了首栋的“智能型建筑”,从此揭开了全世界争相建造智能家居派的序幕。
一、家庭自动化(Home Automation)
家庭自动化系指利用微处理电子技术,来集成或控制家中的电子电器产品或系统,例如:照明灯、咖啡炉、电脑设备、保安系统、暖气及冷气系统、视讯及音响系统等。家庭自动化系统主要是以一个中央微处理机(Central Processor Unit,CPU)接收来自相关电子电器产品(外界环境因素的变化,如太阳初升或西落等所造成的光线变化等)的讯息后,再以既定的程序发送适当的信息给其它电子电器产品。中央微处理机必须透过许多界面来控制家中的电器产品,这些界面可以是键盘,也可以是触摸式荧幕、按钮、电脑、电话机、遥控器等;消费者可发送信号至中央微处理机,或接收来自中央微处理机的讯号。
家庭自动化是智能家居的一个重要系统,在智能家居刚出现时,家庭自动化甚至就等同于智能家居,今天它仍是智能家居的核心之一,但随着网络技术有智能家居的普遍应用,网络家电/信息家电的成熟,家庭自动化的许多产品功能将融入到这些新产品中去,从而使单纯的家庭自动化产品在系统设计中越来越少,其核心地位也将被家庭网络/家庭信息系统所代替。它将作为家庭网络中的控制网络部份在智能家居中发挥作用。
最有名的家庭自动化系统为美国的X-10。

二、家庭网络(Home networking)
首先大家要把这个家庭网络和纯粹的“家庭局域网”分开来,我们在本书中还会提到“家庭局域网/家庭内部网络”这一名称,它是指连接家庭里的PC、各种外设及与因特网互联的网络系统,它只是家庭网络的一个组成部份。家庭网络是在家庭范围内(可扩展至邻居,小区)将PC、家电、安全系统、照明系统和广域网相连接的一种新技术。 当前在家庭网络所采用的连接技术可以分为“有线”和“无线”两大类。有线方案主要包括:双绞线或同轴电缆连接、电话线连接、电力线连接等;无线方案主要包括:红外线连接、无线电连接、基于RF技术的连接和基于PC的无线连接等。
家庭网络相比起传统的办公网络来说,加入了很多家庭应用产品和系统,如家电设备、照明系统,因此相应技术标准也错综复杂,这里面也牵涉太多知名的网络厂家和家电厂家的利益,我们在智能家居技术一章中将对各种技术标准作详细介绍。家庭网络的发展趋势是将智能家居中其它系统融合进去,最终一统天下。
三、网络家电
网络家电是将普通家用电器利用数字技术、网络技术及智能控制技术设计改进的新型家电产品。网络家电可以实现互联组成一个家庭内部网络,同时这个家庭网络又可以与外部互联网相连接。可见,网络家电技术包括两个层面:首先就是家电之间的互连问题,也就是使不同家电之间能够互相识别,协同工作。第二个层面是解决家电网络与外部网络的通信,使家庭中的家电网络真正成为外部网络的延伸。
要实现家电间互联和信息交换,就需要解决:1. 描述家电的工作特性的产品模型,使得数据的交换具有特定含义;2. 信息传输的网络媒介。在解决网络媒介这一难点中,可选择的方案有:电力线、无线射频、双绞线、同轴电缆、红外线、光纤。认为比较可行的网络家电包括网络冰箱、网络空调、网络洗衣机、网络热水器、网络微波炉、网络炊具等。网络家电未来的方向也是充分融合到家庭网络中去。
四、信息家电(3C 或者说IA)
信息家电应该是一种价格低廉、操作简便、 实用性强、带有PC主要功能的家电产品。利用电脑、电信和电子技术与传统家电(包括白色家电:电冰箱、洗衣机、微波炉等和黑色家电:电视机、录像机、音响、VCD、DVD等)相结合的创新产品, 是为数字化与网络技术更广泛地深入家庭生活而设计的新型家用电器,信息家电包括PC、机顶盒、HPC、DVD、超级VCD、无线数据通信设备、视频游戏设备、WEBTV、INTERNET电话等等,所有能够通过网络系统交互信息的家电产品,都可以称之为信息家电。音频、视频和通信设备是信息家电的主要组成部分。另一方面, 在传统家电的基础上,将信息技术融入传统的家电当中,使其功能更加强大,使用更加简单、方便和实用,为家庭生活创造更高品质的生活环境。比如模拟电视发展成数字电视,VCD变成DVD,电冰箱、洗衣机、微波炉等也将会变成数字化、网络化、智能化的信息家电。
从广义的分类来看,信息家电产品实际上包含了网络家电产品,但如果从狭义的定义来界定,我们可以这样做一简单分类:信息家电更多的指带有嵌入式处理器的小型家用(个人用)信息设备,它的基本特征是与网络(主要指互联网)相连而有一些具体功能,可以是成套产品,也可以是一个辅助配件。而网络家电则指一个具有网络操作功能的家电类产品,这种家电可以理解是我们原来普通家电产品的升级。
信息家电由嵌入式处理器、相关支撑硬件(如显示卡、存储介质、IC卡或信用卡等读取设备)、嵌入式操作系统以及应用层的软件包组成。信息家电把PC的某些功能分解出来,设计成应用性更强、更家电化的产品,使普通居民步人信息时代的步伐更为快速,是具备高性能、低价格、易操作特点的lnternet工具。信息家电的出现将推动家庭网络市场的兴起,同时家庭网络市场的发展又反过来推动信息家电的普及和深人应用。
现状与发展
国内现状
智能家居作为一个新生产业,处于一个导入期与成长期的临界点,市场消费观念还未形成,但随着智能家居市场推广普及的进一步落实,培育起消费者的使用习惯,智能家居市场的消费潜力必然是巨大的,产业前景光明。 正因为如此,国内优秀的智能家居生产企业愈来愈重视对行业市场的研究,特别是对企业发展环境和客户需求趋势变化的深入研究,一大批国内优秀的智能家居品牌迅速崛起,逐渐成为智能家居产业中的翘楚! 智能家居至今在中国已经历了近12年的发展,从人们最初的梦想,到今天真实的走进我们的生活,经历了一个艰难的过程。 [1]
智能家居在中国的发展经历的四个阶段,分别是萌芽期、开创期、徘徊期、融合演变期。
萌芽期/智能小区期(1994年-1999年)
  这是智能家居在中国的第一个发展阶段,整个行业还处在一个概念熟悉、产品认知的阶段,这时没有出现专业的智能家居生产厂商,只有深圳有一两家从事美国X-10智能家居代理销售的公司从事进口零售业务,产品多销售给居住国内的欧美用户。
开创期(2000年-2005年)
  国内先后成立了五十多家智能家居研发生产企业,主要集中在深圳、上海、天津、北京、杭州、厦门等地。智能家居的市场营销、技术培训体系逐渐完善起来,此阶段,国外智能家居产品基本没有进入国内市场。
徘徊期(2006-2010年)
  2005年以后,由于上一阶段智能家居企业的野蛮成长和恶性竞争,给智能家居行业带来了极大的负面影响:包括过分夸大智能家居的功能而实际上无法达到这个效果、厂商只顾发展代理商却忽略了对代理商的培训和扶持导致代理商经营困难、产品不稳定导致用户高投诉率。行业用户、媒体开始质疑智能家居的实际效果,由原来的鼓吹变得谨慎,市场销售也几年出来增长减缓甚至部分区域出现了销售额下降的现象。2005年-2007年,大约有20多家智能家居生产企业退出了这一市场,各地代理商结业转行的也不在少数。许多坚持下来的智能家居企业,在这几年也经历了缩减规模的痛苦。正在这一时期,国外的智能家居品牌却暗中布局进入了中国市场,而活跃在市场上的国外主要智能家居品牌都是这一时期进入中国市场的,如罗格朗、霍尼韦尔、施耐德、Control4等。国内部分存活下来的企业也逐渐找到自己的发展方向,例如天津瑞朗,青岛爱尔豪斯,海尔,科道等,用X10,深圳索科特做了空调远程控制,成为工业智控的厂家。
融合演变期(2011-2020年)
  进入2011年以来,市场明显看到了增长的势头,而且大的行业背景是房地产受到调控。智能家居的放量增长说明智能家居行业进入了一个拐点,由徘徊期进入了新一轮的融合演变期。
  接下来的三到五年,智能家居一方面进入一个相对快速的发展阶段,另一方面协议与技术标准开始主动互通和融合,行业并购现象开始出来甚至成为主流。
  接下来的五到十年,将是智能家居行业发展极为快速,但也是最不可琢磨的时期,由于住宅家庭成为各行业争夺的焦点市场,智能家居作为一个承接平台成为各方力量首先争夺的目标。谁能最终胜出,我们可以作种种分析,但最终结果,也许只有到时才知。但不管如何发展,这个阶段国内将诞生多家年销售额上百亿元的智能家居企业。
5、爆发期
进入到2014年以来,各大厂商已开始密集布局智能家居,尽管从产业来看,业内还没有特别成功的案例显现,这预示着行业发展仍处于探索阶段,但越来越多的厂商开始介入和参与已使得外界意识到,智能家居未来已不可逆转。
目前来看,智能家居经过一年多产业磨合,已正处爆发前夜。业内人士认为,2015年随着合作企业已普遍进入到出成果时刻,智能家居新品将会层出不穷,业内涌现的新案例也会越来越多。
国内相关政策
截止2013年,全球范围内信息技术创新不断加快,信息领域新产品、新服务、新业态大量涌现,不断激发新的消费需求,成为日益活跃的消费热点。我国市场规模庞大,正处于居民消费升级和信息化、工业化、城镇化、农业现代化加快融合发展的阶段,信息消费具有良好发展基础和巨大发展潜力。我国政府为了推动信息化、智能化城市发展也在2013年8月14日发表了关于促进信息消费扩大内需的若干意见,大力测发展宽带普及、宽带提速,加快推动信息消费持续增长,这都为智能家居、物联网行业的发展打下了坚实的基础。
政策摘要:增强信息产品供给能力
这里写图片描述

这里写图片描述

猜你喜欢

转载自blog.csdn.net/A94721990/article/details/81108654