2017-03-23 20 views
0

領収書をBluetoothの外部プリンタに印刷するアプリケーションを作成しています。私は正常に彼らのSDKを構成することができ、外部デバイスに印刷することができます!私が実装した方法は、印刷ボタンをクリックするとペアデバイスを検索し、プリンタを選択するとMac IDを優先して呼び出して印刷機能を呼び出します。次回は印刷ボタンをクリックすると、デバイスのMAC IDがあり、印刷を呼び出すような、prefernceのような検索はしません!Bluetooth外部サーマルプリンタに接続するときに切断する

私が直面している問題は、最初に印刷ボタンをクリックしたときに動作し、印刷します。デバイス接続が切断され、トーストポップアップに接続できなくなり、印刷が行われません。再び私はそれが正常に印刷接続されます。これは起き続ける!私のデバイスがいつかアイドル状態のままにしておけば、プリントもできます!ブルートゥースの電源を入れ直したときにもプリントが発生します。

マイBluetoothのサービス:

public class BluetoothService { 
    // Debugging 
    private static final String TAG = "BluetoothService"; 
    private static final boolean DEBUG = true; 

    // Name for the SDP record when creating server socket 
    private static final String NAME = "ZJPrinter"; 
    //UUID must be this 
    // Unique UUID for this application 
    private static final UUID MY_UUID = UUID.fromString("00001101-0000-1000-8000-00805F9B34FB"); 

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

    // 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 static String ErrorMessage = "No_Error_Message"; 
    /** 
    * Constructor. Prepares a new BTPrinter session. 
    * @param context The UI Activity Context 
    * @param handler A Handler to send messages back to the UI Activity 
    */ 
    public BluetoothService(Context context, Handler handler) { 
     mAdapter = BluetoothAdapter.getDefaultAdapter(); 
     mState = STATE_NONE; 
     mHandler = handler; 
    } 


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

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

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

    /** 
    * Start the service. Specifically start AcceptThread to begin a 
    * session in listening (server) mode. Called by the Activity onResume() */ 
    public synchronized void start() { 
     if (DEBUG) 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;} 

     // Start the thread to listen on a BluetoothServerSocket 
     if (mAcceptThread == null) { 
      mAcceptThread = new AcceptThread(); 
      mAcceptThread.start(); 
     } 
     setState(STATE_LISTEN); 
    } 

    /** 
    * Start the ConnectThread to initiate a connection to a remote device. 
    * @param device The BluetoothDevice to connect 
    */ 
    public synchronized void connect(BluetoothDevice device) { 
     if (DEBUG) 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 (DEBUG) 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;} 

     // Cancel the accept thread because we only want to connect to one device 
     if (mAcceptThread != null) {mAcceptThread.cancel(); mAcceptThread = 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(PrintBluetooth.MESSAGE_DEVICE_NAME); 
     Bundle bundle = new Bundle(); 
     bundle.putString(PrintBluetooth.DEVICE_NAME, device.getName()); 
     msg.setData(bundle); 
     mHandler.sendMessage(msg); 

     setState(STATE_CONNECTED); 
    } 

    /** 
    * Stop all threads 
    */ 
    public synchronized void stop() { 
     if (DEBUG) Log.d(TAG, "stop"); 
     setState(STATE_NONE); 
     if (mConnectThread != null) {mConnectThread.cancel(); mConnectThread = null;} 
     if (mConnectedThread != null) {mConnectedThread.cancel(); mConnectedThread = null;} 
     if (mAcceptThread != null) {mAcceptThread.cancel(); mAcceptThread = null;} 
    } 

    /** 
    * 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; 
     } 
     r.write(out); 
    } 

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

     // Send a failure message back to the Activity 
     Message msg = mHandler.obtainMessage(PrintBluetooth.MESSAGE_TOAST); 
     Bundle bundle = new Bundle(); 
     bundle.putString(PrintBluetooth.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_LISTEN); 

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

    /** 
    * This thread runs while listening for incoming connections. It behaves 
    * like a server-side client. It runs until a connection is accepted 
    * (or until cancelled). 
    */ 
    private class AcceptThread extends Thread { 
     // The local server socket 
     private final BluetoothServerSocket mmServerSocket; 

     public AcceptThread() { 
      BluetoothServerSocket tmp = null; 

      // Create a new listening server socket 
      try { 
       tmp = mAdapter.listenUsingRfcommWithServiceRecord(NAME, MY_UUID); 
      } catch (IOException e) { 
       Log.e(TAG, "listen() failed", e); 
      } 
      mmServerSocket = tmp; 
     } 

     @Override 
     public void run() { 
      if (DEBUG) Log.d(TAG, "BEGIN mAcceptThread" + this); 
      setName("AcceptThread"); 
      BluetoothSocket socket = null; 

      // Listen to the server socket if we're not connected 
      while (mState != STATE_CONNECTED) { 
       try { 
        // This is a blocking call and will only return on a 
        // successful connection or an exception 
        socket = mmServerSocket.accept(); 
       } catch (IOException e) { 
        Log.e(TAG, "accept() failed", e); 
        break; 
       } 

       // If a connection was accepted 
       if (socket != null) { 
        synchronized (BluetoothService.this) { 
         switch (mState) { 
         case STATE_LISTEN: 
         case STATE_CONNECTING: 
          // Situation normal. Start the connected thread. 
          connected(socket, socket.getRemoteDevice()); 
          break; 
         case STATE_NONE: 
         case STATE_CONNECTED: 
          // Either not ready or already connected. Terminate new socket. 
          try { 
           socket.close(); 
          } catch (IOException e) { 
           Log.e(TAG, "Could not close unwanted socket", e); 
          } 
          break; 
         } 
        } 
       } 
      } 
      if (DEBUG) Log.i(TAG, "END mAcceptThread"); 
     } 

     public void cancel() { 
      if (DEBUG) Log.d(TAG, "cancel " + this); 
      try { 
       mmServerSocket.close(); 
      } catch (IOException e) { 
       Log.e(TAG, "close() of server failed", e); 
      } 
     } 
    } 


    /** 
    * This thread runs while attempting to make an outgoing connection 
    * with a device. It runs straight through; the connection either 
    * succeeds or fails. 
    */ 
    private 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(MY_UUID); 
      } catch (IOException e) { 
       Log.e(TAG, "create() failed", e); 
      } 
      mmSocket = tmp; 
     } 

     @Override 
     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) { 
       Log.e("ERRROR :::::","INSIDE CATCH RUN"); 
       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 
       BluetoothService.this.start(); 
       return; 
      } 

      // Reset the ConnectThread because we're done 
      synchronized (BluetoothService.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. 
    */ 
    private 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; 
     } 

     @Override 
     public void run() { 
      Log.i(TAG, "BEGIN mConnectedThread"); 
      int bytes; 

      // Keep listening to the InputStream while connected 
      while (true) { 
       try { 
        byte[] buffer = new byte[256]; 
        // Read from the InputStream 
        bytes = mmInStream.read(buffer); 
        if(bytes>0) 
        { 
         // Send the obtained bytes to the UI Activity 
         mHandler.obtainMessage(PrintBluetooth.MESSAGE_READ, bytes, -1, buffer) 
           .sendToTarget(); 
        } 
        else 
        { 
         Log.e(TAG, "disconnected"); 
         connectionLost(); 

         //add by chongqing jinou 
         if(mState != STATE_NONE) 
         { 
          Log.e(TAG, "disconnected"); 
         // Start the service over to restart listening mode 
          BluetoothService.this.start(); 
         } 
         break; 
        } 
       } catch (IOException e) { 
        Log.e(TAG, "disconnected", e); 
        connectionLost(); 

        //add by chongqing jinou 
        if(mState != STATE_NONE) 
        { 
         // Start the service over to restart listening mode 
         BluetoothService.this.start(); 
        } 
        break; 
       } 
      } 
     } 

     /** 
     * Write to the connected OutStream. 
     * @param buffer The bytes to write 
     */ 
     public void write(byte[] buffer) { 
      try { 
       mmOutStream.write(buffer); 
       mmOutStream.flush();//清空缓存 
       /* if (buffer.length > 3000) // 
       { 
        byte[] readata = new byte[1]; 
        SPPReadTimeout(readata, 1, 5000); 
       }*/ 
       Log.i("BTPWRITE", new String(buffer,"GBK")); 
       // Share the sent message back to the UI Activity 
       mHandler.obtainMessage(PrintBluetooth.MESSAGE_WRITE, -1, -1, buffer) 
         .sendToTarget(); 
      } catch (IOException e) { 
       Log.e(TAG, "Exception during write", e); 
      } 
     } 

     /* 
     // 
     private boolean SPPReadTimeout(byte[] Data, int DataLen, int Timeout){ 
      for (int i = 0; i < Timeout/5; i++) 
      { 
      try 
      { 
       if (mmInStream.available() >= DataLen) 
       { 
       try 
       { 
        mmInStream.read(Data, 0, DataLen); 
        return true; 
       } 
       catch (IOException e) 
       { 
        ErrorMessage = "读取蓝牙数据失败"; 
        return false; 
       } 
       } 
      } 
      catch (IOException e) 
      { 
       ErrorMessage = "读取蓝牙数据失败"; 
       return false; 
      } 
      try 
      { 
       Thread.sleep(5L); 
      } 
      catch (InterruptedException e) 
      { 
       ErrorMessage = "读取蓝牙数据失败"; 
       return false; 
      } 
      } 
      ErrorMessage = "蓝牙读数据超时"; 
      return false; 
     } 
     */ 
     public void cancel() { 
      try { 
       mmSocket.close(); 
      } catch (IOException e) { 
       Log.e(TAG, "close() of connect socket failed", e); 
      } 
     } 
    } 

アクティビティコード:

http://52.221.44.206/mobeeload/PrintBluetooth.java

・ログ・エラー:

03-23 11:17:08.639 15416-17471/in.juasoft.mobeeload E/BluetoothService: disconnected 
                     java.io.IOException: bt socket closed, read return: -1 
                      at android.bluetooth.BluetoothSocket.read(BluetoothSocket.java:578) 
                      at android.bluetooth.BluetoothInputStream.read(BluetoothInputStream.java:96) 
                      at java.io.InputStream.read(InputStream.java:162) 
                      at in.juasoft.mobeeload.BluetoothService$ConnectedThread.run(BluetoothService.java:387) 
03-23 11:17:08.641 15416-17716/in.juasoft.mobeeload E/ERRROR :::::: INSIDE CATCH RUN 

答えて

0

あなたがバックグラウンドでBluetooth接続を維持する必要があります。 Bluetoothサービス作成コードをAndroidサービスに移動し、ローカルバインダーを使用してサービスオブジェクトとそのメソッドにアクセスします。

関連する問題