Android蓝牙串口通信模板及demo,trick

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

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>




  • 14
    点赞
  • 33
    收藏
    觉得还不错? 一键收藏
  • 12
    评论
评论 12
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值