精华内容
下载资源
问答
  • 蓝牙串口助手源码

    2016-07-19 09:36:09
    蓝牙串口助手源码,本人hc-05可使用
  • 蓝牙串口助手、2.0蓝牙串口通信、安卓手机源码,支持发送字符
  • 【实例简介】蓝牙串口助手(Android Studio源码)【实例截图】http://a.app.qq.com/o/simple.jsp?pkgname=com.example.bluetoothassist软件外观和下载位置【核心代码】package com.example.main;import android....

    【实例简介】蓝牙串口助手(Android Studio源码)

    【实例截图】http://a.app.qq.com/o/simple.jsp?pkgname=com.example.bluetoothassist

    软件外观和下载位置

    db9c0156b2cf8cd1f40af69996fe351f.png

    【核心代码】

    package com.example.main;

    import android.Manifest;

    import android.content.pm.PackageManager;

    import android.renderscript.Byte3;

    import android.support.v4.app.ActivityCompat;

    import android.util.Log;

    import java.io.File;

    import java.io.FileInputStream;

    import java.io.FileOutputStream;

    import java.io.IOException;

    import java.io.OutputStreamWriter;

    import java.nio.ByteBuffer;

    import android.app.Activity;

    import android.bluetooth.BluetoothAdapter;

    import android.bluetooth.BluetoothDevice;

    import android.content.Context;

    import android.content.Intent;

    import android.os.Bundle;

    import android.os.Environment;

    import android.os.Handler;

    import android.os.Message;

    import android.text.Layout;

    import android.view.Menu;

    import android.view.MenuItem;

    import android.view.View;

    import android.view.View.OnClickListener;

    import android.view.View.OnLongClickListener;

    import android.view.View.OnTouchListener;

    import android.widget.Button;

    import android.widget.CheckBox;

    import android.widget.CompoundButton;

    import android.widget.CompoundButton.OnCheckedChangeListener;

    import com.example.bluetooth.BluetoothService;

    import com.example.bluetooth.DeviceListActivity;

    import com.example.bluetoothassist.R;

    import android.widget.EditText;

    import android.widget.RadioButton;

    import android.widget.RadioGroup;

    import android.widget.ScrollView;

    import android.widget.TextView;

    import android.widget.Toast;

    public class MainActivity extends Activity {

    private static final String TAG = "MainActivity";

    private static final boolean DEBUG = false;

    public static final int REC_DATA = 2;

    public static final int CONNECTED_DEVICE_NAME = 4;

    public static final int BT_TOAST = 5;

    public static final int MAIN_TOAST = 6;

    // 标志字符串常量

    public static final String DEVICE_NAME = "device name";

    public static final String TOAST = "toast";

    // 意图请求码

    private static final int REQUEST_CONNECT_DEVICE = 1;

    private static final int REQUEST_ENABLE_BT = 2;

    private TextView RecDataView;

    private Button ClearWindow,pauseButton,sendButton;

    private Button Button01,Button02,Button03,Button04,Button05;

    private StringBuffer Str2Send1=new StringBuffer("1"),

    Str2Send2=new StringBuffer("2"),

    Str2Send3=new StringBuffer("3"),

    Str2Send4=new StringBuffer("4"),

    Str2Send5=new StringBuffer("5");

    private RadioGroup rgRec,rgSend;

    private EditText sendContent,period;

    private CheckBox setPeriod;

    // 已连接设备的名字

    private String mConnectedDeviceName = null;

    //蓝牙连接服务对象

    private BluetoothAdapter mBluetoothAdapter = null;

    private BluetoothService mConnectService = null;

    static boolean isHEXsend=false,isHEXrec=false;

    private static final int REQUEST_EXTERNAL_STORAGE = 1;

    private static String[] PERMISSIONS_STORAGE = {

    Manifest.permission.READ_EXTERNAL_STORAGE,

    Manifest.permission.WRITE_EXTERNAL_STORAGE

    };

    public static void verifyStoragePermissions(Activity activity) {

    // Check if we have write permission

    int permission = ActivityCompat.checkSelfPermission(activity, Manifest.permission.WRITE_EXTERNAL_STORAGE);

    if (permission != PackageManager.PERMISSION_GRANTED) {

    // We don't have permission so prompt the user

    ActivityCompat.requestPermissions(

    activity,

    PERMISSIONS_STORAGE,

    REQUEST_EXTERNAL_STORAGE

    );

    }

    }

    private void saveConfig(){

    String filename=Environment.getExternalStorageDirectory().getPath() "/蓝牙串口助手.config";

    File f=new File(filename);

    FileOutputStream fOut;

    try {

    f.createNewFile();

    fOut = new FileOutputStream(f);

    fOut.write(Button01.getText().toString().getBytes());

    fOut.write('\0');

    fOut.write(Str2Send1.toString().getBytes());

    fOut.write('\0');

    fOut.write(Button02.getText().toString().getBytes());

    fOut.write('\0');

    fOut.write(Str2Send2.toString().getBytes());

    fOut.write('\0');

    fOut.write(Button03.getText().toString().getBytes());

    fOut.write('\0');

    fOut.write(Str2Send3.toString().getBytes());

    fOut.write('\0');

    fOut.write(Button04.getText().toString().getBytes());

    fOut.write('\0');

    fOut.write(Str2Send4.toString().getBytes());

    fOut.write('\0');

    fOut.write(Button05.getText().toString().getBytes());

    fOut.write('\0');

    fOut.write(Str2Send5.toString().getBytes());

    fOut.write('\0');

    fOut.flush();

    fOut.close();

    } catch (IOException e) {

    e.printStackTrace();

    }

    }

    private void restoreConfig(){

    String filename=Environment.getExternalStorageDirectory().getPath() "/蓝牙串口助手.config";

    File f=new File(filename);

    FileInputStream fIn;

    try {

    fIn = new FileInputStream(f);

    byte[] bs=new byte[1024];

    fIn.read(bs);

    String s=new String(bs);

    String[]ss=s.split("\0");

    Button01.setText(ss[0]);

    Str2Send1.append(ss[1]);

    Button02.setText(ss[2]);

    Str2Send2.append(ss[3]);

    Button03.setText(ss[4]);

    Str2Send3.append(ss[5]);

    Button04.setText(ss[6]);

    Str2Send4.append(ss[7]);

    Button05.setText(ss[8]);

    Str2Send5.append(ss[9]);

    fIn.close();

    } catch (IOException e) {

    e.printStackTrace();

    }

    }

    @Override

    public void onCreate(Bundle savedInstanceState) {

    super.onCreate(savedInstanceState);

    setContentView(R.layout.activity_main);

    Button01 = (Button) findViewById(R.id.Button01);

    Button02 = (Button) findViewById(R.id.Button02);

    Button03 = (Button) findViewById(R.id.Button03);

    Button04 = (Button) findViewById(R.id.Button04);

    Button05 = (Button) findViewById(R.id.Button05);

    RecDataView = (TextView) findViewById(R.id.Rec_Text_show);

    ClearWindow = (Button) findViewById(R.id.ClearWindow);

    pauseButton = (Button) findViewById(R.id.pauseButton);

    sendContent = (EditText) findViewById(R.id.sendContent);

    period = (EditText) findViewById(R.id.period);

    sendButton = (Button) findViewById(R.id.sendButton);

    setPeriod = (CheckBox) findViewById(R.id.setPeriod);

    rgRec=(RadioGroup) findViewById(R.id.rgRec);

    rgSend =(RadioGroup) findViewById(R.id.rgSend);

    setupListener();

    mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();

    if (mBluetoothAdapter == null) {

    Toast.makeText(this, "Bluetooth is not available", Toast.LENGTH_LONG).show();

    finish();

    return;

    }//savaData();

    this.setTitle("蓝牙串口助手(未连接)");

    init_hex_string_table();

    verifyStoragePermissions(this);

    restoreConfig();

    }

    @Override

    public void onStart() {

    super.onStart();

    if(DEBUG) Log.i(TAG, " ON START ");

    // 查看请求打开蓝牙

    if (!mBluetoothAdapter.isEnabled()) {

    Intent enableIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);

    startActivityForResult(enableIntent,REQUEST_ENABLE_BT);

    } //否则创建蓝牙连接服务对象

    else if (mConnectService == null){

    mConnectService = new BluetoothService(mHandler);

    }

    }

    @Override

    public synchronized void onResume() {

    super.onResume();

    if (mConnectService != null) {

    if (mConnectService.getState() == BluetoothService.IDLE) {

    //监听其他蓝牙主设备

    mConnectService.acceptWait();

    }

    }

    }

    /**

    * 自定义按键长按监听方法,进入定义按键的对话框

    */

    private OnLongClickListener ButtonLongClickListener=new OnLongClickListener(){

    @Override

    public boolean onLongClick(View v) {

    switch(v.getId()){

    case R.id.Button01:new defineButtonDialog(MainActivity.this,Button01,Str2Send1).show();break;

    case R.id.Button02:new defineButtonDialog(MainActivity.this,Button02,Str2Send2).show();break;

    case R.id.Button03:new defineButtonDialog(MainActivity.this,Button03,Str2Send3).show();break;

    case R.id.Button04:new defineButtonDialog(MainActivity.this,Button04,Str2Send4).show();break;

    case R.id.Button05:new defineButtonDialog(MainActivity.this,Button05,Str2Send5).show();break;

    }

    return false;

    }

    };

    /**

    * 所有按键的监听方法,

    * 分别根据按键ID处理其相应的事件

    */

    private OnClickListener ButtonClickListener=new OnClickListener() {

    public void onClick(View v) {

    switch(v.getId()){

    case R.id.Button01:sendMessage(Button01,Str2Send1.toString());break;

    case R.id.Button02:sendMessage(Button02,Str2Send2.toString());break;

    case R.id.Button03:sendMessage(Button03,Str2Send3.toString());break;

    case R.id.Button04:sendMessage(Button04,Str2Send4.toString());break;

    case R.id.Button05:sendMessage(Button05,Str2Send5.toString());break;

    case R.id.ClearWindow:RecDataView.setText("");break;

    case R.id.sendButton:sendMessage(sendButton,sendContent.getText().toString());break;

    case R.id.pauseButton:if(BluetoothService.allowRec)pauseButton.setText("继续");

    else pauseButton.setText("暂停");

    BluetoothService.allowRec=!BluetoothService.allowRec;break;

    }

    }

    };

    /**

    * 定时选择框组件监听方法

    * 开启相应的时间任务

    */

    private OnCheckedChangeListener checkBoxListener=new OnCheckedChangeListener(){

    @Override

    public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {

    if(isChecked){

    String s=period.getText().toString();

    //新建时间任务

    if(s.length()!=0){

    timeTask=new timeThread(Integer.valueOf(s));

    }

    else timeTask=new timeThread(1000);

    //启动定时任务

    timeTask.start();

    }

    else timeTask.interrupt();

    }

    };

    /**

    * RadioGroup的监听方法

    * 根据RadioButton的ID处理相应事件

    */

    private RadioGroup.OnCheckedChangeListener rgListener=new RadioGroup.OnCheckedChangeListener(){

    @Override

    public void onCheckedChanged(RadioGroup group, int checkedId) {

    switch(checkedId){

    case R.id.receiveASCII:isHEXrec=false;break;

    case R.id.receiveHEX:isHEXrec=true;break;

    case R.id.sendASCII:isHEXsend=false;break;

    case R.id.sendHEX:isHEXsend=true;break;

    }

    }};

    /**

    * 设置自定按键及其他固定按键的监听方法

    */

    private void setupListener() {

    Button01.setOnClickListener(ButtonClickListener);

    Button02.setOnClickListener(ButtonClickListener);

    Button03.setOnClickListener(ButtonClickListener);

    Button04.setOnClickListener(ButtonClickListener);

    Button05.setOnClickListener(ButtonClickListener);

    Button01.setOnLongClickListener(ButtonLongClickListener);

    Button02.setOnLongClickListener(ButtonLongClickListener);

    Button03.setOnLongClickListener(ButtonLongClickListener);

    Button04.setOnLongClickListener(ButtonLongClickListener);

    Button05.setOnLongClickListener(ButtonLongClickListener);

    ClearWindow.setOnClickListener(ButtonClickListener);

    pauseButton.setOnClickListener(ButtonClickListener);

    sendButton.setOnClickListener(ButtonClickListener);

    setPeriod.setOnCheckedChangeListener(checkBoxListener);

    rgRec.setOnCheckedChangeListener(rgListener);

    rgSend .setOnCheckedChangeListener(rgListener);

    }

    @Override

    public synchronized void onPause() {

    super.onPause();

    if(DEBUG) Log.i(TAG, "onPause");

    }

    @Override

    public void onStop() {

    super.onStop();

    if(DEBUG) Log.i(TAG, "onStop");

    }

    @Override

    public void onDestroy() {

    super.onDestroy();

    if(DEBUG) Log.e(TAG, "onDestroy");

    // Stop the Bluetooth connection

    if (mConnectService != null) mConnectService.cancelAllBtThread();

    if(timeTask!=null)timeTask.interrupt();

    saveConfig();

    android.os.Process.killProcess(android.os.Process.myPid());

    }

    /**

    * 按键触发发送字符串

    * @param Str2Send 欲发送的字符串.

    */

    private void sendMessage(Button callButton,String Str2Send) {

    if(callButton!=null){

    if(Str2Send.length()==0){

    if(callButton!=sendButton){

    Toast.makeText(this,"请先长按配置按键", Toast.LENGTH_SHORT).show();

    }

    return;

    }

    if (mConnectService==null||mConnectService.getState()!=BluetoothService.CONNECTED) {

    Toast.makeText(this,"未连接到任何蓝牙设备", Toast.LENGTH_SHORT).show();

    return;

    }

    }else if(Str2Send==null||mConnectService==null||Str2Send.equals(""))return;

    byte[] bs;

    if (!isHEXsend) {

    bs = Str2Send.getBytes();

    mConnectService.write(bs);

    }else{

    for(char c:Str2Send.toCharArray()){

    if(!((c>='0'&&c<='9')||(c>='a'&&c<='f')||(c>='A'&&c<='F')||c==' ')){

    Toast.makeText(this,"发送内容含非法字符", Toast.LENGTH_SHORT).show();

    return;

    }

    }

    String[] ss=Str2Send.split(" ");

    bs=new byte[1];

    for(String s:ss){

    if(s.length()!=0){

    bs[0]=(byte)(int)Integer.valueOf(s, 16);

    mConnectService.write(bs);

    }

    }

    }

    }

    timeThread timeTask=null;

    private class timeThread extends Thread{

    private int sleeptime;

    timeThread(int militime){

    super();

    sleeptime=militime;

    }

    /*byte[] buffer={'a','v','c','d','f','a','v','c','d','f','a','v','c',

    'a','v','c','d','f','a','v','c','d','f','a','v','c',

    'a','v','c','d','f','a','v','c','d','f','a','v','c',

    'a','v','c','d','f','a','v','c','d','f','a','v','c'

    ,'d','f','a','v','c','d','f','a','v','c','d','f','\n'};*/

    @Override

    public void run(){

    while(!isInterrupted()){

    if(DEBUG)Log.i("myDebug", "timeThread start");

    sendMessage(null,sendContent.getText().toString());

    //mHandler.obtainMessage(MainActivity.REC_DATA,buffer.length,-1,buffer).sendToTarget();

    try {

    Thread.sleep(sleeptime);

    } catch (InterruptedException e) {

    e.printStackTrace();

    break;

    }

    }

    if(DEBUG)Log.i("myDebug", "timeThread end");

    }

    }

    String[] hex_string_table=new String[256];

    private void init_hex_string_table(){

    for(int i=0;i<256;i ){

    if(i<16){

    hex_string_table[i]=" 0" Integer.toHexString(i).toUpperCase();

    }else{

    hex_string_table[i]=" " Integer.toHexString(i).toUpperCase();

    }

    }

    }

    private int align_num=0;//对齐字节数

    // 用于从线程获取信息的Handler对象

    private final Handler mHandler = new Handler(){

    StringBuffer sb=new StringBuffer();

    byte[] bs;

    float sWidth;

    int b,i,lineWidth=0,align_i=0;

    @Override

    public void handleMessage(Message msg) {

    switch (msg.what) {

    case REC_DATA:

    sb.setLength(0);

    if(isHEXrec){

    bs=(byte[])msg.obj;

    for(i=0;i

    b=(bs[i]&0xff);

    sb.append(hex_string_table[b]);

    sWidth=RecDataView.getPaint().measureText(hex_string_table[b]);

    lineWidth =sWidth;

    if(lineWidth>RecDataView.getWidth()||(align_num!=0&&align_num==align_i)){

    lineWidth=(int)sWidth;align_i=0;

    sb.insert(sb.length()-3, '\n');

    }

    align_i ;

    }

    }else {

    bs=(byte[])msg.obj;

    char[] c=new char[msg.arg1];

    for(i=0;i

    c[i]=(char)(bs[i]&0xff);

    sWidth=RecDataView.getPaint().measureText(c,i,1);

    lineWidth =sWidth;

    if(lineWidth>RecDataView.getWidth()){

    lineWidth=(int)sWidth;

    sb.append('\n');

    }

    if(c[i]=='\n')lineWidth=0;

    sb.append(c[i]);

    }

    }

    RecDataView.append(sb);

    break;

    case CONNECTED_DEVICE_NAME:

    // 提示已连接设备名

    mConnectedDeviceName = msg.getData().getString(DEVICE_NAME);

    Toast.makeText(getApplicationContext(), "已连接到"

    mConnectedDeviceName, Toast.LENGTH_SHORT).show();

    MainActivity.this.setTitle("蓝牙串口助手(已连接)");

    break;

    case BT_TOAST:

    if(mConnectedDeviceName!=null)

    Toast.makeText(getApplicationContext(), "与" mConnectedDeviceName

    msg.getData().getString(TOAST),Toast.LENGTH_SHORT).show();

    else Toast.makeText(getApplicationContext(), "与" target_device_name

    msg.getData().getString(TOAST),Toast.LENGTH_SHORT).show();

    MainActivity.this.setTitle("蓝牙串口助手(未连接)");

    mConnectedDeviceName=null;

    break;

    case MAIN_TOAST:

    Toast.makeText(getApplicationContext(),"",Toast.LENGTH_SHORT).show();

    break;

    }

    }

    };

    private String target_device_name=null;

    @Override

    public void onActivityResult(int requestCode, int resultCode, Intent data) {

    Log.e(TAG, "onActivityResult");

    switch (requestCode) {

    case REQUEST_CONNECT_DEVICE:

    if (resultCode == Activity.RESULT_OK) {

    // 提取蓝牙地址数据

    String address = data.getExtras().getString(DeviceListActivity.DEVICE_ADDRESS);

    // 获取设备

    BluetoothDevice device = mBluetoothAdapter.getRemoteDevice(address);

    target_device_name=device.getName();

    if(target_device_name.equals(mConnectedDeviceName)){

    Toast.makeText(this, "已连接" mConnectedDeviceName, Toast.LENGTH_SHORT).show();

    return;

    }

    // 提示正在连接设备

    Toast.makeText(this, "正在连接" target_device_name, Toast.LENGTH_SHORT).show();

    // 连接设备

    mConnectService.connect(device);

    }

    break;

    case REQUEST_ENABLE_BT:

    // 请求打开蓝牙被用户拒绝时提示

    if (resultCode == Activity.RESULT_OK) {

    mConnectService = new BluetoothService(mHandler);

    } else {

    Toast.makeText(this,"拒绝打开蓝牙", Toast.LENGTH_SHORT).show();

    //finish();

    }

    }

    }

    @Override

    public boolean onCreateOptionsMenu(Menu menu) {

    getMenuInflater().inflate(R.menu.main, menu);

    return true;

    }

    @Override

    public boolean onOptionsItemSelected(MenuItem item) {

    switch (item.getItemId()) {

    case R.id.Connect:

    // 查看请求打开蓝牙

    if (!mBluetoothAdapter.isEnabled()) {

    Intent enableIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);

    startActivityForResult(enableIntent,REQUEST_ENABLE_BT);

    return true;

    }

    // 打开设备蓝牙设备列表活动

    Intent serverIntent = new Intent(this, DeviceListActivity.class);

    startActivityForResult(serverIntent, REQUEST_CONNECT_DEVICE);

    return true;

    case R.id.discoverable:

    // 请求打开本地蓝牙可见性

    if (mBluetoothAdapter.getScanMode() !=

    BluetoothAdapter.SCAN_MODE_CONNECTABLE_DISCOVERABLE) {

    Intent discoverableIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE);

    discoverableIntent.putExtra(BluetoothAdapter.EXTRA_DISCOVERABLE_DURATION, 300);

    startActivity(discoverableIntent);

    }

    return true;

    case R.id.RecAlign:

    new setAlignDialog(this,new setAlignDialog.DialogCallback(){

    @Override

    public void DialogReturn(int i) {

    align_num=i;

    }

    }).show();

    }

    return false;

    }

    }

    展开全文
  • 蓝牙串口助手(Android Studio源码

    热门讨论 2018-03-06 12:58:34
    本软件为蓝牙串口通信工具,支持蓝牙从模式和主模式,可进行蓝牙串口通信测试。能连接单片机及PC的蓝牙串口。 可用于硬件的串口蓝牙模块(TTL)通信。 软件功能: 1、搜索蓝牙设备 2、接收显示数据与发送数据 3、可...
  • 蓝牙串口APP源码

    2018-10-06 21:17:25
    应移动互联实验需求,实现手机与蓝牙之间的通信,即单片机检测的温度通过蓝牙模块传送到手机上。特地在网上找了蓝牙连接程序,下载有七八个就发现这个还行,经过修改效果不错。
  • 本软件为蓝牙串口通信工具,支持蓝牙从模式和主模式,可进行蓝牙串口通信测试。能连接单片机及PC的蓝牙串口。 可用于硬件的串口蓝牙模块(TTL)通信。 软件功能: 1、搜索蓝牙设备 2、接收显示数据与发送数据 3、可...
  •  由于地面站APP少了个测试工具,就先花点时间来整理一下历时3周开发无人机蓝牙图传串口助手(地面端、飞机端)两个小APP程序,回顾下这三周来,真的是受益匪浅了,从未知到已知怎么和硬件打交道究竟是怎...

        这个APP是在2016年11月底-12月初开发的,现在想把这项目开源共享给有需要的开发者参考!源码有需要请留言联系本人,由于本项目属于公司项目,不能完全开源出来,只提供部分技术支持!请谅解!

        由于地面站APP少了个测试工具,就先花点时间来整理一下历时3周开发无人机蓝牙图传串口助手(地面端、飞机端)两个小APP程序,回顾下这三周来,真的是受益匪浅了,从未知到已知怎么和硬件打交道究竟是怎么和硬件通信的,终于解开我进入智能硬件行业以来的一大疑惑,以前非常好奇到底是怎么和硬件通信的,开发完后,也就一句话:原来如此,也不过这么回事而已者!

           先上点图看看效果

           








    非常简洁吧这界面,当初还没开始开发的时候已经和主要负责人确定过界面怎么设计了,他们说对界面没什么要求能把功能实现可以用就行,加上目前也没有UI设计师,只能全用原生态的自带图标了,最终开发出来的效果也就这样了
           接着还是先说说具体实现了什么功能吧:
           地面端的主要实现了:
           1、读取配置参数
           2、高级配置设置(系统保存配置、系统复位)
           3、参数配置修改(频率、带宽、密钥)
           4、恢复MMC出厂设置
           5、连接、清屏
           地面端技术总结:
           别看地面端的功能点少,却是这两个程序中花的时间最长的,中间卡顿原因主要有:                                                                          
           a、刚动手不知道界面怎么设计好两天内重建了好几套框架,中间出现很多连接蓝牙不了的问题                                                                                      b、可以连上蓝牙设备了,不知道为什么可以发数据却接不了数据,最终是因为单片机程序那边是以ASCII码“123和125”为判断条件就是大括号“{}”而我这边一般都以ASCII码“0x0A和0x0D”为判断条件就是换行,后面改回和单片机程序那边一样就可以收发数据了                                                                    c、不太懂各进制、ASCII码的转换和意思                                                                                                                                                                      d、解析数据也耗了不少时间才弄明白,郝**同事和我说这收发的“命令格式:  {+操作码+RAM地址+<操作数>+校验码+} ” 还有返回格式足足讲了好几天我才领悟到其中的奥秘,才懂何为操作码、何为RAM地址、何为校验码、这些都怎么来的、操作数又是读才有还是发数据才有的,收回来的一大串数据又是怎么解析和校验的,以及刘*同事给的一些写程序的逻辑思路,很快这程序就慢慢的通了,后面也做的越来越顺了
           飞机端的主要实现了:
            1、一键配置
            2、系统控制(复位系统、保存参数、恢复系统、关闭RF输出、打开RF输出、关闭DA输出)
            3、串口设置(查看波特率、设置保存波特率)
            4、带宽设置(查看带宽、设置保存带宽)
            5、中心频率(查看中心频率、设置保存中心频率)
            6、密钥(查看密钥、设置保存密钥)
            7、调制方式(查看调制方式、设置保存调制方式)
            8、视频模式
            9.功率衰减(查看功率衰减、设置保存功率衰减)
            10、FEC码率(查看FEC码率、设置保存FEC码率)
            11、连接、清屏
            飞机端技术总结:
             飞机端的功能点比地面端多了好几倍,但是也比地面端完成的快,不用多说,因为技术都是差不多,基本上都是复制粘贴的,主要都花在调试接口解析数据上
          总的来说,通过这次开发让我学到很多很珍贵的经验!
    下载链接:http://fir.im/mmcfigurepass
    展开全文
  • android BluetoothSPP,有兴趣的可以下载研究,不是程序是源码哦,刚下载,还没测试,先分享 android BluetoothSPP,有兴趣的可以下载研究,不是程序是源码哦,刚下载,还没测试,先分享
  • 买别人的代码,这里分享。已经编译生成apk。可以改源码供自己需要。
  • 如果你觉得这份android蓝牙串口助手源码非常有价值,只是我半个多月做出来的,希望对你有用,献给哪些为了蓝牙串口默默牺牲青春的IT战友们,如果你们能把它做得更完美,欢迎把源码发给我,可以直接运行。
  • 【原创】BLE蓝牙串口助手

    热门讨论 2015-04-30 14:17:21
    一个方便可用的蓝牙BLE串口调试工具源码,包含了BLE设备的查找、连接、读与写。大部分代码都是网上找来的,结合自己的学习及需要改写的。初学者可以看看。
  • 改好的android源代码 蓝牙串口助手.rar,太多无法一一验证是否可用,程序如果跑不起来需要自调,部分代码功能进行参考学习。
  • 本软件作为HC05/06系列蓝牙串口的调试助手,方便嵌入式工程师、电子工程师调试蓝牙串口模块。HC05/06是经典的2.0串口蓝牙模块。
  • 蓝牙串口保存文件APP

    2015-11-26 00:13:22
    很多蓝牙串口软件源码都没有保存文件的功能,开发出这个功能以供大家学习交流
  • 蓝牙串口通信手机APP(适用于HC05,HC06等蓝牙模块),亲测有效,打开自动连接,无需配置蓝牙。
  • 一、环境介绍 ...设计本软件的目的是作为HC05/06系列蓝牙串口的调试助手,方便嵌入式工程师、电子工程师调试蓝牙串口模块,HC05/06是经典的2.0串口蓝牙模块。 三、软件核心源码 #include "mainwin..

    一、环境介绍

    QT版本: 5.12.6

    编译环境: win10 64位

    目标系统: Android

    完整工程源码下载地址(包含APK文件):  https://download.csdn.net/download/xiaolong1126626497/19051787

    想学习QT的Android环境搭建看这里(win10版本): https://blog.csdn.net/xiaolong1126626497/article/details/117254453

                                                              (ubuntu版本): https://blog.csdn.net/xiaolong1126626497/article/details/117256660

    想学习QT入门到精通编程的看这里:https://blog.csdn.net/xiaolong1126626497/article/details/116485145

    二、功能介绍

    设计本软件的目的是作为HC05/06系列蓝牙串口的调试助手,方便嵌入式工程师、电子工程师调试蓝牙串口模块,HC05/06是经典的2.0串口蓝牙模块。

    三、软件核心源码

    #include "mainwindow.h"
    #include "ui_mainwindow.h"
    
    
    /*
     * 设置QT界面的样式
    */
    void MainWindow::SetStyle(const QString &qssFile) {
        QFile file(qssFile);
        if (file.open(QFile::ReadOnly)) {
            QString qss = QLatin1String(file.readAll());
            qApp->setStyleSheet(qss);
            QString PaletteColor = qss.mid(20,7);
            qApp->setPalette(QPalette(QColor(PaletteColor)));
            file.close();
        }
        else
        {
            qApp->setStyleSheet("");
        }
    }
    
    
    static const QLatin1String serviceUuid("00001101-0000-1000-8000-00805F9B34FB");
    //这个字符串里面的内容就是串口模式的Uuid
    
    MainWindow::MainWindow(QWidget *parent) :
        QMainWindow(parent),
        ui(new Ui::MainWindow)
    {
        ui->setupUi(this);
    
        this->SetStyle(":/qss/blue.css");     //设置样式表
        this->setWindowTitle("HC05蓝牙调试助手"); //设置标题
        this->setWindowIcon(QIcon(":/wbyq.ico")); //设置图标
    
        /*1. 实例化蓝牙相关的对象*/
        discoveryAgent = new QBluetoothDeviceDiscoveryAgent();
        localDevice = new QBluetoothLocalDevice();
        socket = new QBluetoothSocket(QBluetoothServiceInfo::RfcommProtocol);
        //RfcommProtocol表示该服务使用RFCOMM套接字协议。RfcommProtocol属于模拟RS232模式,就叫串口模式
    
        /*2. 关联蓝牙设备相关的信号*/
        /*2.1 关联发现设备的槽函数,当扫描发现周围的蓝牙设备时,会发出deviceDiscovered信号*/
        connect(discoveryAgent,
                SIGNAL(deviceDiscovered(QBluetoothDeviceInfo)),
                this,
                SLOT(addBlueToothDevicesToList(QBluetoothDeviceInfo))
                );
    
        //蓝牙有数据可读
        connect(socket,
                SIGNAL(readyRead()),
                this,
                SLOT(readBluetoothDataEvent())
                );
    
        //蓝牙连接建立成功
        connect(socket,
                SIGNAL(connected()),
                this,
                SLOT(bluetoothConnectedEvent())
                );
    
        //蓝牙断开连接
        connect(socket,
                SIGNAL(disconnected()),
                this,
                SLOT(bluetoothDisconnectedEvent())
                );
        //蓝牙连接错误
        connect(socket, static_cast<void(QBluetoothSocket::*)(QBluetoothSocket::SocketError)>(&QBluetoothSocket::error),
              [=](QBluetoothSocket::SocketError error)
        {
                ui->plainTextEdit_BluetoothInfiShow->insertPlainText(socket->errorString()); //显示错误信息
    
                if(QBluetoothSocket::UnknownSocketError ==error)
                {
                   ui->plainTextEdit_BluetoothInfiShow->insertPlainText("位置错误\n"); //显示错误信息
                }
    
                if(QBluetoothSocket::NoSocketError ==error)
                {
                    ui->plainTextEdit_BluetoothInfiShow->insertPlainText(" 没有错误 用于测试\n"); //显示错误信息
                }
    
                if(QBluetoothSocket::HostNotFoundError ==error)
                {
                      ui->plainTextEdit_BluetoothInfiShow->insertPlainText("找不到远程主机\n"); //显示错误信息
                }
    
                if(QBluetoothSocket::ServiceNotFoundError ==error)
                {
                         ui->plainTextEdit_BluetoothInfiShow->insertPlainText(" 无法在远程主机上找到服务UUID\n"); //显示错误信息
                }
    
                if(QBluetoothSocket::NetworkError ==error)
                {
                     ui->plainTextEdit_BluetoothInfiShow->insertPlainText("尝试从套接字读取或写入返回错误\n"); //显示错误信息
                }
    
                if(QBluetoothSocket::UnsupportedProtocolError ==error)
                {
                     ui->plainTextEdit_BluetoothInfiShow->insertPlainText(" 该平台不支持该协议\n"); //显示错误信息
                }
    
                if(QBluetoothSocket::OperationError ==error)
                {
                     ui->plainTextEdit_BluetoothInfiShow->insertPlainText("当套接字处于不允许的状态时尝试进行操作\n"); //显示错误信息
                }
        });
    
        /*3. 检查蓝牙的状态,用于设置按钮的初始状态*/
        /*3.1 检查蓝牙是否开启*/
        if(localDevice->hostMode() == QBluetoothLocalDevice::HostPoweredOff)
        {
                //如果蓝牙处于关闭状态
                ui->pushButton_OpenBluetooth->setEnabled(true);   //打开按钮
                ui->pushButton_CloseBluetooth->setEnabled(false); //关闭按钮
                ui->pushButton_BluetoothScan->setEnabled(false);
    
        }
        else    //如果蓝牙处于开启状态
        {
                ui->pushButton_OpenBluetooth->setEnabled(false);//打开按钮
                ui->pushButton_CloseBluetooth->setEnabled(true);//关闭按钮
                 ui->pushButton_BluetoothScan->setEnabled(true); //设置扫描按钮可用
        }
    
        /*3.2 设置标签显示本地蓝牙的名称*/
        QString name_info("本机蓝牙:");
        name_info+=localDevice->name();
        ui->label_BluetoothName->setText(name_info);
    
         ui->pushButton_StopScan->setEnabled(false);      //设置停止扫描蓝牙的按钮不可用
    
         ui->plainTextEdit_BluetoothInfiShow->setEnabled(false); //设置不可编辑
    }
    
    
    MainWindow::~MainWindow()
    {
        delete ui;
        delete discoveryAgent;
        delete localDevice;
        delete socket;
    }
    
    void MainWindow::on_pushButton_OpenBluetooth_clicked()
    {
        /*请求打开蓝牙设备*/
        localDevice->powerOn();
        ui->pushButton_OpenBluetooth->setEnabled(false);//打开按钮
        ui->pushButton_CloseBluetooth->setEnabled(true);//关闭按钮
        ui->pushButton_BluetoothScan->setEnabled(true); //设置扫描按钮可用
        ui->pushButton_StopScan->setEnabled(true);
    }
    
    void MainWindow::on_pushButton_CloseBluetooth_clicked()
    {
        /*关闭蓝牙设备*/
        localDevice->setHostMode(QBluetoothLocalDevice::HostPoweredOff);
        ui->pushButton_OpenBluetooth->setEnabled(true);//打开按钮
        ui->pushButton_CloseBluetooth->setEnabled(false);//关闭按钮
        ui->pushButton_BluetoothScan->setEnabled(false); //设置扫描按钮不可用
        ui->pushButton_StopScan->setEnabled(false);
    
    }
    
    
    void MainWindow::on_pushButton_BluetoothScan_clicked()
    {
         /*开始扫描周围的蓝牙设备*/
        discoveryAgent->start();
        ui->comboBox_BluetoothDevice->clear(); //清除条目
        ui->pushButton_BluetoothScan->setEnabled(false); //设置扫描按钮不可用
        ui->pushButton_StopScan->setEnabled(true);     //设置停止扫描按钮可用
    }
    
    
    void MainWindow::on_pushButton_StopScan_clicked()
    {
        /*停止扫描周围的蓝牙设备*/
        discoveryAgent->stop();
        ui->pushButton_StopScan->setEnabled(false);     //设置停止扫描按钮不可用
        ui->pushButton_BluetoothScan->setEnabled(true); //设置扫描按钮可用
    
    }
    
    
    /*当扫描到周围的设备时会调用当前的槽函数*/
    void MainWindow::addBlueToothDevicesToList(const QBluetoothDeviceInfo &info)
    {
       // QString label = QString("%1 %2").arg(info.name()).arg(info.address().toString());
        QString label = QString("%1 %2").arg(info.address().toString()).arg(info.name());
        ui->comboBox_BluetoothDevice->addItem(label); //添加字符串到comboBox上
    }
    
    
    //有数据可读
    void MainWindow::readBluetoothDataEvent()
    {
        QByteArray all = socket->readAll();
        ui->plainTextEdit_BluetoothInfiShow->insertPlainText(QString::fromLocal8Bit(all));
    }
    
    
    //建立连接
    void MainWindow::bluetoothConnectedEvent()
    {
        QMessageBox::information(this,tr("连接提示"),"蓝牙连接成功!");
    
        /*停止扫描周围的蓝牙设备*/
        discoveryAgent->stop();
        ui->pushButton_StopScan->setEnabled(false);     //设置停止扫描按钮不可用
        ui->pushButton_BluetoothScan->setEnabled(false); //设置扫描按钮不可用
    }
    
    
    //断开连接
    void MainWindow::bluetoothDisconnectedEvent()
    {
        QMessageBox::information(this,tr("连接提示"),"蓝牙断开连接!");
        ui->pushButton_BluetoothScan->setEnabled(true); //设置扫描按钮可用
    }
    
    
    /*
    在说蓝牙设备连接之前,不得不提一个非常重要的概念,就是蓝牙的Uuid,引用一下百度的:
    在蓝牙中,每个服务和服务属性都唯一地由"全球唯一标识符" (UUID)来校验。
    正如它的名字所暗示的,每一个这样的标识符都要在时空上保证唯一。
    UUID类可表现为短整形(16或32位)和长整形(128位)UUID。
    他提供了分别利用String和16位或32位数值来创建类的构造函数,提供了一个可以比较两个UUID(如果两个都是128位)的方法,还有一个可以转换一个UUID为一个字符串的方法。
    UUID实例是不可改变的(immutable),只有被UUID标示的服务可以被发现。
    在Linux下你用一个命令uuidgen -t可以生成一个UUID值;
    在Windows下则执行命令uuidgen 。UUID看起来就像如下的这个形式:2d266186-01fb-47c2-8d9f-10b8ec891363。当使用生成的UUID去创建一个UUID对象,你可以去掉连字符。
    */
    
    //发送数据
    void MainWindow::on_pushButton_SendData_clicked()
    {
        QString text=ui->lineEdit_SendData->text();
        QByteArray send_data=text.toLocal8Bit();
        socket->write(send_data); //发送数据
    }
    
    //清空收到的数据
    void MainWindow::on_pushButton_Clear_clicked()
    {
        ui->plainTextEdit_BluetoothInfiShow->setPlainText("");
    }
    
    //连接蓝牙
    void MainWindow::on_pushButton_ConnectDev_clicked()
    {
        QString text = ui->comboBox_BluetoothDevice->currentText();
        int index = text.indexOf(' ');
        if(index == -1) return;
    
        QBluetoothAddress address(text.left(index));
    
        QString connect_device="开始连接蓝牙设备:\n";
        connect_device+=ui->comboBox_BluetoothDevice->currentText();
        QMessageBox::information(this,tr("连接提示"),connect_device);
    
        //开始连接蓝牙设备
        socket->connectToService(address, QBluetoothUuid(serviceUuid) ,QIODevice::ReadWrite);
    }
    
    
    //帮助提示
    void MainWindow::on_pushButton_help_clicked()
    {
        QMessageBox::information(this,tr("帮助提示"),"本软件用于HC-05/06系列串口蓝牙调试!\n"
                                                 "不支持BLE4.0版本蓝牙调试!\n"
                                                 "软件作者:DS小龙哥\n"
                                                 "BUG反馈:1126626497@qq.com");
    }
    
    

     

     

     

    展开全文
  • 手机蓝牙串口的调试助手demo实现

    万次阅读 多人点赞 2018-05-31 17:36:28
    在开始学Android开发的时候,由于其他的需要,本着学习的心态,再网上找了一个资源,做了一个手机蓝牙串口的调试助手。 程序搭建原理简介: 在Android蓝牙通信连接的开发中,需要在AndroidManifest.xml配置文件中...

    在开始学Android开发的时候,由于其他的需要,本着学习的心态,再网上找了一个资源,做了一个手机蓝牙串口的调试助手。

    程序搭建原理简介:

    在Android蓝牙通信连接的开发中,需要在AndroidManifest.xml配置文件中增加相应的权限,需要添加BLUETOOTH和BLUETOOTH_ADMIN这两个权限。在确保手机支持蓝牙的前提下,应用程序通过获取BluetoothAdapter类,根据其getDefaultAdapter()方法获取该类的实例,通过.isEnabled()查询手机蓝牙是否为打开状态。通过BluetoothAdapter.getBondedDevices()获取该手机蓝牙设备已经匹配的蓝牙设备信息;搜索新设备可通过使用BluetoothAdapter.startDiscovery()方法进入一个为时12秒的扫描发现外围蓝牙其他设备,当发系统现设备时,随即系统发出广播,程序通过注册并接受该广播,获取该广播信息里的蓝牙设备BluetoothDevice实例,从而获取该蓝牙设备的信息。
     
     

    蓝牙通信技术可以在短距离传输中以无线电的方式传递数据,借助蓝牙通信技术来创造便利性,智能性和可控性[8]。实现Android应用程序与蓝牙设备连接,类似TCP连接,构建Android蓝牙通信连接两个关键类是BluetoothSocket和BluetoothServerSocket[9]。

    在Android蓝牙通信连接的开发中,实现基本功能蓝牙通信软件,则需要在软件实现服务端和客户端两种机制[10]。这种通信构建需要在服务端程序根据UUID(通用唯一识别码)调用listenUsingRfcommWithServiceRecord(String,UUID)获得BluetoothServerSocket对象,在子线程调用accept()方法开启监听线程。在客户端也根据UUID(通用唯一识别码)调用createRfcommSocketToServiceRecord(UUID)获取BluetoothSocket,在子线程调用connect()方法发起请求连接。

    构建蓝牙通信连接后,不管是服务器还是客户端机制,彼此都会连接好的BluetoothSocket对象,获取对应的输入字节流(inputstream)和输出字节流(outputstream),可调用它们的read(byte[])和write(byte[])方法来分别实现对数据流的读和写,实现蓝牙数据通信功能。

     

    程序蓝牙通信搭建原理框图:

     

    本项目所用的权限:

       由于用到蓝牙连接,Android存储权限获取,要配置相应的权限,没有配置Android6.0动态权限获取。

     

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

    接下来大体过一下代码,代码 基本都有注释,基本应该都能看的懂,由于时间原因就不一一介绍了:

    构建蓝牙的基本服务类BluetoothChatService.class

     

    /**
     * 这个类做了所有设置和管理与其它蓝牙设备连接的工作。
     *  它有一个线程监听传入连接,一个线程与设备进行连接,还有一个线程负责连接后的数据传输。
     *
     */
    public class BluetoothChatService {
        // Debugging
        private static final String TAG = "BluetoothChatService";
        private static final boolean D = true;
        // 创建服务器套接字时SDP记录的名称
        private static final String NAME = "BluetoothChat";
        // 该应用的唯一UUID
        private static final UUID MY_UUID = UUID.fromString("00001101-0000-1000-8000-00805F9B34FB");
        // 成员变量
        private final BluetoothAdapter mAdapter;
        private final Handler mHandler;
        private AcceptThread mAcceptThread;
        private ConnectThread mConnectThread;
        private ConnectedThread mConnectedThread;
        private int mState;
        // 指示当前连接状态的常量
        public static final int STATE_NONE = 0;       // we're doing nothing
        public static final int STATE_LISTEN = 1;     // 现在正在侦听传入连接
        public static final int STATE_CONNECTING = 2; // 现在启动传出连接
        public static final int STATE_CONNECTED = 3;  // 现在连接到远程设备
    
        //蓝牙接收延迟时间
         private int delay_time;
        public void setDelay_time(int delay_time) {
            this.delay_time = delay_time;
        }
        /**
         * 构造函数。 准备新的BluetoothChat会话。
         * @param context  The UI Activity Context
         * @param handler  A Handler to send messages back to the UI Activity
         */
        public BluetoothChatService(Context context, Handler handler) {
            mAdapter = BluetoothAdapter.getDefaultAdapter();
            mState = STATE_NONE;
            mHandler = handler;
            delay_time=100;
        }
    
        /**
         * 设置聊天连接的当前状态
         * @param state  定义当前连接状态的整数
         */
        private synchronized void setState(int state) {
            if (D) Log.d(TAG, "setState() " + mState + " -> " + state);
            mState = state;
    
            // Give the new state to the Handler so the UI Activity can update
            mHandler.obtainMessage(BluetoothChat.MESSAGE_STATE_CHANGE, state, -1).sendToTarget();
        }
    
        /**
         * 返回当前连接状态。 */
        public synchronized int getState() {
            return mState;
        }
    
        /**
         * 启动聊天服务。 特别地启动AcceptThread以在侦听(服务器)模式下开始会话。
         * 由Activity onResume()调用 */
        public synchronized void start() {
            if (D) Log.d(TAG, "start");
    
            // 取消尝试建立连接的任何线程
            if (mConnectThread != null) {mConnectThread.cancel(); mConnectThread = null;}
    
            // 取消当前运行连接的任何线程
            if (mConnectedThread != null) {mConnectedThread.cancel(); mConnectedThread = null;}
    
            // 启动线程以监听BluetoothServerSocket
            if (mAcceptThread == null) {
                mAcceptThread = new AcceptThread();
                mAcceptThread.start();
            }
            setState(STATE_LISTEN);
        }
    
        /**
         * 启动ConnectThread以启动与远程设备的连接。
         * @param device  要连接的BluetoothDevice
         */
        public synchronized void connect(BluetoothDevice device) {
            if (D) Log.d(TAG, "connect to: " + device);
    
            // 取消尝试建立连接的任何线程
            if (mState == STATE_CONNECTING) {
                if (mConnectThread != null) {mConnectThread.cancel(); mConnectThread = null;}
            }
    
            // 取消当前运行连接的任何线程
            if (mConnectedThread != null) {mConnectedThread.cancel(); mConnectedThread = null;}
    
            // 启动线程以与给定设备连接
            mConnectThread = new ConnectThread(device);
            mConnectThread.start();
            setState(STATE_CONNECTING);
        }
    
        /**
         * 启动ConnectedThread以开始管理蓝牙连接
         * @param socket  在其上进行连接的BluetoothSocket
         * @param device  已连接的BluetoothDevice
         */
        public synchronized void connected(BluetoothSocket socket, BluetoothDevice device) {
            if (D) Log.d(TAG, "connected");
    
            // 取消完成连接的线程
            if (mConnectThread != null) {mConnectThread.cancel(); mConnectThread = null;}
    
            // 取消当前运行连接的任何线程
            if (mConnectedThread != null) {mConnectedThread.cancel(); mConnectedThread = null;}
    
            // 取消接受线程,因为我们只想连接到一个设备
            if (mAcceptThread != null) {mAcceptThread.cancel(); mAcceptThread = null;}
    
            // 启动线程以管理连接并执行传输
            mConnectedThread = new ConnectedThread(socket);
            mConnectedThread.start();
    
            //将连接的设备的名称发送回UI活动
            Message msg = mHandler.obtainMessage(BluetoothChat.MESSAGE_DEVICE_NAME);
            Bundle bundle = new Bundle();
            bundle.putString(BluetoothChat.DEVICE_NAME, device.getName());
            msg.setData(bundle);
            mHandler.sendMessage(msg);
    
            setState(STATE_CONNECTED);
        }
    
        /**
         * Stop all threads
         */
        public synchronized void stop() {
            if (D) Log.d(TAG, "stop");
            if (mConnectThread != null) {mConnectThread.cancel(); mConnectThread = null;}
            if (mConnectedThread != null) {mConnectedThread.cancel(); mConnectedThread = null;}
            if (mAcceptThread != null) {mAcceptThread.cancel(); mAcceptThread = null;}
            setState(STATE_NONE);
        }
    
        /**
         * 以线程锁(不同步)方式写入ConnectedThread
         * @param out 要写入的字节
         * @see ConnectedThread#write(byte[])
         */
        public void write(byte[] out) {
            //创建临时对象
            ConnectedThread r;
            // 同步ConnectedThread的副本
            synchronized (this) {
                if (mState != STATE_CONNECTED) return;
                r = mConnectedThread;
            }
            //执行写入不同步
            r.write(out);
        }
    
        /**
         * 指示连接尝试失败并通知UI活动.
         */
        private void connectionFailed() {
            setState(STATE_LISTEN);
    
            // 将失败消息发送回活动
            Message msg = mHandler.obtainMessage(BluetoothChat.MESSAGE_TOAST);
            Bundle bundle = new Bundle();
            bundle.putString(BluetoothChat.TOAST, "无法连接设备");
            msg.setData(bundle);
            mHandler.sendMessage(msg);
        }
    
        /**
         * 指示连接已丢失并通知UI活动
         */
        private void connectionLost() {
            setState(STATE_LISTEN);
    
            // 将失败消息发送回活动
            Message msg = mHandler.obtainMessage(BluetoothChat.MESSAGE_TOAST);
            Bundle bundle = new Bundle();
            bundle.putString(BluetoothChat.TOAST, "丢失设备连接");
            msg.setData(bundle);
            mHandler.sendMessage(msg);
        }
    
        /**
         * 此线程在侦听传入连接时运行。 它的行为像一个服务器端。
         *  它运行直到接受连接
         * (或直到取消).
         */
        private class AcceptThread extends Thread {
            // 本地服务器套接字
            private final BluetoothServerSocket mmServerSocket;
    
            public AcceptThread() {
                BluetoothServerSocket tmp = null;
    
                // 创建一个新的侦听服务器套接字
                try {
                    tmp = mAdapter.listenUsingRfcommWithServiceRecord(NAME, MY_UUID);
                } catch (IOException e) {
                    Log.e(TAG, "listen() failed", e);
                }
                mmServerSocket = tmp;
            }
    
            public void run() {
                if (D) Log.d(TAG, "BEGIN mAcceptThread" + this);
                setName("AcceptThread");
                BluetoothSocket socket = null;
    
                // 如果我们没有连接,请监听服务器插座
                while (mState != STATE_CONNECTED) {
                    try {
                        // 这是一个阻塞调用,只会在成功的连接或异常返回
                        socket = mmServerSocket.accept();
                    } catch (IOException e) {
                        Log.e(TAG, "accept() failed", e);
                        break;
                    }
    
                    // 如果连接被接受
                    if (socket != null) {
                        synchronized (BluetoothChatService.this) {
                            switch (mState) {
                            case STATE_LISTEN:
                            case STATE_CONNECTING:
                                // 状况正常。 启动连接的线程。
                                connected(socket, socket.getRemoteDevice());
                                break;
                            case STATE_NONE:
                            case STATE_CONNECTED:
                                //未准备就绪或已连接。 终止新套接字。
                                try {
                                    socket.close();
                                } catch (IOException e) {
                                    Log.e(TAG, "Could not close unwanted socket", e);
                                }
                                break;
                            }
                        }
                    }
                }
                if (D) Log.i(TAG, "END mAcceptThread");
            }
    
            public void cancel() {
                if (D) Log.d(TAG, "cancel " + this);
                try {
                    mmServerSocket.close();
                } catch (IOException e) {
                    Log.e(TAG, "close() of server failed", e);
                }
            }
        }
    
        /**
         * 尝试与设备建立传出连接时,此线程运行。类似于一个客户端
         * 它直通; 连接
         * 成功或失败。
         */
        private class ConnectThread extends Thread {
            private final BluetoothSocket mmSocket;
            private final BluetoothDevice mmDevice;
    
            public ConnectThread(BluetoothDevice device) {
                mmDevice = device;
                BluetoothSocket tmp = null;
    
                // 获取与给定的蓝牙设备的连接的BluetoothSocket
                try {
                    tmp = device.createRfcommSocketToServiceRecord(MY_UUID);
                } catch (IOException e) {
                    Log.e(TAG, "create() failed", e);
                }
                mmSocket = tmp;
            }
    
            public void run() {
                Log.i(TAG, "BEGIN mConnectThread");
                setName("ConnectThread");
                // 始终取消发现,因为它会减慢连接速度
                mAdapter.cancelDiscovery();
                //连接到BluetoothSocket
                try {
                    // 这是一个阻塞调用,只会在成功的连接或异常返回
                    mmSocket.connect();
                } catch (IOException e) {
                    connectionFailed();
                    // Close the socket
                    try {
                        mmSocket.close();
                    } catch (IOException e2) {
                        Log.e(TAG, "unable to close() socket during connection failure", e2);
                    }
                    // 启动服务以重新启动侦听模式
                    BluetoothChatService.this.start();
                    return;
                }
    
                // 重置ConnectThread,因为我们完成了
                synchronized (BluetoothChatService.this) {
                    mConnectThread = null;
                }
    
                // 启动连接的线程
                connected(mmSocket, mmDevice);
            }
    
            public void cancel() {
                try {
                    mmSocket.close();
                } catch (IOException e) {
                    Log.e(TAG, "close() of connect socket failed", e);
                }
            }
        }
    
        /**
         * 此线程在与远程设备的连接期间运行。
         * 它处理所有传入和传出传输。
         */
        private class ConnectedThread extends Thread {
            private final BluetoothSocket mmSocket;
            private final InputStream mmInStream;
            private final OutputStream mmOutStream;
    
            public ConnectedThread(BluetoothSocket socket) {
                Log.d(TAG, "create ConnectedThread");
                mmSocket = socket;
                InputStream tmpIn = null;
                OutputStream tmpOut = null;
    
                // 获取BluetoothSocket输入和输出流
                try {
                    tmpIn = socket.getInputStream();
                    tmpOut = socket.getOutputStream();
                } catch (IOException e) {
                    Log.e(TAG, "temp sockets not created", e);
                }
    
                mmInStream = tmpIn;
                mmOutStream = tmpOut;
            }
    
            public void run()
            {
                Log.i(TAG, "BEGIN mConnectedThread");
                byte[] buffer = new byte[1024];  
                int bytes;  
                  
                while (true) {  
                    try {  
                            while(mmInStream.available()==0){
                        }  
                        try {  
                            Thread.sleep(delay_time);  //当有数据流入时,线程休眠一段时间,默认100ms
                        } catch (InterruptedException e) {  
                            e.printStackTrace();  
                        }  
                        bytes = mmInStream.read(buffer);  //从字节流中读取数据填充到字节数组,返回读取数据的长度
                        mHandler.obtainMessage(BluetoothChat.MESSAGE_READ, bytes, -1, buffer)
                                .sendToTarget();  //将消息传回主界面
                    } catch (IOException e) {  
                        Log.e(TAG, "disconnected", e);  
                        connectionLost();  
                        break;  
                    }  
                 }
            }
    
            /**
             * 写入连接的OutStream。
             * @param buffer  The bytes to write
             */
            public void write(byte[] buffer) {
                try {
                    mmOutStream.write(buffer);
    
                    //将发送的消息共享回UI活动
                    mHandler.obtainMessage(BluetoothChat.MESSAGE_WRITE, -1, -1, buffer)
                            .sendToTarget();
                } catch (IOException e) {
                    Log.e(TAG, "Exception during write", e);
                }
            }
    
            public void cancel() {
                try {
                    mmSocket.close();
                } catch (IOException e) {
                    Log.e(TAG, "close() of connect socket failed", e);
                }
            }
        }
    }

    主要显示视图UI类 BluetoothChat.class类

     

    /**
     * 显示通信信息的主Activity。
     */
    public class BluetoothChat extends Activity {
       // Debugging
       private static final String TAG = "BluetoothChat";
       private static final boolean D = true;
        //返回页面标志
       private boolean exit =false;
    
       // 来自BluetoothChatService Handler的消息类型
       public static final int MESSAGE_STATE_CHANGE = 1;
       public static final int MESSAGE_READ = 2;
       public static final int MESSAGE_WRITE = 3;
       public static final int MESSAGE_DEVICE_NAME = 4;
       public static final int MESSAGE_TOAST = 5;
    
       // 来自BluetoothChatService Handler的关键名
       public static final String DEVICE_NAME = "device_name";
       public static final String TOAST = "toast";
       // Intent请求代码
       private static final int REQUEST_CONNECT_DEVICE = 1;
       private static final int REQUEST_ENABLE_BT = 2;
    
       // 布局视图
       private TextView mTitle;
       private TextView mConversationView;
       private TextView outcount;
       private TextView incount;
    
       private TextView view;
    
    
       // 声明复选按钮
       private CheckBox in16;
       private CheckBox autosend;
       private CheckBox out16;
    
       // 声明button按钮
       private Button mSendButton;
    
       private Button search;
       private Button disc;
       // 用来保存存储的文件名
       public String filename = "";
       // 保存用数据缓存
       private String fmsg = "";
       // 计数用
       private int countin = 0;
       private int countout = 0;
    
       // 已连接设备的名称
       private String mConnectedDeviceName = null;
       // 输出流缓冲区
       private StringBuffer mOutStringBuffer;
    
       // 本地蓝牙适配器
       private BluetoothAdapter mBluetoothAdapter = null;
       // 用于通信的服务
       private BluetoothChatService mChatService = null;
       // CheckBox用
       private boolean inhex = true;
       private boolean outhex = true;
       private boolean auto = false;
    
    
       @Override
       public void onCreate(Bundle savedInstanceState) {
          super.onCreate(savedInstanceState);
          if (D)
             Log.e(TAG, "+++ ON CREATE +++");
          // 设置窗口布局
          requestWindowFeature(Window.FEATURE_CUSTOM_TITLE);
          setContentView(R.layout.activity_bluetooth_chat_layout);
          getWindow().setFeatureInt(Window.FEATURE_CUSTOM_TITLE,
                R.layout.custom_title);
    
          //布局控件初始化函数,注册相关监听器
          init();
    
          // 获取本地蓝牙适配器
          mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
    
          // 如果没有蓝牙适配器,则不支持
          if (mBluetoothAdapter == null) {
             Toast.makeText(this, "蓝牙不可用", Toast.LENGTH_LONG).show();
             finish();
             return;
          }
    
          search.setOnClickListener(new OnClickListener() {
    
             @Override
             public void onClick(View v) {
                search();
             }
          });
    
          disc.setOnClickListener(new OnClickListener() {
    
             @Override
             public void onClick(View v) {
                Toast.makeText(BluetoothChat.this, "该设备已设置为可在300秒内发现,且可连接",
                      Toast.LENGTH_SHORT).show();
                ensureDiscoverable();
             }
          });
       }
    
       public void search(){
          Intent serverIntent = new Intent(BluetoothChat.this,
                device.class);
          startActivityForResult(serverIntent, REQUEST_CONNECT_DEVICE);
       }
    
       private void init(){
          // 通过findViewById获得CheckBox对象
          in16 = (CheckBox) findViewById(R.id.in16);
          autosend = (CheckBox) findViewById(R.id.autosend);
          out16 = (CheckBox) findViewById(R.id.out16);
    
          // 注册事件监听器
          in16.setOnCheckedChangeListener(listener);
          autosend.setOnCheckedChangeListener(listener);
          out16.setOnCheckedChangeListener(listener);
          // 获得button的对象
          search = (Button) findViewById(R.id.search);
          disc = (Button) findViewById(R.id.discoverable1);
    
          mSendButton = (Button) findViewById(R.id.button_send);
          //获取选择控件的值
    
          // 设置custom title
          mTitle = (TextView) findViewById(R.id.title_left_text);
          mTitle.setText(R.string.activity_name);
          mTitle = (TextView) findViewById(R.id.title_right_text);
          view = (TextView) findViewById(R.id.edit_text_out);
    
       }
    
    
          // 响应事件监听
       private OnCheckedChangeListener listener = new OnCheckedChangeListener() {
    
             @Override
          public void onCheckedChanged(CompoundButton buttonView,
                boolean isChecked) {
             // in16被选中
             if (buttonView.getId() == R.id.in16) {
                if (isChecked) {
                   Toast.makeText(BluetoothChat.this, "16进制显示",
                         Toast.LENGTH_SHORT).show();
                   inhex = true;
                } else
                   inhex = false;
             }
    
             //out16选中
             if (buttonView.getId() == R.id.out16) {
                if (isChecked) {
                   Toast.makeText(BluetoothChat.this, "16进制发送",
                         Toast.LENGTH_SHORT).show();
                   outhex = true;
                } else
                   outhex = false;
             }
             // 自动发送被选中
             if (buttonView.getId() == R.id.autosend) {
                if (isChecked) {
                   Toast.makeText(BluetoothChat.this, "自动发送",
                         Toast.LENGTH_SHORT).show();
                   auto = true;
                } else
                   auto = false;
             }
          }
       };
    
    
       @Override
       public void onStart() {
          super.onStart();
          if (D)
             Log.e(TAG, "++ ON START ++");
    
    
          //如果BT未打开,请求启用。
          // 然后在onActivityResult期间调用setupChat()
          if (!mBluetoothAdapter.isEnabled())
          {
             Intent enableIntent = new Intent(
                   BluetoothAdapter.ACTION_REQUEST_ENABLE);
             startActivityForResult(enableIntent, REQUEST_ENABLE_BT);
             // 否则,设置聊天会话
          }
          else
          {
    
             if (mChatService == null)
                setupChat();
             else {
                try {
                   mChatService.wait(100);
                } catch (InterruptedException e) {
                   e.printStackTrace();
                }
             }
          }
       }
    
    
       //300秒内搜索
       private void ensureDiscoverable() {
          if (D)
             Log.d(TAG, "ensure discoverable");
          if (mBluetoothAdapter.getScanMode() != BluetoothAdapter.SCAN_MODE_CONNECTABLE_DISCOVERABLE) {
             Intent discoverableIntent = new Intent(
                   BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE);
             //设置本机蓝牙可让发现
             discoverableIntent.putExtra(
                   BluetoothAdapter.EXTRA_DISCOVERABLE_DURATION, 300);
             startActivity(discoverableIntent);
          }
       }
    
       //自动发送
       private Runnable runnable = new Runnable() {
          @Override
          public void run() {
             String message = view.getText().toString();
             sendMessage(message);
             // 初始化输出流缓冲区
             mOutStringBuffer = new StringBuffer("");
    
          }
       };
    
    
    //初始化
       private void setupChat() {
          Log.d(TAG, "setupChat()");
    
          mConversationView = (TextView) findViewById(R.id.in);
          mConversationView.setMovementMethod(ScrollingMovementMethod
                .getInstance());// 使TextView接收区可以滚动
          outcount = (TextView) findViewById(R.id.outcount);
          incount = (TextView) findViewById(R.id.incount);
          outcount.setText("0");
          incount.setText("0");
    
          mSendButton.setOnClickListener(new OnClickListener() {
             public void onClick(View v) {
                // 使用编辑文本小部件的内容发送消息
                TextView view = (TextView) findViewById(R.id.edit_text_out);
    
                   String message = view.getText().toString();
                   sendMessage(message);
    
             }
          });
    
             // 初始化BluetoothChatService以执行app_incon_bluetooth连接
          mChatService = new BluetoothChatService(this, mHandler);
    
          //初始化外发消息的缓冲区
          mOutStringBuffer = new StringBuffer("");
       }
    
    
       //重写发送函数,参数不同。
       private void sendMessage(String message) {
          // 确保已连接
          if (mChatService.getState() != BluetoothChatService.STATE_CONNECTED) {
             Toast.makeText(this, R.string.not_connected, Toast.LENGTH_SHORT)
                   .show();
             return;
          }
          // 检测是否有字符串发送
          if (message.length() > 0) {
             // 获取 字符串并告诉BluetoothChatService发送
             if (outhex == true) {
                byte[] send = Data_syn.hexStr2Bytes(message);
                mChatService.write(send);//回调service
    
             } else if (outhex == false) {
                byte[] send = message.getBytes();
                mChatService.write(send);//回调service
             }
             // 清空输出缓冲区
             mOutStringBuffer.setLength(0);
          }
          else {
             Toast.makeText(this,"发送内容不能为空",
                   Toast.LENGTH_SHORT).show();
          }
       }
    
    
    
    
    
       // 该Handler从BluetoothChatService中获取信息
       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)
                   {
                      case BluetoothChatService.STATE_CONNECTED:
                        mTitle.setText(R.string.title_connected_to);
                        mTitle.append(mConnectedDeviceName);
                        mConversationView.setText(null);
                        break;
    
                      case BluetoothChatService.STATE_CONNECTING:
                       mTitle.setText(R.string.title_connecting);
                       break;
    
                      case BluetoothChatService.STATE_LISTEN:
                      case BluetoothChatService.STATE_NONE:
                       mTitle.setText(R.string.title_not_connected);
                       break;
                   }
                break;
    
             case MESSAGE_WRITE:
                byte[] writeBuf = (byte[]) msg.obj;
                // 自动发送
                if (auto == true) {
    
                      // 自动发送模块
                   mHandler.postDelayed(runnable, 1000);
                   } else if (auto == false) {
                      mHandler.removeCallbacks(runnable);
                }
                // 发送计数
                if (outhex == true) {
                   String writeMessage = Data_syn.Bytes2HexString(writeBuf);
                   countout += writeMessage.length() / 2;
                   outcount.setText("" + countout);
                } else if (outhex == false) {
                   String writeMessage = null;
                   try {
                      writeMessage = new String(writeBuf, "GBK");
                   } catch (UnsupportedEncodingException e1) {
                      e1.printStackTrace();
                   }
                   countout += writeMessage.length();
                   outcount.setText("" + countout);
                }
                break;
             case MESSAGE_READ:
    
                byte[] readBuf = (byte[]) msg.obj;
    
                  //检错误码计算函数
    
                if (inhex == true) {
                   String readMessage = " "
                         + Data_syn.bytesToHexString(readBuf, msg.arg1);
                   fmsg += readMessage;
                   mConversationView.append(readMessage);
                   // 接收计数,更显UI
                   countin += readMessage.length() / 2;
                   incount.setText("" + countin);
                } else if (inhex == false) {
                   String readMessage = null;
                   try {
                      readMessage = new String(readBuf, 0, msg.arg1, "GBK");
                   } catch (UnsupportedEncodingException e) {
                      e.printStackTrace();
                   }
                   fmsg += readMessage;
                   mConversationView.append(readMessage);
                   // 接收计数,更新UI
                   countin += readMessage.length();
                   incount.setText("" + countin);
                }
                break;
             case MESSAGE_DEVICE_NAME:
                // 保存已连接设备的名称
                mConnectedDeviceName = msg.getData().getString(DEVICE_NAME);
                Toast.makeText(getApplicationContext(),
                      "连接到 " + mConnectedDeviceName, Toast.LENGTH_SHORT)
                      .show();
                break;
             case MESSAGE_TOAST:
                Toast.makeText(getApplicationContext(),
                      msg.getData().getString(TOAST), Toast.LENGTH_SHORT)
                      .show();
                break;
             }
          }
       };
    
    
    
        //返回该Activity回调函数
       public void onActivityResult(int requestCode, int resultCode, Intent data) {
          if (D)
             Log.d(TAG, "onActivityResult " + resultCode);
    
          switch (requestCode) {
    
    //search返回的
          case REQUEST_CONNECT_DEVICE:
    
             // DeviceListActivity返回时要连接的设备
             if (resultCode == Activity.RESULT_OK) {
                // 获取设备的MAC地址
                String address = data.getExtras().getString(
                      device.EXTRA_DEVICE_ADDRESS);
    
                // 获取BLuetoothDevice对象
                BluetoothDevice device = mBluetoothAdapter
                      .getRemoteDevice(address);
                // 尝试连接到设备
                mChatService.connect(device);
             }
             break;
    //start返回的(遇到蓝牙不可用退出)
          case REQUEST_ENABLE_BT:
             // 当启用蓝牙的请求返回时
             if (resultCode == Activity.RESULT_OK)
             {
                //蓝牙已启用,因此设置聊天会话
                setupChat();//初始化文本
             }
             else
             {
                // 用户未启用蓝牙或发生错误
                Log.d(TAG, "BT not enabled");
    
                Toast.makeText(this, R.string.bt_not_enabled_leaving,
                      Toast.LENGTH_SHORT).show();
                finish();
             }
          }
       }
    
    
       // 保存按键响应函数
       public void onSaveButtonClicked(View v) {
          Save();
       }
    
       // 清屏按键响应函数
       public void onClearButtonClicked(View v) {
          fmsg = "";
          mConversationView.setText(null);
          view.setText(null);
          return;
       }
    
       // 清除计数按键响应函数
       public void onClearCountButtonClicked(View v) {
          countin = 0;
          countout = 0;
          outcount.setText("0");
          incount.setText("0");
          return;
       }
    
    
    
       // 保存功能实现
       private void Save() {
          // 显示对话框输入文件名
          LayoutInflater factory = LayoutInflater.from(BluetoothChat.this); // 图层模板生成器句柄
          final View DialogView = factory.inflate(R.layout.sname, null); // 用sname.xml模板生成视图模板
          new AlertDialog.Builder(BluetoothChat.this).setTitle("文件名")
                .setView(DialogView) // 设置视图模板
                .setPositiveButton("确定", new DialogInterface.OnClickListener() // 确定按键响应函数
                      {
                         public void onClick(DialogInterface dialog,
                               int whichButton) {
                            EditText text1 = (EditText) DialogView
                                  .findViewById(R.id.sname); // 得到文件名输入框句柄
                            filename = text1.getText().toString(); // 得到文件名
    
                            try {
                               if (Environment.getExternalStorageState()
                                     .equals(Environment.MEDIA_MOUNTED)) { // 如果SD卡已准备好
    
                                  filename = filename + ".txt"; // 在文件名末尾加上.txt
                                  File sdCardDir = Environment
                                        .getExternalStorageDirectory(); // 得到SD卡根目录
                                  File BuildDir = new File(sdCardDir,
                                        "/BluetoothSave"); // 打开BluetoothSave目录,如不存在则生成
                                  if (BuildDir.exists() == false)
                                     BuildDir.mkdirs();
                                  File saveFile = new File(BuildDir,
                                        filename); // 新建文件句柄,如已存在仍新建文档
                                  FileOutputStream stream = new FileOutputStream(
                                        saveFile); // 打开文件输入流
                                  stream.write(fmsg.getBytes());
                                  stream.close();
                                  Toast.makeText(BluetoothChat.this,
                                        "存储成功!", Toast.LENGTH_SHORT)
                                        .show();
                               } else {
                                  Toast.makeText(BluetoothChat.this,
                                        "没有存储卡!", Toast.LENGTH_LONG)
                                        .show();
                               }
                            } catch (IOException e) {
                               return;
                            }
                         }
                      })
                .setNegativeButton("取消", // 取消按键响应函数,直接退出对话框不做任何处理
                      new DialogInterface.OnClickListener() {
                         public void onClick(DialogInterface dialog,
                               int which) {
                         }
                      }).show(); // 显示对话框
       }
    
       @Override
       public synchronized void onResume() {
          super.onResume();
          if (D)
             Log.e(TAG, "+ ON RESUME +");
          // 在onResume()中执行此检查包括在onStart()期间未启用BT的情况,
          // 因此我们暂停启用它...
          // onResume()将在ACTION_REQUEST_ENABLE活动时被调用返回.
          if (mChatService != null) {
             // 只有状态是STATE_NONE,我们知道我们还没有启动蓝牙
             if (mChatService.getState() == BluetoothChatService.STATE_NONE) {
                // 启动BluetoothChat服务
                mChatService.start();
             }
          }
    
       }
    
       @Override
       public synchronized void onPause() {
          super.onPause();
          if (D)
             Log.e(TAG, "- ON PAUSE -");
       }
    
       @Override
       public void onStop() {
          super.onStop();
          if (D)
             Log.e(TAG, "-- ON STOP --");
       }
    
    
       @Override
       public void onDestroy() {
          super.onDestroy();
          // 停止蓝牙通信连接服务
          if (mChatService != null)
             mChatService.stop();
          if (D)
             Log.e(TAG, "--- ON DESTROY ---");
       }
       @Override
       public void onBackPressed()
       {
          exit();
       }
    
       public void exit()
       {
          exit = true;
    
    
          if(exit  ==  true)
          {
             this.finish();
          }
    
       }
    }

    DeviceListActivity.class,蓝牙配对列表显示,点击返回给主界面,主要为一个listview

     

    /**
     * 这个 Activity显示为一个对话框. 它列出了所有已配对的设备和之后在该地区搜索到的设备. 当一个设备被用户选择后,
     * 该设备的MAC地址会在result Intent中被传回到父 Activity.
     */
    public class DeviceListActivity extends Activity
    {
       // Debugging
       private static final String TAG = "DeviceListActivity";
       private static final boolean D = true;
    
       // Return Intent extra
       public static String EXTRA_DEVICE_ADDRESS = "device_address";
       public static String EXTRA_LEGAL = "legal";
    
       // Member fields
       private BluetoothAdapter mBtAdapter;
       private ArrayAdapter<String> mPairedDevicesArrayAdapter;
       private ArrayAdapter<String> mNewDevicesArrayAdapter;
    
       private boolean isexist =false;
       //自动配对结果
       private boolean result=false;
    
    
    
       @Override
       protected void onCreate(Bundle savedInstanceState)
       {
          super.onCreate(savedInstanceState);
    
          // 设置窗口
          requestWindowFeature(Window.FEATURE_INDETERMINATE_PROGRESS);
          setContentView(R.layout.device_list);
    
          // 设置结果CANCELED使用户退出
          setResult(Activity.RESULT_CANCELED);
    
    
          // 初始化阵列适配器。 一个用于已配对的设备,一个用于新发现的设备,一个用于测试专用的设备
          mPairedDevicesArrayAdapter = new ArrayAdapter<String>(this,
                R.layout.device_name);
          mNewDevicesArrayAdapter = new ArrayAdapter<String>(this,
                R.layout.device_name);
    
    
          // 为配对的设备查找和设置ListView
          ListView pairedListView = (ListView) findViewById(R.id.paired_devices);
    
          pairedListView.setAdapter(mPairedDevicesArrayAdapter);
          pairedListView.setOnItemClickListener(mDeviceClickListener);
    
    
          // 为新发现的设备找到并设置ListView
          ListView newDevicesListView = (ListView) findViewById(R.id.new_devices);
    
          newDevicesListView.setAdapter(mNewDevicesArrayAdapter);
          newDevicesListView.setOnItemClickListener(mDeviceClickListener);
    
    
    
          // 发现设备时注册广播
          IntentFilter filter = new IntentFilter(BluetoothDevice.ACTION_FOUND);
          this.registerReceiver(mReceiver, filter);
    
          // 发现完成后注册广播
          filter = new IntentFilter(BluetoothAdapter.ACTION_DISCOVERY_FINISHED);
          this.registerReceiver(mReceiver, filter);
    
          //自动配对请求注册广播
    
          filter = new IntentFilter(BluetoothDevice.ACTION_PAIRING_REQUEST);
          this.registerReceiver(mReceiver, filter);
    
          // 获取本地蓝牙适配器
          mBtAdapter = BluetoothAdapter.getDefaultAdapter();
    
          // 获取一组当前配对的设备
          Set<BluetoothDevice> pairedDevices = mBtAdapter.getBondedDevices();
    
          // 如果有配对的设备,请将每个设备添加到ArrayAdapter
          TextView textView = (TextView) findViewById(R.id.title_paired_devices);
          if (pairedDevices.size() > 0)
          {
               textView.setVisibility(View.VISIBLE);
             for (BluetoothDevice device : pairedDevices)
             {   isexist=true;
                mPairedDevicesArrayAdapter.add(device.getName() + "\n"
                      + device.getAddress());
    
             }
          }
    
          if (isexist==false)
          {
             textView.setVisibility(View.GONE);
             String noDevices = getResources().getText(R.string.none_paired)
                   .toString();
             mPairedDevicesArrayAdapter.add(noDevices);
          }
       }
    
       @Override
       protected void onStart() {
          super.onStart();
          doDiscovery();
       }
    
       @Override
       protected void onDestroy()
       {
          super.onDestroy();
    
          // 确保我们不再进行发现
          if (mBtAdapter != null)
          {
             mBtAdapter.cancelDiscovery();
          }
    
          //取消注册广播侦听器
          this.unregisterReceiver(mReceiver);
       }
    
       /**
        * 使用BluetoothAdapter启动设备发现
        */
       private void doDiscovery()
       {
          if (D) Log.d(TAG, "doDiscovery()");
    
          // 在标题中指示扫描
          setProgressBarIndeterminateVisibility(true);
          setTitle(R.string.scanning);
    
          // 开启新装置的副标题
          findViewById(R.id.title_new_devices).setVisibility(View.VISIBLE);
    
          // 如果我们已经发现,停止它
          if (mBtAdapter.isDiscovering())
          {
             mBtAdapter.cancelDiscovery();
          }
          //从BluetoothAdapter请求发现
          mBtAdapter.startDiscovery();
       }
    
       // ListView中其他设备的点击监听器
       private OnItemClickListener mDeviceClickListener = new OnItemClickListener()
       {
          public void onItemClick(AdapterView<?> av, View v, int arg2, long arg3)
          {
             //取消发现,我们m_about来连接
             mBtAdapter.cancelDiscovery();
    
             // 获取设备的MAC地址,这是视图中最后17个字符
             String info = ((TextView) v).getText().toString();
             String address = info.substring(info.length() - 17);
    
             // 创建结果意图并包括MAC地址
             Intent intent = new Intent();
             intent.putExtra(EXTRA_DEVICE_ADDRESS, address);
             intent.putExtra(EXTRA_LEGAL,false);
             // 设置结果并完成此活动
             setResult(Activity.RESULT_OK, intent);
             finish();
          }
       };
         //ListView中专用测试设备的点击监听器
       private  OnItemClickListener mZYDeviceClickListener = new OnItemClickListener() {
           @Override
           public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
              //取消发现,我们m_about来连接
              mBtAdapter.cancelDiscovery();
    
              // 获取设备的MAC地址,这是视图中最后17个字符
              String info = ((TextView) view).getText().toString();
              String address = info.substring(info.length() - 17);
    
              // 创建结果意图并包括MAC地址
              Intent intent = new Intent();
              intent.putExtra(EXTRA_DEVICE_ADDRESS, address);
              intent.putExtra(EXTRA_LEGAL,true);
              // 设置结果并完成此活动
              setResult(Activity.RESULT_OK, intent);
              finish();
           }
        };
       // BroadcastReceiver,侦听发现的设备,并在发现完成时更改标题
       private final BroadcastReceiver mReceiver = new BroadcastReceiver()
       {
          @Override
          public void onReceive(Context context, Intent intent)
          {
             String action = intent.getAction();
             //从Intent获取BluetoothDevice对象
             BluetoothDevice device = intent
                   .getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
             // 发现找到设备时
             if (BluetoothDevice.ACTION_FOUND.equals(action))
             {    String devicename =device.getName();
                while (devicename==null){
                   devicename =device.getName();
                }
    
    
                // 该设备没有配对,加载到新的通用蓝牙设备的列表
    
                if (device.getBondState() != BluetoothDevice.BOND_BONDED)
                {
                   mNewDevicesArrayAdapter.add(device.getName() + "\n"
                         + device.getAddress());
    
                }
                  //    再次得到的action,会等于PAIRING_REQUEST,进行配对操作
             }else if(BluetoothDevice.ACTION_PAIRING_REQUEST.equals(action)){
                String devicename =device.getName();
                while (devicename==null){
                   devicename =device.getName();
                }
                Log.e(TAG,"接收到配对广播");
    
    
             }
             // 发现完成后,更改活动标题
             else if (BluetoothAdapter.ACTION_DISCOVERY_FINISHED.equals(action))
             {
             setProgressBarIndeterminateVisibility(false);
             setTitle(R.string.select_device);
    
             if (mNewDevicesArrayAdapter.getCount() == 0)
             {
                String noDevices = getResources().getText(
                   R.string.none_found).toString();
                mNewDevicesArrayAdapter.add(noDevices);
             }
    
    
          }
          }
       };

    数据转换工具类  主要设置十六进制数据为ascll数据的转化

     

    // 将字节数组转化为16进制字符串,确定长度
    public static String bytesToHexString(byte[] bytes, int a) {
        String result = "";
        for (int i = 0; i < a; i++) {
            String hexString = Integer.toHexString(bytes[i] & 0xFF);// 将高24位置0
            if (hexString.length() == 1) {
                hexString = '0' + hexString;
            }
            result += hexString.toUpperCase();
        }
        return result;
    }
    // 将字节数组转化为16进制字符串,不确定长度
    public static String Bytes2HexString(byte[] b) {
        String ret = "";
        for (int i =0; i < b.length; i++) {
            String hex = Integer.toHexString(b[i] & 0xFF);// 将高24位置0
            if (hex.length() == 1) {
                hex = '0' + hex;
            }
            ret += hex.toUpperCase();
        }
        return ret;
    }
    // 将16进制字符串转化为字节数组
    public static byte[] hexStr2Bytes(String paramString) {
        int i = paramString.length() / 2;
    
        byte[] arrayOfByte = new byte[i];
        int j = 0;
        while (true) {
            if (j >= i)
                return arrayOfByte;
            int k = 1 + j * 2;
            int l = k + 1;
            arrayOfByte[j] = (byte) (0xFF & Integer.decode(
                    "0x" + paramString.substring(j * 2, k)
                            + paramString.substring(k, l)).intValue());
            ++j;
        }
    }
    

    最后附上运行的app界面截图

                                                                           

     

     

    总结:

       这个项目总的来说是比较简单的,蓝牙通信谷歌都有相对应的蓝牙API封装。代码上去弄得比较繁琐,学习做的东西,还请各位请见谅,有什么意见和想法,欢迎留言,一起共同努力。
     

    源码载址:https://download.csdn.net/download/sinat_27064327/10450642

    新增githup地址:  https://github.com/loumeng/myBluetooth

     

     

     

     

     

    展开全文

空空如也

空空如也

1 2 3 4 5 ... 13
收藏数 258
精华内容 103
关键字:

蓝牙串口助手app源码