Android蓝牙串口通信模板

转载请注明出处,谢谢http://blog.csdn.net/metalseed/article/details/7988945

Android蓝牙操作:与蓝牙串口模块通信,或其他蓝牙设备通信。

初涉android的蓝牙操作,按照固定MAC地址连接获取Device时,程序始终是异常终止,查了好多天代码都没查出原因。今天改了一下API版本,突然就成功连接了。总结之后发现果然是个坑爹之极的错误。

为了这种错误拼命查原因浪费大把时间是非常不值得的,但是问题不解决更是揪心。可惜我百度了那么多,都没有给出确切原因。今天特此mark,希望后来者遇到这个问题的时候能轻松解决。

下面是我的连接过程,中间崩溃原因及解决办法。

1:用AT指令获得蓝牙串口的MAC地址,地址是简写的,按照常理猜测可得标准格式。

2:开一个String adress= "************" //MAC地址, String MY_UUID= "************"//UUID根据通信而定,网上都有。

3:取得本地Adapter用getDefaultAdapter(); 远程的则用getRemoteDevice(adress); 之后便可用UUID开socket进行通信。

如果中途各种在getRemoteDevice处崩溃,大家可以查看一下当前的API版本,如果是2.1或以下版本的话,便能确定是API版本问题,只要换成2.2或者以上就都可以正常运行了~   这么坑爹的错误的确很为难初学者。  唉··········  为这种小trick浪费很多时间真是难过。

(另外有个重要地方,别忘了给manifest里面加以下两个蓝牙操作权限哦~)

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

下面附上Android蓝牙操作中用固定MAC地址传输信息的模板,通用搜索模式日后再补删模板:

private BluetoothAdapter mBluetoothAdapter = null;    

private BluetoothSocket btSocket = null;    

private OutputStream outStream = null;    

private InputStream inStream = null;    

private static final UUID MY_UUID = UUID.fromString("00001101-0000-1000-8000-00805F9B34FB");  //这条是蓝牙串口通用的UUID,不要更改    

private static String address = "00:12:02:22:06:61"; // <==要连接的蓝牙设备MAC地址    

/*获得通信线路过程*/    

/*1:获取本地BlueToothAdapter*/
mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
if(mBluetoothAdapter == null)
{
    Toast.makeText(this, "Bluetooth is not available.", Toast.LENGTH_LONG).show();
    finish();
    return;
}
if(!mBluetoothAdapter.isEnabled())
{
    Toast.makeText(this, "Please enable your Bluetooth and re-run this program.", Toast.LENGTH_LONG).show();
    finish();
    return;
}     

/*2:获取远程BlueToothDevice*/
    BluetoothDevice device = mBluetoothAdapter.getRemoteDevice(address);
if(mBluetoothAdapter == null)
{
    Toast.makeText(this, "Can‘t get remote device.", Toast.LENGTH_LONG).show();
    finish();
    return;
}    

/*3:获得Socket*/
    try {
    btSocket = device.createRfcommSocketToServiceRecord(MY_UUID);
} catch (IOException e) {    

    Log.e(TAG, "ON RESUME: Socket creation failed.", e);    

}    

/*4:取消discovered节省资源*/
mBluetoothAdapter.cancelDiscovery();            

/*5:连接*/    

try {    

    btSocket.connect();    

    Log.e(TAG, "ON RESUME: BT connection established, data transfer link open.");    

} catch (IOException e) {    

    try {
        btSocket.close();    

    } catch (IOException e2) {    

        Log .e(TAG,"ON RESUME: Unable to close socket during connection failure", e2);
    }
}     

/*此时可以通信了,放在任意函数中*/
/*  try {
outStream = btSocket.getOutputStream();  

inStream = btSocket.getInputStream(); //可在TextView里显示  

} catch (IOException e) {
    Log.e(TAG, "ON RESUME: Output stream creation failed.", e);
}  

String message = "1";  

byte[] msgBuffer = message.getBytes();  

try {
    outStream.write(msgBuffer);  

} catch (IOException e) {
    Log.e(TAG, "ON RESUME: Exception during write.", e);
}
*/     

通用搜索模式代码模板:

简洁简洁方式1 demo

作用: 用VerticalSeekBar控制一个 LED屏幕的亮暗。

直接上码咯~

package com.example.seed2;

import android.app.Activity;
import android.app.AlertDialog;
import android.app.Dialog;
import android.os.Bundle;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.UUID;

import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothSocket;
import android.content.DialogInterface;
import android.util.Log;
import android.view.KeyEvent;
import android.widget.Toast;

public class MetalSeed extends Activity {

    private static final String TAG = "BluetoothTest";

    private BluetoothAdapter mBluetoothAdapter = null;

    private BluetoothSocket btSocket = null;

    private OutputStream outStream = null;

    private InputStream inStream = null;

    private VerticalSeekBar vskb = null;

    private static final UUID MY_UUID = UUID.fromString("00001101-0000-1000-8000-00805F9B34FB");  //这条是蓝牙串口通用的UUID,不要更改

    private static String address = "00:12:02:22:06:61"; // <==要连接的蓝牙设备MAC地址

    /** Called when the activity is first created. */

    @Override

    public void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        this.vskb = (VerticalSeekBar)super.findViewById(R.id.mskb);
        this.vskb.setOnSeekBarChangeListener(new OnSeekBarChangeListenerX());

        mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
        if(mBluetoothAdapter == null)
        {
            Toast.makeText(this, "Bluetooth is not available.", Toast.LENGTH_LONG).show();
            finish();
            return;
        }

        if(!mBluetoothAdapter.isEnabled())
        {
            Toast.makeText(this, "Please enable your Bluetooth and re-run this program.", Toast.LENGTH_LONG).show();
            finish();
            return;

        }

    }

    private class OnSeekBarChangeListenerX implements VerticalSeekBar.OnSeekBarChangeListener {

        public void onProgressChanged(VerticalSeekBar seekBar, int progress, boolean fromUser) {
            //Main.this.clue.setText(seekBar.getProgress());
        /*    String message;
            byte [] msgBuffer;
            try {
                outStream = btSocket.getOutputStream();
            } catch (IOException e) {
                Log.e(TAG,"ON RESUME : Output Stream creation failed.", e);
            }
            message =Integer.toString( seekBar.getProgress() );
            msgBuffer = message.getBytes();
            try{
                outStream.write(msgBuffer);
            } catch (IOException e) {
                Log.e (TAG, "ON RESUME : Exception during write.", e);
            }       */
       } 

        public void onStartTrackingTouch(VerticalSeekBar seekBar) {
            String message;
            byte [] msgBuffer;
            try {
                outStream = btSocket.getOutputStream();
            } catch (IOException e) {
                Log.e(TAG,"ON RESUME : Output Stream creation failed.", e);
            }
            message =Integer.toString( seekBar.getProgress() );
            msgBuffer = message.getBytes();
            try{
                outStream.write(msgBuffer);
            } catch (IOException e) {
                Log.e (TAG, "ON RESUME : Exception during write.", e);
            }
        }

        public void onStopTrackingTouch(VerticalSeekBar seekBar) {
            String message;
            byte [] msgBuffer;
            try {
                outStream = btSocket.getOutputStream();
            } catch (IOException e) {
                Log.e(TAG,"ON RESUME : Output Stream creation failed.", e);
            }
            message =Integer.toString( seekBar.getProgress() );
            msgBuffer = message.getBytes();
            try{
                outStream.write(msgBuffer);
            } catch (IOException e) {
                Log.e (TAG, "ON RESUME : Exception during write.", e);
            }
        }
    }    

    @Override
    public void onStart()
    {

        super.onStart();

    }

    @Override
    public void onResume()
    {

        super.onResume();

        BluetoothDevice device = mBluetoothAdapter.getRemoteDevice(address);

        try {

            btSocket = device.createRfcommSocketToServiceRecord(MY_UUID);

        } catch (IOException e) {

            Log.e(TAG, "ON RESUME: Socket creation failed.", e);

        }
        mBluetoothAdapter.cancelDiscovery();
        try {

            btSocket.connect();

            Log.e(TAG, "ON RESUME: BT connection established, data transfer link open.");

        } catch (IOException e) {

            try {
                btSocket.close();

            } catch (IOException e2) {

                Log .e(TAG,"ON RESUME: Unable to close socket during connection failure", e2);
            }

        }

        // Create a data stream so we can talk to server.

    /*     try {
        outStream = btSocket.getOutputStream();

        inStream = btSocket.getInputStream();

        } catch (IOException e) {
            Log.e(TAG, "ON RESUME: Output stream creation failed.", e);
        }

        String message = "read";

        byte[] msgBuffer = message.getBytes();

        try {
            outStream.write(msgBuffer);

        } catch (IOException e) {
            Log.e(TAG, "ON RESUME: Exception during write.", e);
        }
        int ret  = -1;

        while( ret != -1)
        {
                    try {

                     ret = inStream.read();

                     } catch (IOException e)
                         {
                             e.printStackTrace();
                         }
        }

    */

    }

    @Override

    public void onPause()
    {

        super.onPause();

        if (outStream != null)
        {
            try {
                outStream.flush();
            } catch (IOException e) {
                Log.e(TAG, "ON PAUSE: Couldn‘t flush output stream.", e);
            }

        }

        try {
            btSocket.close();
        } catch (IOException e2) {
            Log.e(TAG, "ON PAUSE: Unable to close socket.", e2);
        }

    }

    @Override

    public void onStop()
    {

        super.onStop();

    }

    @Override

    public void onDestroy()
    {

        super.onDestroy();

    }

       @Override
        public boolean onKeyDown(int keyCode, KeyEvent event){
           if(keyCode == KeyEvent.KEYCODE_BACK){
               this.exitDialog();
           }
           return false;
       }
        private void exitDialog(){
           Dialog dialog = new AlertDialog.Builder(MetalSeed.this)
                   .setTitle("退出程序?")
                   .setMessage("您确定要退出本程序吗?")
                   .setPositiveButton("确定", new DialogInterface.OnClickListener() {
                        public void onClick(DialogInterface dialog, int whichButton) {
                            MetalSeed.this.finish();
                        }
                    }).setNegativeButton("取消", new DialogInterface.OnClickListener() {
                        public void onClick(DialogInterface dialog, int whichButton) { }
                    }).create();
           dialog.show();
       }

}

此为上述demo的layout

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:background="@drawable/bcf" >

    <TextView
        android:id="@+id/myt"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentTop="true"
        android:layout_centerHorizontal="true"
        android:layout_marginTop="48dp"
        android:text="MetalSeed"
        android:textSize="40dip" />

    <com.example.seed2.VerticalSeekBar
        android:id="@+id/mskb"
        android:layout_width="105dp"
        android:layout_height="219dp"
        android:layout_below="@+id/myt"
        android:layout_centerHorizontal="true"
        android:layout_marginTop="85dp"
        android:maxHeight="95dip"
        android:minHeight="95dip"
        android:minWidth="95dip"
        android:thumbOffset="0dip" />

</RelativeLayout>
时间: 2024-10-07 18:43:25

Android蓝牙串口通信模板的相关文章

BluetoothChat用于蓝牙串口通信的修改方法

本人最近在研究嵌入式的串口通信,任务是要写一个手机端的遥控器用来遥控双轮平衡小车.界面只用了一个小时就写好了,重要的问题是如何与板子所带的SPP-CA蓝牙模块进行通信. SPP-CA模块自带代码,在这里我使用的全部都是SPP-CA的默认模式.其中波特率是9600.读者若要修改其匹配密码,波特率等请使用串口调试工具对SPP-CA使用AT命令进行修改.详情参考其技术手册. 首先介绍Android端,官方的SDK中给了一个BluetoothChat的版本,这个版本稍加修改就可以进行串口通信.由于源代码

Android蓝牙串口程序开发

本文主要介绍了针对android的蓝牙串口上位机开发. 一.帧定义 android客户端按照一定的数据帧格式通过蓝牙串口发送数据到连接到MCU的蓝牙从机,MCU接收到数据后,按照帧格式的定义,接收数据帧,并解析数据帧,得到需要的数据. android客户端按照以下帧格式来发送和接收数据. 1.1客户端发送的数据帧内容 帧校验的和是从帧长开始到帧校验前所有数据的和对256取余.即sum%256. pitch roll yaw数据各16位,由高低8位组成.MCU接收数据时需要将其再复合成一个16位数

Android 蓝牙串口服务客户端开发 尝试

如题,经过三四天的开发尝试已经初步成型,下面是简陋的界面图: 上图是做的蓝牙串口服务的收发界面,主要用于平时的调试之用,由于开发的初衷是为了实现蓝牙对单片机的控制,因此加入了<进入控制/>的按钮选项,下图是控制界(xian)面(tiao) 没办法,没有太多的美学细胞,拖了两个重写的seekbar就作为控制摇杆了... 初次写Android,初次触及Java,水平自然就是无言以对,哈哈,不过为了防止万一以后有需求的升级,博客还是要写的. 1.环境搭建 Android开发者官网上提供了两套集成开发

Android 蓝牙开发之搜索、配对、连接、通信大全

        蓝牙( Bluetooth®):是一种无线技术标准,可实现固定设备.移动设备和楼宇个人域网之间的短距离数据 交换(使用2.4-2.485GHz的ISM波段的UHF无线电波).蓝牙设备最多可以同时和7个其它蓝牙设备建立连接,进 行通信,当然并不是每一个蓝牙都可以达到最大值.下面,我们从蓝牙的基本概念开始,一步一步开始了解蓝牙. 基本概念: 安卓平台提供对蓝牙的通讯栈的支持,允许设别和其他的设备进行无线传输数据.应用程序层通过安卓API来调用蓝牙的相关功 能,这些API使程序无线连接

【转】android蓝牙开发---与蓝牙模块进行通信--不错

原文网址:http://www.cnblogs.com/wenjiang/p/3200138.html 近半个月来一直在搞android蓝牙这方面,主要是项目需要与蓝牙模块进行通信.开头的进展很顺利,但因为蓝牙模块不在我这里,所以只能用手机测试.一开头就发现手机的蓝牙不能用,为了证明这点,我刷了四次不同不同系统的官方包,正式宣布手机的蓝牙报销了,于是和朋友换手机.在测试的过程中也是非常痛苦,放假了,同学都几乎回家了,剩下的同学中竟然80%都是用非android手机!我和我的小伙伴都吓呆了!!就算

Android蓝牙通信总结

这篇文章要达到的目标: 1.介绍在Android系统上实现蓝牙通信的过程中涉及到的概念. 2.在android系统上实现蓝牙通信的步骤. 3.在代码实现上的考虑. 4.例子代码实现(手持设备和蓝牙串口设备通信). 1.介绍在Android系统上实现蓝牙通信的过程中使用到的类 BluetoothAdapter Represents the local Bluetooth adapter (Bluetooth radio). The BluetoothAdapter is the entry-poi

Android串口通信

1. 解析SerialPort API 串口通信例子 首先分析一下例子中的类结构 : 通过类结构可知,最主要的还是在SerialPortJNI.java 类 ,该类写了一些Native 方法处理打开与关闭 串口 接收 发送的 SerialPort.Java 代码如下 : package com.dwin.navy.serialportapi; import java.io.FileDescriptor; import android.util.Log; /** * 串口JNI * * @auth

Android蓝牙实例(和单片机蓝牙模块通信)

最近做毕设,需要写一个简单的蓝牙APP进行交互,在网上也找了很多资料,终于给搞定了,这里分享一下^_^. 1.Android蓝牙编程 蓝牙3.0及以下版本编程需要使用UUID,UUID是通用唯一识别码(Universally Unique Identifier),这是一个软件构建的标准,也是被开源基金会组织应用在分布式计算环境领域的一部分.在蓝牙3.0及下一版本中,UUID被用于唯一标识一个服务,比如文件传输服务,串口服务.打印机服务等,如下: #蓝牙串口服务 SerialPortService

Android 蓝牙 通信

Android中蓝牙模块的使用 1. 使用蓝牙的响应权限 <uses-permission android:name="android.permission.BLUETOOTH" /> <uses-permission android:name="android.permission.BLUETOOTH_ADMIN" /> 2. 配置本机蓝牙模块 在这里首先要了解对蓝牙操作一个核心类BluetoothAdapter BluetoothAdap