我正在尝试使用蓝牙将手机的陀螺仪,加速度计值发送到我的电脑, 我正在使用bluecove java api用于客户端(pc)。
服务器代码:
package com.example.kphan.bluetooth_transfer;
import android.annotation.SuppressLint;
import android.content.Context;
import android.content.Intent;
import android.hardware.SensorEventListener;
import android.os.Handler;
import android.os.Message;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.hardware.SensorEvent;
import android.hardware.Sensor;
import android.hardware.SensorManager;
import android.bluetooth.*;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.nio.ByteBuffer;
import java.util.Set;
import java.util.UUID;
public class MainActivity extends AppCompatActivity implements SensorEventListener {
private SensorManager senSensorManager;
private Sensor senAccelerometer ;
private Sensor senGyroscope;
private TextView tv1;
private TextView tv2;
private boolean clicked = false;
private float AccX,AccY,AccZ,GyroX,GyroY,GyroZ;
private Button mvBtn;
private BluetoothAdapter bAdapter;
String deviceName,deviceAddress;
private ConnectThread mConnectThread;
private Handler mHandler;
String TAG = "bluetooth";
@Override
protected void onCreate(Bundle savedInstanceState) throws NullPointerException{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
tv1 = (TextView)findViewById(R.id.TextView01);
tv2 = (TextView)findViewById(R.id.TextView02);
mvBtn = (Button)findViewById(R.id.button_send);
bAdapter = BluetoothAdapter.getDefaultAdapter();
if(!bAdapter.isEnabled()){
Intent enableBTIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
startActivityForResult(enableBTIntent,1);
}
senSensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
senAccelerometer = senSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
senGyroscope = senSensorManager.getDefaultSensor(Sensor.TYPE_GYROSCOPE);
senSensorManager.registerListener(this, senAccelerometer, SensorManager.SENSOR_DELAY_NORMAL);
senSensorManager.registerListener(this, senGyroscope, SensorManager.SENSOR_DELAY_NORMAL);
Set<BluetoothDevice> pairedDevices = bAdapter.getBondedDevices();
if(pairedDevices.size() > 0){
for(BluetoothDevice device : pairedDevices){
deviceName = device.getName();
deviceAddress = device.getAddress();
mConnectThread = new ConnectThread(device);
mConnectThread.start();
}
}
}
private class ConnectThread extends Thread{
private final BluetoothSocket mmSocket;
private final BluetoothDevice mmDevice;
private final UUID myUUID = UUID.fromString("00001101-0000-1000-8000-00805F9B34FB");
public ConnectedThread mConnectedThread;
ConnectThread(BluetoothDevice device){
BluetoothSocket tmp = null;
mmDevice = device;
try{
tmp = device.createRfcommSocketToServiceRecord(myUUID);
}catch(IOException e){}
mmSocket = tmp;
mConnectedThread = new ConnectedThread(mmSocket);
}
public void run(){
bAdapter.cancelDiscovery();
try{
mmSocket.connect();
mConnectedThread.start();
}catch(IOException e){
try{
mmSocket.close();
}catch(IOException e1){
return;
}
}
}
public void close(){
try {
mmSocket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
public boolean socketAccquired(){
if(mmSocket != null) {
return true;
}
else
return false;
}
}
private class ConnectedThread extends Thread{
private final BluetoothSocket mmSocket;
private final OutputStream mmOutStream;
private byte[] mmBuffer;
public ConnectedThread(BluetoothSocket socket){
mmSocket = socket;
OutputStream tmpOut= null;
try{
tmpOut = socket.getOutputStream();
}catch(IOException e){}
mmOutStream = tmpOut;
}
public void run(){
mmBuffer = new byte[1024];
}
public void write(byte[] bytes){
String message = new String(bytes);
Log.d(TAG,"...Data to send: " + message + "...");
try {
mmOutStream.write(bytes);
}catch(IOException e){}
}
public void cancel(){
try{
mmSocket.close();
}catch(IOException e){}
}
}
@Override
public void onSensorChanged(SensorEvent sensorEvent) {
Sensor mySensor = sensorEvent.sensor;
if(mySensor.getType() == Sensor.TYPE_ACCELEROMETER){
AccX = sensorEvent.values[0];
AccY = sensorEvent.values[1];
AccZ = sensorEvent.values[2];
String x = String.valueOf(AccX);
String y = String.valueOf(AccY);
String z = String.valueOf(AccZ);
String x1 = String.valueOf(GyroX);
String y1 = String.valueOf(GyroY);
String z1 = String.valueOf(GyroZ);
tv1.setText("AccX = "+x+"\n"+"AccY = "+y+"\n"+"AccZ = "+z+"\n");
if(mConnectThread.socketAccquired()) {
mConnectThread.mConnectedThread.write(float2ByteArray(AccX));
mConnectThread.mConnectedThread.write(float2ByteArray(AccY));
mConnectThread.mConnectedThread.write(float2ByteArray(AccZ));
mConnectThread.mConnectedThread.write(float2ByteArray(GyroX));
mConnectThread.mConnectedThread.write(float2ByteArray(GyroY));
mConnectThread.mConnectedThread.write(float2ByteArray(GyroZ));
mConnectThread.mConnectedThread.write((String.valueOf(clicked)).getBytes());
}
}
else if(mySensor.getType() == Sensor.TYPE_GYROSCOPE){
GyroX = sensorEvent.values[0];
GyroY = sensorEvent.values[1];
GyroZ = sensorEvent.values[2];
String x = String.valueOf(GyroX);
String y = String.valueOf(GyroY);
String z = String.valueOf(GyroZ);
String x1 = String.valueOf(AccX);
String y1 = String.valueOf(AccY);
String z1 = String.valueOf(AccZ);
tv2.setText("GyroX = "+x+"\n"+"GyroY = "+y+"\n"+"GyroZ = "+z+ "\n" +
"\n" +
"click = " +String.valueOf(clicked));
if(mConnectThread.socketAccquired()) {
mConnectThread.mConnectedThread.write(float2ByteArray(AccX));
mConnectThread.mConnectedThread.write(float2ByteArray(AccY));
mConnectThread.mConnectedThread.write(float2ByteArray(AccZ));
mConnectThread.mConnectedThread.write(float2ByteArray(GyroX));
mConnectThread.mConnectedThread.write(float2ByteArray(GyroY));
mConnectThread.mConnectedThread.write(float2ByteArray(GyroZ));
mConnectThread.mConnectedThread.write((String.valueOf(clicked)).getBytes());
}
}
}
@Override
public void onAccuracyChanged(Sensor sensor, int i) {
}
@Override
protected void onPause(){
super.onPause();
senSensorManager.unregisterListener(this);
if(mConnectThread.socketAccquired()){
try {
mConnectThread.mConnectedThread.mmOutStream.flush();
} catch (IOException e) {
e.printStackTrace();
}
}
}
@Override
protected void onResume(){
super.onResume();
senSensorManager.registerListener(this,senAccelerometer,SensorManager.SENSOR_DELAY_NORMAL);
senSensorManager.registerListener(this,senGyroscope,SensorManager.SENSOR_DELAY_NORMAL);
}
public void sendMessage(View view){
if(clicked){
clicked = false;
}
else{
clicked = true;
}
}
public static byte [] float2ByteArray (float value)
{
return ByteBuffer.allocate(4).putFloat(value).array();
}
}
我将传感器的单个字节值发送到输出流,它正常工作,因为我可以在logcat中看到它。
客户代码:
public class Bluetooth {
boolean scanFinished = false;
RemoteDevice bluetoothdevice;
String connectionUrl;
public static void main(String[] args) {
try {
new Bluetooth().go();
} catch (Exception ex) {
Logger.getLogger(Bluetooth.class.getName()).log(Level.SEVERE, null, ex);
}
}
private void go() throws Exception {
scanFinished = false;
LocalDevice.getLocalDevice().getDiscoveryAgent().startInquiry(DiscoveryAgent.GIAC, new DiscoveryListener() {
@Override
public void deviceDiscovered(RemoteDevice btDevice, DeviceClass cod) {
try {
String name = btDevice.getFriendlyName(false);
if (name.matches("Mi.*")) {
System.out.format("%s (%s)\n", name, btDevice.getBluetoothAddress());
bluetoothdevice = btDevice;
return;
}
} catch (IOException e) {
e.printStackTrace();
}
}
@Override
public void inquiryCompleted(int discType) {
scanFinished = true;
}
@Override
public void serviceSearchCompleted(int transID, int respCode) {
}
@Override
public void servicesDiscovered(int transID, ServiceRecord[] servRecord) {
}
});
while (!scanFinished) {
Thread.sleep(500);
}
UUID uuid = new UUID(0x1101);
UUID[] searchUuidSet = new UUID[]{uuid};
LocalDevice.getLocalDevice().getDiscoveryAgent().searchServices(null, searchUuidSet,
bluetoothdevice, new DiscoveryListener() {
@Override
public void deviceDiscovered(RemoteDevice btDevice, DeviceClass cod) {
}
@Override
public void inquiryCompleted(int discType) {
}
@Override
public void serviceSearchCompleted(int transID, int respCode) {
scanFinished = true;
}
@Override
public void servicesDiscovered(int transID, ServiceRecord[] servRecord) {
for (int i = 0; i < servRecord.length; i++) {
connectionUrl = servRecord[i].getConnectionURL(ServiceRecord.NOAUTHENTICATE_NOENCRYPT, false);
if (connectionUrl != null) {
break;
}
}
}
});
if(connectionUrl == null) {
System.out.println("could not establish connection");return;
}
StreamConnection streamConnection = (StreamConnection)Connector.open(connectionUrl);
while(true) {
RemoteDevice dev = RemoteDevice.getRemoteDevice(streamConnection);
System.out.println("Remote device address: "+dev.getBluetoothAddress());
System.out.println("Remote device name: "+dev.getFriendlyName(true));
Thread processThread = new Thread(new processConnThread(streamConnection));
processThread.start();
}
}
所以我基本上要做的是从我的手机获取传感器数据并尝试将其发送到我的电脑。我能够检测到我的手机“Mi Al”但是connectionUrl似乎是空的。
为什么connectionUrl为null?