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>

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM