Android - 蓝牙在启动不同活动后断开连接

时间:2016-07-01 14:43:39

标签: android android-activity printing bluetooth

我正在为使用蓝牙打印机的Android做一个学校项目。我从某人那里买了一个蓝牙设备并给了我一个代码片段,如下所示。我根据自己的喜好编辑了它。代码,应用程序和蓝牙打印机正在运行。但我的问题是。原始代码设计用于在1个活动中打印扫描和打印。我想分开扫描蓝牙和打印活动。在我的扫描活动中,从列表视图中选择设备后,我将被重定向回主活动。在主要活动中,我与蓝牙设备断开连接。如何在整个应用程序中选择蓝牙或在应用程序内选择的活动后保持蓝牙的连接。

public class BlueToothService {

private BluetoothAdapter adapter;
private Context context;
private int mState;
private int scanState = 1;
private Boolean D = true;
private String TAG = "BlueToothService";
private AcceptThread mAcceptThread;
private ConnectThread mConnectThread;
private ConnectedThread mConnectedThread;

public static final int STATE_NONE = 0;
public static final int STATE_LISTEN = 1;
public static final int STATE_CONNECTING = 2;
public static final int STATE_CONNECTED = 3;
public static final int LOSE_CONNECT = 4;
public static final int FAILED_CONNECT = 5;
public static final int SUCCESS_CONNECT = 6;

public static final int MESSAGE_STATE_CHANGE = 1;
public static final int MESSAGE_WRITE = 3;
public static final int STATE_SCANING = 0;
public static final int STATE_SCAN_STOP = 1;

private static final int WRITE_READ = 2;
private static final int WRITE_WAIT = 3;
private static int writeState = 2;
private static int PrinterType = 0;
private static int PrinterTypeNow = 0;

private void SetWriteState(int state) {
    synchronized (this) {
        writeState = state;
    }
}

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

private static final String NAME = "BTPrinter";

private Handler mHandler;

public BlueToothService(Context context, Handler handler) {
    this.context = context;
    this.mHandler = handler;
    mState = STATE_NONE;
    adapter = BluetoothAdapter.getDefaultAdapter();
}

public boolean IsOpen() {
    synchronized (this) {
        if (adapter.isEnabled()) {
            return true;
        }
        return false;
    }
}

public void OpenDevice() {
    Intent intent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
    context.startActivity(intent);
}

public void CloseDevice() {
    adapter.disable();
}

public Set<BluetoothDevice> GetBondedDevice() {
    Set<BluetoothDevice> devices = adapter.getBondedDevices();
    return devices;
}

public void ScanDevice() {
    IntentFilter filter = new IntentFilter(BluetoothDevice.ACTION_FOUND);
    context.registerReceiver(mReceiver, filter);

    filter = new IntentFilter(BluetoothAdapter.ACTION_DISCOVERY_FINISHED);
    context.registerReceiver(mReceiver, filter);
    if (adapter.isDiscovering()) {
        adapter.cancelDiscovery();
    }
    SetScanState(BlueToothService.STATE_SCANING);
    adapter.startDiscovery();
}

public void StopScan() {
    context.unregisterReceiver(mReceiver);
    adapter.cancelDiscovery();
    SetScanState(BlueToothService.STATE_SCAN_STOP);
}

public OnReceiveDataHandleEvent OnReceive = null;

public interface OnReceiveDataHandleEvent {
    public void OnReceive(BluetoothDevice device);
}

public void setOnReceive(OnReceiveDataHandleEvent onReceive) {
    OnReceive = onReceive;
}

private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
    public void onReceive(Context context, Intent intent) {
        String action = intent.getAction();
        if (BluetoothDevice.ACTION_FOUND.equals(action)) {
            BluetoothDevice device = intent
                    .getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
            if (device.getBondState() != BluetoothDevice.BOND_BONDED) {
                SetScanState(BlueToothService.STATE_SCANING);
                OnReceive.OnReceive(device);
            }
        } else if (BluetoothAdapter.ACTION_DISCOVERY_FINISHED
                .equals(action)) {
            SetScanState(BlueToothService.STATE_SCAN_STOP);
            OnReceive.OnReceive(null);
        }
    }
};

public void ConnectToDevice(String address) {
    if (BluetoothAdapter.checkBluetoothAddress(address)) {
        BluetoothDevice device = adapter.getRemoteDevice(address);
        PrinterType = 0;
        PrinterTypeNow = 0;
        connect(device);
    }
}

public void write(byte[] out) {
    ConnectedThread r;
    synchronized (this) {
        if (mState != STATE_CONNECTED)
            return;
        r = mConnectedThread;
    }
    if (r != null) {
        r.write(out);
    } else {
        DisConnected();
        Nopointstart();

    }
}

public synchronized void start() {
    if (D)
        Log.d(TAG, "start");

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

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

    if (mAcceptThread == null) {
        mAcceptThread = new AcceptThread();
        mAcceptThread.start();
    }
    setState(STATE_LISTEN);
}

private synchronized void setState(int state) {
    mState = state;
}

public synchronized int getState() {
    return mState;
}

private synchronized void SetScanState(int state) {
    scanState = state;
}

public synchronized int GetScanState() {
    return scanState;
}

public synchronized void connect(BluetoothDevice device) {

    if (mState == STATE_CONNECTING) {
        if (mConnectThread != null) {
            mConnectThread.cancel();
            mConnectThread = null;
        }
    }
    if (mConnectedThread != null) {
        mConnectedThread.cancel();
        mConnectedThread = null;
    }
    try {
        Thread.sleep(1000);
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
    mConnectThread = new ConnectThread(device);
    mConnectThread.start();
    setState(STATE_CONNECTING);
}

public synchronized void DisConnected() {

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

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

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

    setState(STATE_NONE);
}

public synchronized void connected(BluetoothSocket socket, BluetoothDevice device) {

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

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

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

    mConnectedThread = new ConnectedThread(socket);
    mConnectedThread.start();

    setState(STATE_CONNECTED);
}

private void connectionSuccess() {
    setState(STATE_CONNECTED);
    SetPrinterInf();
    mHandler.obtainMessage(MESSAGE_STATE_CHANGE, SUCCESS_CONNECT, -1)
            .sendToTarget();
}

private void SetPrinterInf() {
    new Thread() {
        public void run() {
            try {
                Thread.sleep(200);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            PrinterTypeNow = PrinterType;
        }
    }.start();
}

private void connectionFailed() {
    setState(STATE_LISTEN);
    mHandler.obtainMessage(MESSAGE_STATE_CHANGE, FAILED_CONNECT, -1)
            .sendToTarget();
}

private void connectionLost() {
    setState(STATE_LISTEN);
    mHandler.obtainMessage(MESSAGE_STATE_CHANGE, LOSE_CONNECT, -1)
            .sendToTarget();
}

private void Nopointstart() {
    setState(STATE_LISTEN);
    mHandler.obtainMessage(MESSAGE_STATE_CHANGE, LOSE_CONNECT, 0)
            .sendToTarget();
}

private class AcceptThread extends Thread {
    private final BluetoothServerSocket mmServerSocket;

    public AcceptThread() {
        BluetoothServerSocket tmp = null;
        try {
            tmp = adapter.listenUsingRfcommWithServiceRecord(NAME, MY_UUID);
        } catch (IOException e) {
            Log.e(TAG, "listen() failed", e);
        }
        mmServerSocket = tmp;
    }

    @Override
    public void run() {
        if (D)
            Log.d(TAG, "BEGIN mAcceptThread" + this);
        setName("AcceptThread");
        BluetoothSocket socket;
        while (mState != STATE_CONNECTED) {
            try {
                socket = mmServerSocket.accept();
            } catch (IOException e) {

                break;
            }
            if (socket != null) {
                synchronized (BlueToothService.this) {
                    switch (mState) {
                        case STATE_LISTEN:
                        case STATE_CONNECTING:
                            connected(socket, socket.getRemoteDevice());
                            break;
                        case STATE_NONE:
                        case STATE_CONNECTED:
                            try {
                                socket.close();
                            } catch (IOException e) {
                            }
                            break;
                    }
                }
            }
        }

    }

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

private class ConnectThread extends Thread {
    private final BluetoothSocket mmSocket;
    private final BluetoothDevice mmDevice;

    public ConnectThread(BluetoothDevice device) {
        mmDevice = device;
        BluetoothSocket tmp = null;
        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");

        adapter.cancelDiscovery();
        SetScanState(STATE_SCAN_STOP);
        try {
            mmSocket.connect();
            connectionSuccess();
        } catch (IOException e) {
            connectionFailed();
            try {
                mmSocket.close();
            } catch (IOException e2) {
                Log.e(TAG,
                        "unable to close() socket during connection failure",
                        e2);
            }
            BlueToothService.this.start();
            return;
        }

        synchronized (BlueToothService.this) {
            mConnectThread = null;
        }

        connected(mmSocket, mmDevice);
    }

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

public void SetPrinterType(int type) {
    PrinterType = type;
}

private class ConnectedThread extends Thread {
    private final BluetoothSocket mmSocket;
    private final InputStream mmInStream;
    private final OutputStream mmOutStream;
    private boolean isCancle = false;

    public ConnectedThread(BluetoothSocket socket) {
        Log.d(TAG, "create ConnectedThread");
        mmSocket = socket;
        InputStream tmpIn = null;
        OutputStream tmpOut = null;
        isCancle = false;
        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;

        while (!isCancle) {
            try {
                byte[] buffer = new byte[30];
                bytes = mmInStream.read(buffer);
                if (bytes > 0) {
                    SetPrinterType(2);
                    byte[] by = new byte[bytes];
                    System.arraycopy(buffer, 0, by, 0, bytes);
                    if (buffer[0] != 17) {
                        SetWriteState(WRITE_WAIT);
                    } else
                        SetWriteState(WRITE_READ);

                } else {
                    Log.e(TAG, "disconnected1");
                    connectionLost();
                    isCancle = true;
                    break;
                }
            } catch (IOException e) {
                Log.e(TAG, "disconnected2", e);
                connectionLost();
                isCancle = true;
                break;
            }
        }
    }

    public void write(byte[] buffer) {
        try {
            mmOutStream.write(buffer);
            Log.i("BTPWRITE", new String(buffer, "GBK"));
            mHandler.obtainMessage(MESSAGE_WRITE, -1, -1, buffer)
                    .sendToTarget();
        } catch (IOException e) {

        }
    }

    public void cancel() {
        try {
            isCancle = true;
            mmSocket.close();
            Log.d(TAG, "562cancel suc");
            setState(STATE_LISTEN);
        } catch (IOException e) {
            Log.d(TAG, "565cancel failed");
        }
    }
}

public void PrintCharacters(String str) {
    byte[] send;
    try {
        String ss = str;
        send = ss.getBytes("GBK");
    } catch (UnsupportedEncodingException e) {
        send = str.getBytes();
    }
    write(send);
}
}

选择MainActivity中的按钮将打开此活动,打开手机的蓝牙设备并扫描新的蓝牙设备。选择我的蓝牙打印机设备后,我将使用intent重定向回MainActivity。但连接将丢失。请帮助我如何保持连接。谢谢!

public class BTOptionsActivity extends AppCompatActivity {

private BlueToothService mBTService = null;
public static final int MESSAGE_STATE_CHANGE = 1;
public static final int MESSAGE_READ = 2;
public static final int MESSAGE_WRITE = 3;
private Button controlButton;
private ListView deviceList;
private ArrayAdapter<String> mPairedDevicesArrayAdapter = null;
private ArrayAdapter<String> mNewDevicesArrayAdapter = null;
private Set<BluetoothDevice> devices;
private Button bt_scan;
public Handler handler = null;
public Handler mhandler;
private LinearLayout layoutscan;
private TextView tv_status;
private Thread tv_update;
private boolean tvFlag = true;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_btoptions);

    deviceList = (ListView) findViewById(R.id.lv_device);

    layoutscan = (LinearLayout) findViewById(R.id.layoutscan);
    layoutscan.setVisibility(View.GONE);

    mhandler = new Handler() {
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            switch (msg.what) {
                case MESSAGE_STATE_CHANGE:
                    switch (msg.arg1) {
                        case BlueToothService.STATE_CONNECTED:
                            break;
                        case BlueToothService.STATE_CONNECTING:
                            break;
                        case BlueToothService.STATE_LISTEN:
                        case BlueToothService.STATE_NONE:
                            break;
                        case BlueToothService.SUCCESS_CONNECT:
                            Toast.makeText(BTOptionsActivity.this, "Success", Toast.LENGTH_LONG).show();
                            Intent intent = new Intent(BTOptionsActivity.this, MainActivity.class);
                            startActivity(intent);
                            finish();
                            break;
                        case BlueToothService.FAILED_CONNECT:
                            Toast.makeText(BTOptionsActivity.this, "Failed", Toast.LENGTH_LONG).show();
                            break;
                        case BlueToothService.LOSE_CONNECT:
                            switch(msg.arg2){
                                case -1:
                                    Toast.makeText(BTOptionsActivity.this, "Lost Connection", Toast.LENGTH_LONG).show();
                                    break;
                                case 0:
                                    break;
                            }
                    }
                    break;
                case MESSAGE_READ:
                    break;
                case MESSAGE_WRITE:
                    break;
            }
        }
    };

    mBTService = new BlueToothService(this, mhandler);

    controlButton = (Button) findViewById(R.id.bt_openclose);
    if (mBTService.IsOpen()) {
        controlButton.setText("Disconnect");
    }
    controlButton.setOnClickListener(new View.OnClickListener() {
        public void onClick(View v) {
            if (mBTService.IsOpen()) {
                if (mBTService.getState() == mBTService.STATE_CONNECTED) {
                    mBTService.DisConnected();
                }
                try {
                    Thread.sleep(200);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                mBTService.CloseDevice();
            } else {
                mBTService.OpenDevice();
                controlButton.setText("Connect");
            }
        }
    });

    mPairedDevicesArrayAdapter = new ArrayAdapter<String>(this, R.layout.device_name);

    mNewDevicesArrayAdapter = new ArrayAdapter<String>(this, R.layout.device_name);

    bt_scan = (Button) findViewById(R.id.bt_scan);
    bt_scan.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            if (!mBTService.IsOpen()) {
                mBTService.OpenDevice();
                return;
            }
            if (mBTService.GetScanState() == mBTService.STATE_SCANING)
                return;
            layoutscan.setVisibility(View.VISIBLE);
            mNewDevicesArrayAdapter.clear();
            devices = mBTService.GetBondedDevice();
            if (devices.size() > 0) {
                for (BluetoothDevice device : devices) {
                    mNewDevicesArrayAdapter.add(device.getName() + "\n"
                            + device.getAddress());
                }
            }
            deviceList.setAdapter(mNewDevicesArrayAdapter);
            new Thread() {
                public void run() {
                    mBTService.ScanDevice();
                }
            }.start();
        }
    });

    mBTService.setOnReceive(new BlueToothService.OnReceiveDataHandleEvent() {
        @Override
        public void OnReceive(BluetoothDevice device) {
            if (device != null) {
                mNewDevicesArrayAdapter.add(device.getName() + "\n"
                        + device.getAddress());
            } else {
                Message msg = new Message();
                msg.what = 1;
                handler.sendMessage(msg);
            }
        }
    });

    deviceList.setOnItemClickListener(new AdapterView.OnItemClickListener() {
        @Override
        public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
            if (!mBTService.IsOpen()) {
                mBTService.OpenDevice();
                return;
            }
            if (mBTService.GetScanState() == mBTService.STATE_SCANING) {
                Message msg = new Message();
                msg.what = 2;
                handler.sendMessage(msg);
            }
            if (mBTService.getState() == mBTService.STATE_CONNECTING) {
                return;
            }
            String info = ((TextView) view).getText().toString();
            String address = info.substring(info.length() - 17);
            mBTService.DisConnected();
            mBTService.ConnectToDevice(address);
        }
    });

    handler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            switch (msg.what) {
                case 0:
                    break;
                case 1:
                    mBTService.StopScan();
                    layoutscan.setVisibility(View.GONE);
                    Toast.makeText(BTOptionsActivity.this, "scan over", Toast.LENGTH_LONG).show();
                    break;
                case 2:
                    layoutscan.setVisibility(View.GONE);
                    break;
            }
        }
    };

    tv_status = (TextView) findViewById(R.id.tv_status);

    tv_update = new Thread() {
        public void run() {
            while (tvFlag) {
                try {
                    Thread.sleep(200);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                tv_status.post(new Runnable() {
                    @Override
                    public void run() {
                        if (mBTService != null) {
                            if (mBTService.getState() == mBTService.STATE_CONNECTED) {
                                tv_status.setText("Connected!");
                            } else if (mBTService.getState() == mBTService.STATE_CONNECTING) {
                                tv_status.setText("Connecting!");
                            } else {
                                tv_status.setText("Disconnected!");
                            }
                        }
                    }
                });
            }
        }
    };
    tv_update.start();
}

@Override
protected void onDestroy() {
    super.onDestroy();
}

@Override
protected void onPause() {
    super.onPause();
}

public void onBackPressed() {
    if (tv_update != null) {
        tvFlag = false;
        tv_update = null;
    }
    try {
        Thread.sleep(200);
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
    if (mBTService != null) {
        mBTService.DisConnected();
        mBTService = null;
    }
    try {
        Thread.sleep(1000);
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
    System.exit(0);
}
}

这是我的MainActivity

public class MainActivity extends AppCompatActivity {

private TextView tvStatus;
private Button btnBTOptions;
private Thread tv_update;
private boolean tvFlag = true;
private BlueToothService mBTService = null;
public Handler mhandler;
public static final int MESSAGE_STATE_CHANGE = 1;
public static final int MESSAGE_READ = 2;
public static final int MESSAGE_WRITE = 3;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    tvStatus = (TextView) findViewById(R.id.tvStatus);
    btnBTOptions = (Button) findViewById(R.id.btnBTOptions);

    mhandler = new Handler() {
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            switch (msg.what) {
                case MESSAGE_STATE_CHANGE:
                    switch (msg.arg1) {
                        case BlueToothService.STATE_CONNECTED:
                            break;
                        case BlueToothService.STATE_CONNECTING:
                            break;
                        case BlueToothService.STATE_LISTEN:
                            break;
                        case BlueToothService.STATE_NONE:
                            break;
                        case BlueToothService.SUCCESS_CONNECT:
                            Toast.makeText(MainActivity.this, "Success", Toast.LENGTH_LONG).show();
                            break;
                        case BlueToothService.FAILED_CONNECT:
                            Toast.makeText(MainActivity.this, "Failed", Toast.LENGTH_LONG).show();
                            break;
                        case BlueToothService.LOSE_CONNECT:
                            switch(msg.arg2){
                                case -1:
                                    Toast.makeText(MainActivity.this, "Lost Connection", Toast.LENGTH_LONG).show();
                                    break;
                                case 0:
                                    break;
                            }
                    }
                    break;
                case MESSAGE_READ:
                    break;
                case MESSAGE_WRITE:
                    break;
            }
        }
    };

    mBTService = new BlueToothService(this, mhandler);

    tv_update = new Thread() {
        public void run() {
            while (tvFlag) {
                try {
                    Thread.sleep(200);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                tvStatus.post(new Runnable() {
                    @Override
                    public void run() {
                        if (mBTService != null) {
                            if (mBTService.getState() == mBTService.STATE_CONNECTED) {
                                tvStatus.setText("BlueTooth is Connected!");
                            } else if (mBTService.getState() == mBTService.STATE_CONNECTING) {
                                tvStatus.setText("BlueTooth is Connecting!");
                            } else {
                                tvStatus.setText("BlueTooth is Disconnected!");
                            }
                        }
                    }
                });
            }
        }
    };
    tv_update.start();

    btnBTOptions.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            Intent intent = new Intent(MainActivity.this, BTOptionsActivity.class);
            startActivity(intent);
        }
    });

0 个答案:

没有答案