android蓝牙文件传输的实现

来源:互联网 发布:python中的appends 编辑:程序博客网 时间:2024/06/15 16:39

一、android设备蓝牙通信介绍
1.1配对
两个蓝牙设备在建立通信连接之前需要先彼此感知到对方的存在,这一过程就是配对。使用android蓝牙api进行配对分为以下几步:
1、设备A与B均开始蓝牙模块;
2、设备A声明自己可以被发现,默认保持该状态为120秒,也可以自定义一个值;
3、设备B扫描周围是否有可被发现的蓝牙设备;
4、当搜索到设备A后,向设备A发起配对请求;
5、设备A响应设备B的配对请求,响应信息包含设备名,类,唯一的MAC地址。
通常设备在进行过一次配对以后,会记住配对信息,以备以后连接通信时使用。使用已知的远程设备的MAC地址,连接可以在任何时候初始化而不必先完成搜索(当然这是假设远程设备是在可连接的空间范围内)。配对意思是两个设备相互意识到对方的存在,共享一个用来鉴别身份的链路键(link-key),能够与对方建立一个加密的连接。
1.2通信
在配对成功以后,两个设备就可以通过已经获取的配对信息来建立连接,连接建立以后,两个设备就可以共享一个RFCOMM信道,相互传输数据。目前android蓝牙api要求设备在建立RFCOMM信道前必须配对(配对是在使用Bluetooth API初始化一个加密连接时自动完成的)。
如果要连接两个设备,其中一个必须充当服务器,通过持有一个打开的BluetoothServerSocket对象。服务器socket的作用是侦听进来的连接,如果一个连接被接受,提供一个连接好的BluetoothSocket对象。从BluetoothServerSocket获取到BluetoothSocket对象之后,BluetoothServerSocket就可以(也应该)丢弃了,除非你还要用它来接收更多的连接。另一设备为了实现与远程设备的连接,必须首先获得一个代表远程设备BluetoothDevice对象。然后使用BluetoothDevice对象来获取一个BluetoothSocket来实现来接。
如果已经连接了两个设备,他们都已经拥有各自的连接好的BluetoothSocket对象。那就是一个有趣的开始,因为你可以在设备间共享数据了。使用BluetoothSocket,传输任何数据通常来说都很容易了:
1.通过socket获取输入输出流来处理传输(分别使用getInputStream()和getOutputStream())。
2.用read(byte[])和write(byte[])来实现读写。
1.3以上两步的流程图

二、蓝牙通信传输文件的实现
2.1 权限
要使用android提供的蓝牙api,至少需要获取以下2个权限:
BLUETOOTH:用来授权任何Bluetooth通信,如请求连接,接受连接,传输数据等。
BLUETOOTH_ADMIN:用来授权初始化设备搜索或操作Bluetooth设置。
注意:需要BLUETOOTH_ADMIN权限的场合,BLUETOOTH权限也是必需的。
要使用android提供的文件读写api,需要获取以下权限:
WRITE_EXTERNAL_STORAGE:读写设备外置存储(通常是sd卡)。
需要在manifest文件中声明上述权限,示例如下:
<manifest ... >
...
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
 <uses-permission android:name="android.permission.BLUETOOTH" />
 <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
  ...
</manifest>

2.2 关键代码
 private final Handler mHandler = new Handler() {
  @Override
  public void handleMessage(Message msg) {
   switch (msg.what) {
   case MESSAGE_STATE_CHANGE:
    if (D)
     Log.i(TAG, "MESSAGE_STATE_CHANGE: " + msg.arg1);
    switch (msg.arg1) {
    caseFileTransferService.STATE_CONNECTED:
     mTitle.setText(R.string.title_connected_to);
     mTitle.append(mConnectedDeviceName);
     break;
    caseFileTransferService.STATE_CONNECTING:
     mTitle.setText(R.string.title_connecting);
     break;
    caseFileTransferService.STATE_LISTEN:
    caseFileTransferService.STATE_NONE:
     mTitle.setText(R.string.title_not_connected);
     break;
    }
    break;
   case MESSAGE_FILE_TRANSFER_BEGIN:
    fileSize = msg.arg1;
    sendBeginAt = (Long) msg.obj;
    mProgressDialog
      .setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
    mProgressDialog.setMax(fileSize);
    mProgressDialog.show();
    sendTotalBytes = 0;
    break;
   case MESSAGE_FILE_TRANSFER_ING:
    intsendBytes = msg.arg1;
    sendTotalBytes += sendBytes;
    mProgressDialog.setProgress(sendTotalBytes);
    break;
   case MESSAGE_FILE_TRANSFER_END:
    mProgressDialog.dismiss();
    sendEndAt = (Long) msg.obj;

    long duration = sendEndAt - sendBeginAt;
    Log.e(TAG, "=======" + duration);
    longdataSize = fileSize / 1024;
    float speed = ((float) fileSize / 1024)
      / ((float) duration / 1000);
    Toast.makeText(
      getApplicationContext(),
      "(" + String.valueOf(dataSize) + "Kb/"
        + String.valueOf(duration / 1000) + "s):"
        + String.valueOf(speed) + "Kb/s",
      Toast.LENGTH_SHORT).show();
    break;
   case MESSAGE_FILE_PROFILE_SEND:
    Toast.makeText(
      getApplicationContext(),
      "Send file " + selectFilePath + "\nto "
        + selectBluetoothDevice, Toast.LENGTH_SHORT)
      .show();
    break;
   case MESSAGE_FILE_PROFILE_RECEIVED:
    fileSize = msg.arg1;
    fileName = (String) msg.obj;
    Toast.makeText(
      getApplicationContext(),
      "Receive file name:" + fileName
        + "\n        file size:" + fileSize,
      Toast.LENGTH_SHORT).show();
    break;
   case MESSAGE_FILE_RECEIVE_ING:
    receiveTotalBytes = msg.arg1;

    if (receiveTotalBytes == 0) {
     mProgressDialog
       .setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
     mProgressDialog.setMax(fileSize);
     mProgressDialog.show();
    }
    mProgressDialog.setProgress(receiveTotalBytes);
    if (fileSize == receiveTotalBytes) {
     mProgressDialog.dismiss();
     FileTransferService.mReceiving = false;
    }
    break;
   case MESSAGE_DEVICE_NAME:
    // save the connected device's name
    mConnectedDeviceName = msg.getData().getString(DEVICE_NAME);
    Toast.makeText(getApplicationContext(),
      "Connected to " + mConnectedDeviceName,
      Toast.LENGTH_SHORT).show();
    break;
   case MESSAGE_TOAST:
    Toast.makeText(getApplicationContext(),
      msg.getData().getString(TOAST), Toast.LENGTH_SHORT)
      .show();
    break;
   }
  }
 };

 

原创粉丝点击