与Android使用手持式蓝牙打印机
我有一个蓝牙手持打印机,可以使用我的Mac(使用Coolterm)使用SPP连接进行通信。 当我试图从Android(使用平台7)做同样的事情时,我遇到了很多问题:
-
打印机似乎不支持/需要PIN身份validation。 当从OSX进行连接时,我只是select了“不使用引脚”的选项并将其配对。 在Android中,当我使用
device.createRfcommSocketToServiceRecord(),它总是要求我input一个PIN / Key(我没有/需要)。 我使用reflection技巧解决了这个问题:Method m = device.getClass().getMethod("createInsecureRfcommSocket", new Class[] {int.class}); BluetoothSocket connection = (BluetoothSocket) m.invoke(device, 1);我不确定这是否真正起作用,但是打印机上的闪烁LED不再闪烁,这使我相信这样做。
-
一旦我有套接字,我尝试写字节数据的stream使用:
byte[] buffer = new byte[3]; buffer[0] = (byte) 0x8A; buffer[1] = (byte) 0xC1; buffer[2] = (byte) 0x04; outStream.write(buffer); int response = inStream.read(); mySocket.close();在OSX上从Coolterm发送相同的三字节序列从打印机打印testing页。 但是,这似乎使线程挂在Android(读)。
有什么我在这里错过吗?
编辑:这似乎只有当我把通道设置为1。所以这意味着我在这里的东西。
@Trevor页面我认为是在正确的道路上。 这里是我用来连接到一个基本的邮票微控制器的谷歌的例子。
/ *
*版权(C)2009 Android开源项目
*
*根据Apache许可证2.0版(“许可证”)获得许可;
*除遵守许可证外,您不得使用此文件。
*您可以在获得许可证副本
*
* http://www.apache.org/licenses/LICENSE-2.0
*
*除非适用法律要求或书面同意,软件
*根据许可证分发是“按现状”分发的,
*无任何明示或暗示的保证或条件。
*请参阅许可证以了解特定语言的pipe理权限和权限
*许可证下的限制。
* /
package com.your_package;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.UUID;
导入android.bluetooth.BluetoothAdapter;
导入android.bluetooth.BluetoothDevice;
导入android.bluetooth.BluetoothServerSocket;
导入android.bluetooth.BluetoothSocket;
导入android.content.Context;
导入android.os.Bundle;
导入android.os.Handler;
导入android.os.Message;
导入android.util.Log;
/ **
*此课程负责设置和pipe理蓝牙的所有工作
*与其他设备的连接。 它有一个线程,倾听
*传入连接,用于连接设备的线程和一个
*连接时执行数据传输的线程。
* /
公共类BluetoothService
{
//debugging
private static final String TAG =“BluetoothService_BoeBot”;
private static final boolean D = true;
//创build服务器套接字时,SDPlogging的名称
private static final String NAME_SECURE =“BluetoothSecure”;
private static final String NAME_INSECURE =“BluetoothInsecure”;
//此应用程序的唯一UUID
私有静态最终的UUID MY_UUID_SECURE =
UUID.fromString( “00001101-0000-1000-8000-00805F9B34FB”);
私有静态最终UUID MY_UUID_INSECURE =
UUID.fromString( “00001101-0000-1000-8000-00805F9B34FB”);
//会员字段
私人最终BluetoothAdapter mAdapter;
私人最终处理程序mHandler;
private AcceptThread mSecureAcceptThread;
private AcceptThread mInsecureAcceptThread;
私有ConnectThread mConnectThread;
私人ConnectedThread mConnectedThread;
private int mState;
//指示当前连接状态的常量
公共静态最终诠释STATE_NONE = 0; //我们什么都不做
公共静态最终诠释STATE_LISTEN = 1; //现在正在监听传入的连接
公共静态最终诠释STATE_CONNECTING = 2; //现在启动一个传出连接
公共静态最终诠释STATE_CONNECTED = 3; //现在连接到远程设备
/ **
*构造函数。 准备一个新的蓝牙聊天会话。
* @param上下文UI活动上下文
* @param处理程序将消息发送回UI活动的处理程序
* /
公共BluetoothService(上下文上下文,处理程序处理程序)
{
mAdapter = BluetoothAdapter.getDefaultAdapter();
mState = STATE_NONE;
mHandler = handler;
}
/ **
*设置聊天连接的当前状态
* @param state定义当前连接状态的整数
* /
私有同步无效setState(int状态)
{
(D)
Log.d(TAG,“setState()”+ mState +“ - >”+ state);
mState =状态;
//将新状态赋予处理程序,以便UI活动可以更新
mHandler.obtainMessage(BoeBot.MESSAGE_STATE_CHANGE,state,-1).sendToTarget();
}
/ **
*返回当前的连接状态。 * /
公共同步诠释getState()
{
返回mState;
}
/ **
*开始聊天服务。 具体启动AcceptThread来开始一个
*监听(服务器)模式的会话。 由Activity onResume()调用* /
public synchronized void start()
{
(D)
Log.d(TAG,“开始”);
//取消任何尝试build立连接的线程
如果(mConnectThread!= null)
{
mConnectThread.cancel();
mConnectThread = null;
}
//取消当前正在运行连接的任何线程
如果(mConnectedThread!= null)
{
mConnectedThread.cancel();
mConnectedThread = null;
}
的setState(STATE_LISTEN);
//启动线程以侦听BluetoothServerSocket
如果(mSecureAcceptThread == null)
{
mSecureAcceptThread = new AcceptThread(true);
mSecureAcceptThread.start();
}
如果(mInsecureAcceptThread == null)
{
mInsecureAcceptThread = new AcceptThread(false);
mInsecureAcceptThread.start();
}
}
/ **
*启动ConnectThread以启动到远程设备的连接。
* @param设备BluetoothDevice连接
* @param安全套接字安全types - 安全(true),不安全(false)
* /
公共同步无效连接(BluetoothDevice设备,布尔安全)
{
(D)
Log.d(TAG,“connect to:”+ device);
//取消任何尝试build立连接的线程
如果(mState == STATE_CONNECTING)
{
如果(mConnectThread!= null)
{
mConnectThread.cancel();
mConnectThread = null;
}
}
//取消当前正在运行连接的任何线程
如果(mConnectedThread!= null)
{
mConnectedThread.cancel();
mConnectedThread = null;
}
尝试
{
//开始线程连接给定的设备
mConnectThread = new ConnectThread(设备,安全);
mConnectThread.start();
的setState(STATE_CONNECTING);
catch(Exception e)
{
}
}
/ **
*启动ConnectedThread开始pipe理蓝牙连接
* @param socket已连接的BluetoothSocket
* @参数设备已连接的BluetoothDevice
* /
public synchronized void connected(BluetoothSocket socket,BluetoothDevice device,final String socketType)
{
(D)
Log.d(TAG,“connected,Socket Type:”+ socketType);
//取消完成连接的线程
如果(mConnectThread!= null)
{
mConnectThread.cancel();
mConnectThread = null;
}
//取消当前正在运行连接的任何线程
如果(mConnectedThread!= null)
{
mConnectedThread.cancel();
mConnectedThread = null;
}
//取消接受线程,因为我们只想连接到一个设备
如果(mSecureAcceptThread!= null)
{
mSecureAcceptThread.cancel();
mSecureAcceptThread = null;
}
如果(mInsecureAcceptThread!= null)
{
mInsecureAcceptThread.cancel();
mInsecureAcceptThread = null;
}
//启动线程来pipe理连接并执行传输
mConnectedThread = new ConnectedThread(socket,socketType);
mConnectedThread.start();
//将连接设备的名称发送回UI活动
消息msg = mHandler.obtainMessage(BoeBot.MESSAGE_DEVICE_NAME);
Bundle bundle = new Bundle();
bundle.putString(BoeBot.DEVICE_NAME,device.getName());
msg.setData(束);
mHandler.sendMessage(MSG);
的setState(STATE_CONNECTED);
}
/ **
*停止所有线程
* /
公共同步无效停止()
{
(D)
Log.d(TAG,“stop”);
如果(mConnectThread!= null)
{
mConnectThread.cancel();
mConnectThread = null;
}
如果(mConnectedThread!= null)
{
mConnectedThread.cancel();
mConnectedThread = null;
}
如果(mSecureAcceptThread!= null)
{
mSecureAcceptThread.cancel();
mSecureAcceptThread = null;
}
如果(mInsecureAcceptThread!= null)
{
mInsecureAcceptThread.cancel();
mInsecureAcceptThread = null;
}
的setState(STATE_NONE);
}
/ **
*以不同步的方式写入ConnectedThread
* @param out要写入的字节
*参见ConnectedThread#write(byte [])
* /
public void write(byte [] out)
{
//创build临时对象
ConnectedThread r;
//同步ConnectedThread的副本
同步(这个)
{
如果(mState!= STATE_CONNECTED)
返回;
r = mConnectedThread;
}
//执行写入不同步
r.write(下);
}
/ **
*表示连接尝试失败并通知UI活动。
* /
private void connectionFailed()
{
//发送失败消息回到活动
消息msg = mHandler.obtainMessage(BoeBot.MESSAGE_TOAST);
Bundle bundle = new Bundle();
bundle.putString(BoeBot.TOAST,“无法连接设备”);
msg.setData(束);
mHandler.sendMessage(MSG);
//启动服务以重新启动监听模式
BluetoothService.this.start();
}
/ **
*表示连接丢失并通知UI活动。
* /
私人无效connectionLost()
{
//发送失败消息回到活动
消息msg = mHandler.obtainMessage(BoeBot.MESSAGE_TOAST);
Bundle bundle = new Bundle();
bundle.putString(BoeBot.TOAST,“设备连接丢失”);
msg.setData(束);
mHandler.sendMessage(MSG);
//启动服务以重新启动监听模式
BluetoothService.this.start();
}
/ **
*此线程在侦听传入连接时运行。 它的行为
*像服务器端的客户端。 它运行,直到连接被接受
*(或直到取消)。
* /
私有类AcceptThread扩展了Thread
{
//本地服务器套接字
私人最终BluetoothServerSocket mmServerSocket;
私人stringmSocketType;
公共AcceptThread(布尔安全)
{
BluetoothServerSocket tmp = null;
mSocketType =安全吗? “安全”:“不安全”;
//创build一个新的侦听服务器套接字
尝试
{
如果(安全)
{
tmp = mAdapter.listenUsingRfcommWithServiceRecord(NAME_SECURE,MY_UUID_SECURE);
}别的
{
tmp = mAdapter.listenUsingInsecureRfcommWithServiceRecord(
NAME_INSECURE,MY_UUID_INSECURE);
}
catch(IOException e)
{
Log.e(TAG,“Socket Type:”+ mSocketType +“listen()failed”,e);
}
mmServerSocket = tmp;
}
@覆盖
public void run()
{
(D)
{
Log.d(TAG,“Socket Type:”+ mSocketType +“BEGIN mAcceptThread”+ this);
}
setName(“AcceptThread”+ mSocketType);
BluetoothSocket socket = null;
//如果我们没有连接,请收听服务器套接字
while(mState!= STATE_CONNECTED)
{
尝试
{
//这是一个阻塞调用,只会返回一个
//成功连接或exception
socket = mmServerSocket.accept();
catch(IOException e)
{
Log.e(TAG,“Socket Type:”+ mSocketType +“accept()failed”,e);
打破;
}
//如果连接被接受
if(socket!= null)
{
同步(BluetoothService.this)
{
开关(mState)
{
情况STATE_LISTEN:
情况STATE_CONNECTING:
//情况正常。 开始连接的线程。
连接(socket,socket.getRemoteDevice(),mSocketType);
打破;
情况STATE_NONE:
情况STATE_CONNECTED:
//未准备好或已经连接。 终止新的套接字。
尝试
{
socket.close();
catch(IOException e)
{
Log.e(TAG,“无法closures不需要的套接字”,e);
}
打破;
}
}
}
}
(D)
{
Log.i(TAG,“END mAcceptThread,socket Type:”+ mSocketType);
}
}
public void cancel()
{
(D)
{
Log.d(TAG,“Socket Type”+ mSocketType +“cancel”+ this);
}
尝试
{
mmServerSocket.close();
catch(IOException e)
{
Log.e(TAG,“套接字types”+ mSocketType +“服务器的close()失败”,e);
}
}
}
/ **
*此线程在尝试build立传出连接时运行
*用设备。 它贯穿始终; 连接要么
*成功或失败。
* /
私有类ConnectThread扩展了Thread
{
私人最终BluetoothSocket mmSocket;
私人最终的BluetoothDevice设备;
私人stringmSocketType;
公共ConnectThread(BluetoothDevice设备,布尔安全)
{
mmDevice = device;
BluetoothSocket tmp = null;
mSocketType =安全吗? “安全”:“不安全”;
//获取与蓝牙连接的BluetoothSocket
//给出BluetoothDevice
尝试
{
如果(安全)
{
tmp = device.createRfcommSocketToServiceRecord(MY_UUID_SECURE);
}别的
{
tmp = device.createInsecureRfcommSocketToServiceRecord(MY_UUID_INSECURE);
}
catch(IOException e)
{
Log.e(TAG,“Socket Type:”+ mSocketType +“create()failed”,e);
}
mmSocket = tmp;
}
@覆盖
public void run()
{
Log.i(TAG,“BEGIN mConnectThread SocketType:”+ mSocketType);
setName(“ConnectThread”+ mSocketType);
//总是取消发现,因为它会减慢连接速度
mAdapter.cancelDiscovery();
//连接到BluetoothSocket
尝试
{
//这是一个阻塞调用,只会返回一个
//成功连接或exception
mmSocket.connect();
catch(IOException e)
{
//closures套接字
尝试
{
mmSocket.close();
catch(IOException e2)
{
Log.e(TAG,“无法在连接失败时closures()”+ mSocketType +“套接字”,e2);
}
连接失败();
返回;
}
//重置ConnectThread,因为我们完成了
同步(BluetoothService.this)
{
mConnectThread = null;
}
尝试
{
//启动连接的线程
连接(mmSocket,mmDevice,mSocketType);
catch(Exception e)
{
Log.e(TAG,“”,e);
}
}
public void cancel()
{
尝试
{
mmSocket.close();
catch(IOException e)
{
Log.e(TAG,“连接的close()”+ mSocketType +“套接字失败”,e);
}
}
}
/ **
*此线程在与远程设备连接期间运行。
*它处理所有传入和传出的传输。
* /
私有类ConnectedThread扩展了Thread
{
私人最终BluetoothSocket mmSocket;
私人最终InputStream mmInStream;
私人最终OutputStream mmOutStream;
公共ConnectedThread(BluetoothSocket套接字,string套接字types)
{
Log.d(TAG,“创buildConnectedThread:”+ socketType);
mmSocket = socket;
InputStream tmpIn = null;
OutputStream tmpOut = null;
//获取BluetoothSocketinput和输出stream
尝试
{
tmpIn = socket.getInputStream();
tmpOut = socket.getOutputStream();
catch(IOException e)
{
Log.e(TAG,“未创build临时套接字”,e);
}
mmInStream = tmpIn;
mmOutStream = tmpOut;
}
@覆盖
public void run()
{
Log.i(TAG,“BEGIN mConnectedThread”);
byte [] buffer = new byte [1024];
int字节;
//连接时保持监听InputStream
而(真)
{
尝试
{
//从InputStream中读取
bytes = mmInStream.read(buffer);
//将获得的字节发送到UI活动
mHandler.obtainMessage(BoeBot.MESSAGE_READ,bytes,-1,buffer).sendToTarget();
catch(IOException e)
{
Log.e(TAG,“disconnected”,e);
connectionLost();
打破;
}
}
}
/ **
*写入连接的OutStream。
* @param buffer要写入的字节
* /
public void write(byte [] buffer)
{
尝试
{
mmOutStream.write(缓冲液);
//将发送的消息分享回UI活动
mHandler.obtainMessage(BoeBot.MESSAGE_WRITE,-1,-1,buffer).sendToTarget();
catch(IOException e)
{
Log.e(TAG,“写入期间的exception”,e);
}
}
public void cancel()
{
尝试
{
mmSocket.close();
catch(IOException e)
{
Log.e(TAG,“连接套接字的close()失败”,e);
}
}
}
}
testing看它是否工作。
BluetoothService mService = new BluetoothService(this, mHandler); mService.write(Bytes);
Google云打印