2012-06-14 61 views
2

我正在創建一個用於連接到帶有平板電腦/手機的嵌入式藍牙設備的程序。我的代碼主要由我已經給出的不同代碼片段組成,並且我已經找到。處理藍牙設備連接的代碼主要來自BlueTerm程序的源代碼。我試圖消除對某個給定類的需求,並開始出現一些我不知道如何解決的錯誤。這是我的出發活動代碼:沒有可以訪問類型Foo的封閉實例

public class AndroidBluetooth extends Activity { 

/** Called when the activity is first created. */ 
    private static BluetoothAdapter myBtAdapter; 
    private static BluetoothDevice myBtDevice; 
    private ArrayAdapter<String> btArrayAdapter; 
    private ArrayList<BluetoothDevice> btDevicesFound = new ArrayList<BluetoothDevice>(); 
    private Button btnScanDevice; 
    private TextView stateBluetooth; 
    private ListView listDevicesFound; 
    private InputStream iStream; 
    private OutputStream oStream; 
    private BluetoothSocket btSocket; 
    private String newDeviceAddress; 
    private BroadcastReceiver mReceiver; 

    private static BluetoothSerialService mSerialService = null; 

    // Intent request codes 
    private static final int REQUEST_CONNECT_DEVICE = 1; 

    private static TextView mTitle; 

    // Message types sent from the BluetoothReadService Handler 
    public static final int MESSAGE_STATE_CHANGE = 1; 
    public static final int MESSAGE_READ = 2; 
    public static final int MESSAGE_WRITE = 3; 
    public static final int MESSAGE_DEVICE_NAME = 4; 
    public static final int MESSAGE_TOAST = 5; 

    // Name of the connected device 
    private String mConnectedDeviceName = null; 

    /** 
    * Set to true to add debugging code and logging. 
    */ 
    public static final boolean D = true; 

    /** 
    * Set to true to log each character received from the remote process to the 
    * android log, which makes it easier to debug some kinds of problems with 
    * emulating escape sequences and control codes. 
    */ 
    public static final boolean LOG_CHARACTERS_FLAG = D && false; 

    /** 
    * Set to true to log unknown escape sequences. 
    */ 
    public static final boolean LOG_UNKNOWN_ESCAPE_SEQUENCES = D && false; 

    private static final String TAG = "ANDROID BLUETOOTH"; 
    private static final int REQUEST_ENABLE_BT = 2; 


    // Member fields 
    //private final Handler mHandler; 
    private ConnectThread mConnectThread; 
    private ConnectedThread mConnectedThread; 
    private int mState; 

    //private EmulatorView mEmulatorView; 

    // Constants that indicate the current connection state 
    public static final int STATE_NONE = 0;  // we're doing nothing 
    public static final int STATE_LISTEN = 1;  // now listening for incoming connections 
    public static final int STATE_CONNECTING = 2; // now initiating an outgoing connection 
    public static final int STATE_CONNECTED = 3; // now connected to a remote device 
    public int currentState; 

    public boolean customTitleSupported; 

    @Override 
    public void onCreate(Bundle savedInstanceState) { 

     super.onCreate(savedInstanceState); 
     currentState = 0; 
     customTitleSupported = requestWindowFeature(Window.FEATURE_CUSTOM_TITLE); 
     // Set up window View 
     setContentView(R.layout.main); 

     stateBluetooth = new TextView(this); 
     myBtAdapter = null; 
     startBluetooth(); 
     CheckBlueToothState(); 

     customTitleBar(getText(R.string.app_name).toString(), stateBluetooth.getText().toString()); 
    } 

    public void customTitleBar(String left, String right) { 
     if(right.length() > 30) right = right.substring(0, 20); 

     if(customTitleSupported) { 
      getWindow().setFeatureInt(Window.FEATURE_CUSTOM_TITLE, R.layout.customlayoutbar); 
      TextView titleTvLeft = (TextView) findViewById(R.id.titleTvLeft); 
      TextView titleTvRight = (TextView) findViewById(R.id.titleTvRight); 

      titleTvLeft.setText(left); 
      titleTvRight.setText(right); 

     } 
    } 

    public boolean onCreateOptionsMenu(Menu menu) { 
     MenuInflater inflater = getMenuInflater(); 
     inflater.inflate(R.menu.option_menu, menu); 
     return true; 
    } 

    public boolean onOptionsItemSelected(MenuItem item) { 
     switch(item.getItemId()) { 
     case R.id.connect: 
      startActivityForResult(new Intent(this, DeviceList.class), REQUEST_CONNECT_DEVICE ); 
      return true; 
     case R.id.preferences: 
      return true; 
     default: 
      return super.onContextItemSelected(item); 
     } 
    } 

    private void CheckBlueToothState() { 
     if(myBtAdapter == null) { 
      stateBluetooth.setText("Bluetooth NOT supported"); 
     } else { 
      if(myBtAdapter.isEnabled()) { 
       if(myBtAdapter.isDiscovering()) { 
        stateBluetooth.setText("Bluetooth is currently " + 
         "in device discovery process."); 
       } else { 
        stateBluetooth.setText("Bluetooth is Enabled."); 
       } 
      } else { 
       stateBluetooth.setText("Bluetooth is NOT enabled"); 
       Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE); 
       startActivityForResult(enableBtIntent, REQUEST_ENABLE_BT); 
      } 
     } 
    } 

    public void onActivityResult(int requestCode, int resultCode, Intent data) { 
     if(D) Log.d(TAG, "onActivityResult " + resultCode); 
     switch (requestCode) { 

     case REQUEST_CONNECT_DEVICE: 

      // When DeviceListActivity returns with a device to connect 
      if (resultCode == Activity.RESULT_OK) { 
       // Get the device MAC address 
       String address = data.getExtras() 
           .getString(DeviceList.EXTRA_DEVICE_ADDRESS); 
       // Get the BLuetoothDevice object 
       BluetoothDevice device = myBtAdapter.getRemoteDevice(address); 
       // Attempt to connect to the device 
       connect(device);     
      } 
      break; 

     case REQUEST_ENABLE_BT: 
      // When the request to enable Bluetooth returns 
      CheckBlueToothState(); 
     } 
    } 

    public synchronized void connect(BluetoothDevice device) { 
     if (D) Log.d(TAG, "connect to: " + device); 

     // Cancel any thread attempting to make a connection 
     if (mState == STATE_CONNECTING) { 
      if (mConnectThread != null) {mConnectThread.cancel(); mConnectThread = null;} 
     } 

     // Cancel any thread currently running a connection 
     if (mConnectedThread != null) {mConnectedThread.cancel(); mConnectedThread = null;} 

     // Start the thread to connect with the given device 
     mConnectThread = new ConnectThread(device); 
     mConnectThread.start(); 
     mSerialService.setState(STATE_CONNECTING); 
    } 

    //In SDK15 (4.0.3) this method is now public as 
    //Bluetooth.fetchUuisWithSdp() and BluetoothDevice.getUuids() 
    public ParcelUuid[] servicesFromDevice(BluetoothDevice device) { 
     try { 
      Class cl = Class.forName("android.bluetooth.BluetoothDevice"); 
      Class[] par = {}; 
      Method method = cl.getMethod("getUuids", par); 
      Object[] args = {}; 
      ParcelUuid[] retval = (ParcelUuid[]) method.invoke(device, args); 
      return retval; 
     } catch (Exception e) { 
      e.printStackTrace(); 
      return null; 
     } 
    } 

    private final BroadcastReceiver ActionFoundReceiver = new BroadcastReceiver() { 
     public void onReceive(Context context, Intent intent) { 
      String action = intent.getAction(); 
      if(BluetoothDevice.ACTION_FOUND.equals(action)) { 
       BluetoothDevice btDevice = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE); 
       btDevicesFound.add(btDevice); 
       btArrayAdapter.add(btDevice.getName() + "\n" + btDevice.getAddress()); 
       btArrayAdapter.notifyDataSetChanged(); 
      }   
     } 
    }; 
    public static void startBluetooth(){ 
     try { 
      myBtAdapter = BluetoothAdapter.getDefaultAdapter(); 
      myBtAdapter.enable(); 
     } catch (NullPointerException ex) { 
      Log.e("Bluetooth", "Device not available"); 
     } 
    } 

    public static void stopBluetooth() { 
     myBtAdapter.disable(); 
    } 
} 

大約三十排隊從底部connect()方法是在錯誤發生。行mConnectThread = new ConnectThread(device);帶下劃線,錯誤消息說:

沒有可以訪問類型BluetoothSerialService的封閉實例。必須使用封閉的BluetoothSerialService類型實例(例如x.new A(),其中x是BluetoothSerialService的一個實例)限定分配。

這是我目前擁有的BluetoothSerialService代碼:

public class BluetoothSerialService { 
// Debugging 
private static final String TAG = "BluetoothReadService"; 
private static final boolean D = true; 


private static final UUID SerialPortServiceClass_UUID = UUID.fromString("00001101-0000-1000-8000-00805F9B34FB"); 

// Member fields 
private final BluetoothAdapter mAdapter; 
private final Handler mHandler; 
private ConnectThread mConnectThread; 
private ConnectedThread mConnectedThread; 
private int mState; 

//private EmulatorView mEmulatorView; 

// Constants that indicate the current connection state 
public static final int STATE_NONE = 0;  // we're doing nothing 
public static final int STATE_LISTEN = 1;  // now listening for incoming connections 
public static final int STATE_CONNECTING = 2; // now initiating an outgoing connection 
public static final int STATE_CONNECTED = 3; // now connected to a remote device 

/** 
* Constructor. Prepares a new BluetoothChat session. 
* @param context The UI Activity Context 
* @param handler A Handler to send messages back to the UI Activity 
*/ 
public BluetoothSerialService(Context context, Handler handler) { //EmulatorView emulatorView) { 
    mAdapter = BluetoothAdapter.getDefaultAdapter(); 
    mState = STATE_NONE; 
    mHandler = handler; 
    //mEmulatorView = emulatorView; 
} 

/** 
* Set the current state of the chat connection 
* @param state An integer defining the current connection state 
*/ 
public synchronized void setState(int state) { 
    if (D) Log.d(TAG, "setState() " + mState + " -> " + state); 
    mState = state; 

    // Give the new state to the Handler so the UI Activity can update 
    mHandler.obtainMessage(AndroidBluetooth.MESSAGE_STATE_CHANGE, state, -1).sendToTarget(); 
} 

/** 
* Return the current connection state. */ 
public synchronized int getState() { 
    return mState; 
} 

/** 
* Start the chat service. Specifically start AcceptThread to begin a 
* session in listening (server) mode. Called by the Activity onResume() */ 
public synchronized void start() { 
    if (D) Log.d(TAG, "start"); 

    // Cancel any thread attempting to make a connection 
    if (mConnectThread != null) { 
     mConnectThread.cancel(); 
     mConnectThread = null; 
    } 

    // Cancel any thread currently running a connection 
    if (mConnectedThread != null) { 
     mConnectedThread.cancel(); 
     mConnectedThread = null; 
    } 

    setState(STATE_NONE); 
} 

/** 
* Start the ConnectThread to initiate a connection to a remote device. 
* @param device The BluetoothDevice to connect 
*/ 
public synchronized void connect(BluetoothDevice device) { 
    if (D) Log.d(TAG, "connect to: " + device); 

    // Cancel any thread attempting to make a connection 
    if (mState == STATE_CONNECTING) { 
     if (mConnectThread != null) {mConnectThread.cancel(); mConnectThread = null;} 
    } 

    // Cancel any thread currently running a connection 
    if (mConnectedThread != null) {mConnectedThread.cancel(); mConnectedThread = null;} 

    // Start the thread to connect with the given device 
    mConnectThread = new ConnectThread(device); 
    mConnectThread.start(); 
    setState(STATE_CONNECTING); 
} 

/** 
* Start the ConnectedThread to begin managing a Bluetooth connection 
* @param socket The BluetoothSocket on which the connection was made 
* @param device The BluetoothDevice that has been connected 
*/ 
public synchronized void connected(BluetoothSocket socket, BluetoothDevice device) { 
    if (D) Log.d(TAG, "connected"); 

    // Cancel the thread that completed the connection 
    if (mConnectThread != null) { 
     mConnectThread.cancel(); 
     mConnectThread = null; 
    } 

    // Cancel any thread currently running a connection 
    if (mConnectedThread != null) { 
     mConnectedThread.cancel(); 
     mConnectedThread = null; 
    } 

    // Start the thread to manage the connection and perform transmissions 
    mConnectedThread = new ConnectedThread(socket); 
    mConnectedThread.start(); 

    // Send the name of the connected device back to the UI Activity 
    //Message msg = mHandler.obtainMessage(BlueTerm.MESSAGE_DEVICE_NAME); 
    Bundle bundle = new Bundle(); 
    //bundle.putString(BlueTerm.DEVICE_NAME, device.getName()); 
    //msg.setData(bundle); 
    //mHandler.sendMessage(msg); 

    setState(STATE_CONNECTED); 
} 

/** 
* Stop all threads 
*/ 
public synchronized void stop() { 
    if (D) Log.d(TAG, "stop"); 


    if (mConnectThread != null) { 
     mConnectThread.cancel(); 
     mConnectThread = null; 
    } 

    if (mConnectedThread != null) { 
     mConnectedThread.cancel(); 
     mConnectedThread = null; 
    } 

    setState(STATE_NONE); 
} 

/** 
* Write to the ConnectedThread in an unsynchronized manner 
* @param out The bytes to write 
* @see ConnectedThread#write(byte[]) 
*/ 
public void write(byte[] out) { 
    // Create temporary object 
    ConnectedThread r; 
    // Synchronize a copy of the ConnectedThread 
    synchronized (this) { 
     if (mState != STATE_CONNECTED) return; 
     r = mConnectedThread; 
    } 
    // Perform the write unsynchronized 
    r.write(out); 
} 

/** 
* Indicate that the connection attempt failed and notify the UI Activity. 
*/ 
private void connectionFailed() { 
    setState(STATE_NONE); 

    // Send a failure message back to the Activity 
    //Message msg = mHandler.obtainMessage(BlueTerm.MESSAGE_TOAST); 
    Bundle bundle = new Bundle(); 
    //bundle.putString(BlueTerm.TOAST, "Unable to connect device"); 
    //msg.setData(bundle); 
    //mHandler.sendMessage(msg); 
} 

/** 
* Indicate that the connection was lost and notify the UI Activity. 
*/ 
private void connectionLost() { 
    setState(STATE_NONE); 

    // Send a failure message back to the Activity 
    //Message msg = mHandler.obtainMessage(BlueTerm.MESSAGE_TOAST); 
    Bundle bundle = new Bundle(); 
    //bundle.putString(BlueTerm.TOAST, "Device connection was lost"); 
    //msg.setData(bundle); 
    //mHandler.sendMessage(msg); 
} 

/** 
* This thread runs while attempting to make an outgoing connection 
* with a device. It runs straight through; the connection either 
* succeeds or fails. 
*/ 
public class ConnectThread extends Thread { 
    private final BluetoothSocket mmSocket; 
    private final BluetoothDevice mmDevice; 

    public ConnectThread(BluetoothDevice device) { 
     mmDevice = device; 
     BluetoothSocket tmp = null; 

     // Get a BluetoothSocket for a connection with the 
     // given BluetoothDevice 
     try { 
      tmp = device.createRfcommSocketToServiceRecord(SerialPortServiceClass_UUID); 
     } catch (IOException e) { 
      Log.e(TAG, "create() failed", e); 
     } 
     mmSocket = tmp; 
    } 

    public void run() { 
     Log.i(TAG, "BEGIN mConnectThread"); 
     setName("ConnectThread"); 

     // Always cancel discovery because it will slow down a connection 
     mAdapter.cancelDiscovery(); 

     // Make a connection to the BluetoothSocket 
     try { 
      // This is a blocking call and will only return on a 
      // successful connection or an exception 
      mmSocket.connect(); 
     } catch (IOException e) { 
      connectionFailed(); 
      // Close the socket 
      try { 
       mmSocket.close(); 
      } catch (IOException e2) { 
       Log.e(TAG, "unable to close() socket during connection failure", e2); 
      } 
      // Start the service over to restart listening mode 
      //BluetoothSerialService.this.start(); 
      return; 
     } 

     // Reset the ConnectThread because we're done 
     synchronized (BluetoothSerialService.this) { 
      mConnectThread = null; 
     } 

     // Start the connected thread 
     connected(mmSocket, mmDevice); 
    } 

    public void cancel() { 
     try { 
      mmSocket.close(); 
     } catch (IOException e) { 
      Log.e(TAG, "close() of connect socket failed", e); 
     } 
    } 
} 

/** 
* This thread runs during a connection with a remote device. 
* It handles all incoming and outgoing transmissions. 
*/ 
public class ConnectedThread extends Thread { 
    private final BluetoothSocket mmSocket; 
    private final InputStream mmInStream; 
    private final OutputStream mmOutStream; 


    public ConnectedThread(BluetoothSocket socket) { 
     Log.d(TAG, "create ConnectedThread"); 
     mmSocket = socket; 
     InputStream tmpIn = null; 
     OutputStream tmpOut = null; 

     // Get the BluetoothSocket input and output streams 
     try { 
      tmpIn = socket.getInputStream(); 
      tmpOut = socket.getOutputStream(); 
     } catch (IOException e) { 
      Log.e(TAG, "temp sockets not created", e); 
     } 

     mmInStream = tmpIn; 
     mmOutStream = tmpOut; 
    } 

    public void run() { 
     Log.i(TAG, "BEGIN mConnectedThread"); 
     byte[] buffer = new byte[1024]; 
     int bytes; 

     // Keep listening to the InputStream while connected 
     while (true) { 
      try { 
       // Read from the InputStream 
       bytes = mmInStream.read(buffer); 

       //mEmulatorView.write(buffer, bytes); 
       // Send the obtained bytes to the UI Activity 
       //mHandler.obtainMessage(BlueTerm.MESSAGE_READ, bytes, -1, buffer).sendToTarget(); 

       String a = buffer.toString(); 
       a = ""; 
      } catch (IOException e) { 
       Log.e(TAG, "disconnected", e); 
       connectionLost(); 
       break; 
      } 
     } 
    } 

    /** 
    * Write to the connected OutStream. 
    * @param buffer The bytes to write 
    */ 
    public void write(byte[] buffer) { 
     try { 
      mmOutStream.write(buffer); 

      // Share the sent message back to the UI Activity 
      //mHandler.obtainMessage(BlueTerm.MESSAGE_WRITE, buffer.length, -1, buffer) 
        //.sendToTarget(); 
     } catch (IOException e) { 
      Log.e(TAG, "Exception during write", e); 
     } 
    } 

    public void cancel() { 
     try { 
      mmSocket.close(); 
     } catch (IOException e) { 
      Log.e(TAG, "close() of connect socket failed", e); 
     } 
    } 
} 
} 
+0

如果任何人有關於如何清理我的代碼,我也將不勝感激的任何建議。我對Android應用程序的結構仍然感到不舒服,尤其是包括藍牙在內的應用程序的結構。我知道這是非常糟糕的組織。 – JuiCe

回答

5

是對BluetoothSerialService一個內部類?如果是這樣,使其成爲static

看到這個職位

No enclosing instance of type Server is accessible

+0

我創建的BluetoothSerialService對象是靜態的。 – JuiCe

+0

不是對象......但是類...'公共靜態類BluetoothSerialService' – stuckless

+0

現在,我回頭看,這可能與您所說的內容有關。 ConnectThread是BluetoothSerialService的內部類。我應該讓ConnectThread是靜態的嗎? – JuiCe

相關問題