Android 如何在后台保持蓝牙连接?

Android 如何在后台保持蓝牙连接?,android,service,bluetooth,android-bluetooth,background-service,Android,Service,Bluetooth,Android Bluetooth,Background Service,我在android应用程序中创建了一个蓝牙活动类,它可以很好地用于所有蓝牙功能,如:扫描、配对、连接、发送和接收数据 真正的问题是活动何时被破坏。蓝牙正在断开连接 如何在整个应用程序中建立蓝牙连接。我想从其他活动向蓝牙发送数据 帮助我以一种简单的方式实现这一点 public class BTActivity extends AppCompatActivity { ArrayList<BluetoothDevice> devices = new ArrayList<>()

我在android应用程序中创建了一个蓝牙活动类,它可以很好地用于所有蓝牙功能,如:扫描、配对、连接、发送和接收数据

真正的问题是活动何时被破坏。蓝牙正在断开连接

如何在整个应用程序中建立蓝牙连接。我想从其他活动向蓝牙发送数据

帮助我以一种简单的方式实现这一点

public class BTActivity extends AppCompatActivity {

ArrayList<BluetoothDevice> devices = new ArrayList<>();
BluetoothAdapter mBluetoothAdapter;
BluetoothDevice mBluetoothDevice;
ArrayAdapter<BluetoothDevice> arrayAdapter;

ConnectThread c;

private static final String TAG = "MY_BT";

ListView lvPaired;
Button BluetoothOnOff, ScanBt, pairedlist, sendButton, btDisconnect, incrementBtn, decrementBtn;
EditText input_text;
TextView ConnectedTo;

FragmentManager fm = getSupportFragmentManager();

UUID BHANU_UUID = UUID.fromString("00001101-0000-1000-8000-00805f9b34fb");

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

    mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
    lvPaired = findViewById(R.id.btPairedLV);
    pairedlist = findViewById(R.id.btPaired);
    input_text = findViewById(R.id.user_input);
    sendButton = findViewById(R.id.btnSend);
    BluetoothOnOff = findViewById(R.id.offOn_bt);
    ScanBt = findViewById(R.id.scan_bt);
    ConnectedTo = findViewById(R.id.current_connected_bluetooth);
    btDisconnect = findViewById(R.id.bt_disconnect);
    incrementBtn = findViewById(R.id.incrementBtn);
    decrementBtn = findViewById(R.id.decrementBtn);

    onClickListener();
    pairedList();

    IntentFilter filter = new IntentFilter();
    filter.addAction(BluetoothDevice.ACTION_ACL_CONNECTED);
    filter.addAction(BluetoothDevice.ACTION_ACL_DISCONNECTED);
    registerReceiver(mReceiver, filter);

}
public void onClickListener(){

    pairedlist.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            if (arrayAdapter != null){
                arrayAdapter.clear();
            }
            pairedList();
        }
    });

    lvPaired.setOnItemClickListener(new AdapterView.OnItemClickListener() {
        @Override
        public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
            BluetoothDevice device = (BluetoothDevice) parent.getItemAtPosition(position);
            c = new ConnectThread(device, true);
            c.start();
        }
    });
    sendButton.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            String text = input_text.getText().toString();
            c.sendData(text);
            input_text.setText("");

        }
    });
    BluetoothOnOff.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            if (!mBluetoothAdapter.isEnabled()){
                mBluetoothAdapter.enable();
                BluetoothOnOff.setText("ON");
            }else {
                mBluetoothAdapter.disable();
                BluetoothOnOff.setText("OFF");
            }
        }
    });
    ScanBt.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            ScanFragment scanFragment = new ScanFragment();
            scanFragment.show(fm,"ScanBT");
            //ScanFragment scanFragment = new ScanFragment();
            //scanFragment.show(fm,"Scan Fragment");
        }
    });
    btDisconnect.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            c.cancel();
        }
    });

    incrementBtn.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            c.sendData("a");
        }
    });
    decrementBtn.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            c.sendData("b");
        }
    });

}


public void toast(String message) {
    Toast.makeText(this, message, Toast.LENGTH_SHORT).show();
}

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

public void pairedList() {
    //arrayAdapter.clear();
    devices.addAll(mBluetoothAdapter.getBondedDevices());
    arrayAdapter = new ArrayAdapter<BluetoothDevice>(this, android.R.layout.simple_list_item_1,android.R.id.text1, devices);
    lvPaired.setAdapter(arrayAdapter);
    arrayAdapter.notifyDataSetChanged();

}

BroadcastReceiver mReceiver = new BroadcastReceiver() {
    @Override
    public void onReceive(Context context, Intent intent) {
        String action = intent.getAction();
        if (BluetoothDevice.ACTION_ACL_CONNECTED.equals(action)) {
            toast("connected");
            BluetoothDevice device = intent
                    .getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
            ConnectedTo.setText(device.getName());
            btDisconnect.setVisibility(View.VISIBLE);
            //getActionBar().setSubtitle(device.getName());
            Log.d("BT", "connected to");
        } else if (BluetoothDevice.ACTION_ACL_DISCONNECTED.equals(action)) {
            toast("disconnected");
            ConnectedTo.setText("None");
            btDisconnect.setVisibility(View.INVISIBLE);
           // getActionBar().setSubtitle("");
            Log.d("BT", "disconnected");
        }

    }
};


public class ConnectThread extends Thread {
    BluetoothDevice cDevice;
    BluetoothSocket socket;
    ConnectedThread ct;

    ConnectThread(BluetoothDevice device, boolean insecureConnection) {
        cDevice = device;
        try {
            if (insecureConnection) {
                socket = device.createInsecureRfcommSocketToServiceRecord(BHANU_UUID);
            } else {
                socket = device.createRfcommSocketToServiceRecord(BHANU_UUID);
            }
        } catch (IOException e) {
            e.getMessage();
        }
    }

    public void run() {
        mBluetoothAdapter.cancelDiscovery();

        try {
            Log.d("BT", "Socket ready to connect");
            socket.connect();
            Log.d("BT", "Socket connected");
            // out = socket.getOutputStream();
            // input = new BufferedReader(new InputStreamReader(socket.getInputStream()));


        } catch (final IOException e) {
            e.getMessage();
        }

        ct = new ConnectedThread(socket);

        //ct.write("Q-smart".getBytes());
            /*try {
                socket.close();
            } catch (final IOException closeException) {
                closeException.getMessage();
            }*/
    }
    private void sendData(String message){
        Log.d(TAG,message);
        if (socket != null){
            ct.write(message.getBytes());
        }else {
            toast("Please connect to bluetooth first");
        }
    }

    public void cancel() {
        try {
            socket.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

private class ConnectedThread extends Thread {
    private final BluetoothSocket mmSocket;
    private final InputStream mmInStream;
    private final OutputStream mmOutStream;
    private byte[] mmBuffer; // mmBuffer store for the stream

    public ConnectedThread(BluetoothSocket socket) {
        mmSocket = socket;
        InputStream tmpIn = null;
        OutputStream tmpOut = null;

        // Get the input and output streams; using temp objects because
        // member streams are final.
        try {
            tmpIn = socket.getInputStream();
        } catch (IOException e) {
            Log.e(TAG, "Error occurred when creating input stream", e);
        }
        try {
            tmpOut = socket.getOutputStream();
        } catch (IOException e) {
            Log.e(TAG, "Error occurred when creating output stream", e);
        }

        mmInStream = tmpIn;
        mmOutStream = tmpOut;
    }

    public void run() {
        mmBuffer = new byte[1024];
        int numBytes; // bytes returned from read()

        // Keep listening to the InputStream until an exception occurs.
        while (true) {
            try {
                // Read from the InputStream.
                numBytes = mmInStream.read(mmBuffer);
                // Send the obtained bytes to the UI activity.
               /* Message readMsg = mHandler.obtainMessage(
                        MessageConstants.MESSAGE_READ, numBytes, -1,
                        mmBuffer);
                readMsg.sendToTarget();*/
            } catch (IOException e) {
                Log.d(TAG, "Input stream was disconnected", e);
                break;
            }
        }
    }

    // Call this from the main activity to send data to the remote device.
    public void write(byte[] bytes) {
        try {
            mmOutStream.write(bytes);

            // Share the sent message with the UI activity.
           /* Message writtenMsg = mHandler.obtainMessage(
                    MessageConstants.MESSAGE_WRITE, -1, -1, mmBuffer);
            writtenMsg.sendToTarget();*/
        } catch (IOException e) {
            Log.e(TAG, "Error occurred when sending data", e);

            // Send a failure message back to the activity.
           /* Message writeErrorMsg =
                    mHandler.obtainMessage(MessageConstants.MESSAGE_TOAST);
            Bundle bundle = new Bundle();
            bundle.putString("toast",
                    "Couldn't send data to the other device");
            writeErrorMsg.setData(bundle);
            mHandler.sendMessage(writeErrorMsg);*/
        }
    }


}
}
公共类BTActivity扩展了AppCompatActivity{
ArrayList设备=新的ArrayList();
蓝牙适配器mBluetoothAdapter;
蓝牙设备;
ArrayAdapter ArrayAdapter;
连接螺纹c;
私有静态最终字符串TAG=“MY_BT”;
列表视图;
按钮蓝牙关闭、扫描、配对列表、发送按钮、断开连接、递增BTN、递减TBTN;
编辑文本输入\文本;
连接到的文本视图;
FragmentManager fm=getSupportFragmentManager();
UUID BHANU_UUID=UUID.fromString(“00001101-0000-1000-8000-00805f9b34fb”);
@凌驾
创建时受保护的void(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_bt);
mBluetoothAdapter=BluetoothAdapter.getDefaultAdapter();
lvPaired=findviewbyd(R.id.btPairedLV);
pairedlist=findViewById(R.id.btPaired);
input_text=findViewById(R.id.user_输入);
sendButton=findviewbyd(R.id.btnSend);
BluetoothOnOff=findViewById(R.id.offOn_bt);
ScanBt=findviewbyd(R.id.scan_bt);
ConnectedTo=findViewById(R.id.当前\u已连接\u蓝牙);
btDisconnect=findViewById(R.id.bt\u disconnect);
incrementBtn=findViewById(R.id.incrementBtn);
DecrementTBTN=findViewById(R.id.DecrementTBTN);
onClickListener();
pairedList();
IntentFilter=newintentfilter();
filter.addAction(BluetoothDevice.ACTION\u ACL\u已连接);
filter.addAction(BluetoothDevice.ACTION\u ACL\u已断开连接);
registerReceiver(mrReceiver,过滤器);
}
公共void onClickListener(){
pairedlist.setOnClickListener(新视图.OnClickListener(){
@凌驾
公共void onClick(视图v){
if(arrayAdapter!=null){
arrayAdapter.clear();
}
pairedList();
}
});
lvPaired.setOnItemClickListener(新的AdapterView.OnItemClickListener(){
@凌驾
public void onItemClick(AdapterView父对象、视图、整型位置、长id){
BluetoothDevice=(BluetoothDevice)父级.getItemAtPosition(位置);
c=新连接线程(设备,正确);
c、 start();
}
});
sendButton.setOnClickListener(新视图.OnClickListener(){
@凌驾
公共void onClick(视图v){
String text=input_text.getText().toString();
c、 发送数据(文本);
输入_text.setText(“”);
}
});
BluetoothOnOff.setOnClickListener(新视图.OnClickListener(){
@凌驾
公共void onClick(视图v){
如果(!mBluetoothAdapter.isEnabled()){
mBluetoothAdapter.enable();
BluetoothOnOff.setText(“ON”);
}否则{
mBluetoothAdapter.disable();
BluetoothOnOff.setText(“关闭”);
}
}
});
ScanBt.setOnClickListener(新视图.OnClickListener(){
@凌驾
公共void onClick(视图v){
ScanFragment ScanFragment=新的ScanFragment();
scanFragment.show(fm,“ScanBT”);
//ScanFragment ScanFragment=新的ScanFragment();
//show(fm,“扫描片段”);
}
});
btDisconnect.setOnClickListener(新视图.OnClickListener(){
@凌驾
公共void onClick(视图v){
c、 取消();
}
});
incrementBtn.setOnClickListener(新视图.OnClickListener(){
@凌驾
公共void onClick(视图v){
c、 sendData(“a”);
}
});
decrementBtn.setOnClickListener(新视图.OnClickListener(){
@凌驾
公共void onClick(视图v){
c、 sendData(“b”);
}
});
}
公共无效toast(字符串消息){
Toast.makeText(this,message,Toast.LENGTH_SHORT).show();
}
@凌驾
受保护的空onDestroy(){
未注册接收人(mReceiver);
super.ondestory();
}
公共无效pairedList(){
//arrayAdapter.clear();
addAll(mBluetoothAdapter.getBondedDevices());
arrayAdapter=新的arrayAdapter(这个,android.R.layout.simple_list_item_1,android.R.id.text1,设备);
lvPaired.setAdapter(arrayAdapter);
arrayAdapter.notifyDataSetChanged();
}
BroadcastReceiver mReceiver=新的BroadcastReceiver(){
@凌驾
公共void onReceive(上下文、意图){
String action=intent.getAction();
if(BluetoothDevice.ACTION\u ACL\u CONNECTED.equals(ACTION)){
吐司(“相关”);
蓝牙设备=意图
.getParcelableExtra(蓝牙设备.EXTRA_设备);
ConnectedTo.setText(device.getName());
btDisconnect.setVisibility(View.VISIBLE);
//getActionBar().setSubtitle(device.getName());
日志d(“BT”,“连接到”);
}else if(BluetoothDevice.ACTION\u ACL\u DISCONNECTED.equals(ACTION)){
吐司(“断开”);
连接到.setText(“无”);
btDisconnect.setVisibility(视图不可见);
//getActionBar().setSubtitle(“”);
日志d(“BT”、“断开”);
}
}
};
公共类ConnectThread扩展线程{
蓝牙设备;
蓝牙插座;
连接螺纹ct;
ConnectThread(蓝牙设备,布尔不安全连接){
cDevice=设备;
试一试{
if(不安全连接){
socket=device.createInsurerCommsocketToServiceRecord(BHANU_UUID);
}否则{
socket=device.createRfcommS
public class BluetoothServices extends Service {

private BluetoothAdapter mBluetoothAdapter;
public static final String B_DEVICE = "MY DEVICE";
public static final String B_UUID = "00001101-0000-1000-8000-00805f9b34fb";
// 00000000-0000-1000-8000-00805f9b34fb

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;

private ConnectBtThread mConnectThread;
private static ConnectedBtThread mConnectedThread;

private static Handler mHandler = null;
public static int mState = STATE_NONE;
public static String deviceName;
public static BluetoothDevice sDevice = null;
public Vector<Byte> packData = new Vector<>(2048);

//IBinder mIBinder = new LocalBinder();


@Nullable
@Override
public IBinder onBind(Intent intent) {
    //mHandler = getApplication().getHandler();
    return mBinder;
}
public void toast(String mess){
    Toast.makeText(this,mess,Toast.LENGTH_SHORT).show();
}
private final IBinder mBinder = new LocalBinder();

public class LocalBinder extends Binder {
    BluetoothServices getService() {
        // Return this instance of LocalService so clients can call public methods
        return BluetoothServices.this;
    }
}

@Override
public int onStartCommand(Intent intent, int flags, int startId) {

    String deviceg = intent.getStringExtra("bluetooth_device");


    mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();

            connectToDevice(deviceg);

    return START_STICKY;
}
private synchronized void connectToDevice(String macAddress){
    BluetoothDevice device = mBluetoothAdapter.getRemoteDevice(macAddress);
    if (mState == STATE_CONNECTING){
        if (mConnectThread != null){
            mConnectThread.cancel();
            mConnectThread = null;
        }
    }
    if (mConnectedThread != null){
        mConnectedThread.cancel();
        mConnectedThread = null;
    }
    mConnectThread = new ConnectBtThread(device);
    toast("connecting");
    mConnectThread.start();
    setState(STATE_CONNECTING);
}
private void setState(int state){
    mState = state;
    if (mHandler != null){
       // mHandler.obtainMessage();
    }
}
public synchronized void stop(){
    setState(STATE_NONE);
    if (mConnectThread != null){
        mConnectThread.cancel();
        mConnectThread = null;
    }
    if (mConnectedThread != null){
        mConnectedThread.cancel();
        mConnectedThread = null;
    }
    if (mBluetoothAdapter != null){
        mBluetoothAdapter.cancelDiscovery();
    }

    stopSelf();
}

public void sendData(String message){
    if (mConnectedThread!= null){
        mConnectedThread.write(message.getBytes());
        toast("sent data");
    }else {
        Toast.makeText(BluetoothServices.this,"Failed to send data",Toast.LENGTH_SHORT).show();
    }
}

@Override
public boolean stopService(Intent name) {
    setState(STATE_NONE);

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

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

    mBluetoothAdapter.cancelDiscovery();
    return super.stopService(name);
}

/*private synchronized void connected(BluetoothSocket mmSocket){

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

    mConnectedThread = new ConnectedBtThread(mmSocket);
    mConnectedThread.start();


    setState(STATE_CONNECTED);
}*/

private class ConnectBtThread extends Thread{
    private final BluetoothSocket mSocket;
    private final BluetoothDevice mDevice;

    public ConnectBtThread(BluetoothDevice device){
        mDevice = device;
        BluetoothSocket socket = null;
        try {
            socket = device.createInsecureRfcommSocketToServiceRecord(UUID.fromString(B_UUID));
        } catch (IOException e) {
            e.printStackTrace();
        }
        mSocket = socket;

    }

    @Override
    public void run() {
        mBluetoothAdapter.cancelDiscovery();

        try {
            mSocket.connect();
            Log.d("service","connect thread run method (connected)");
            SharedPreferences pre = getSharedPreferences("BT_NAME",0);
            pre.edit().putString("bluetooth_connected",mDevice.getName()).apply();

        } catch (IOException e) {

            try {
                mSocket.close();
                Log.d("service","connect thread run method ( close function)");
            } catch (IOException e1) {
                e1.printStackTrace();
            }
            e.printStackTrace();
        }
        //connected(mSocket);
        mConnectedThread = new ConnectedBtThread(mSocket);
        mConnectedThread.start();
    }

    public void cancel(){

        try {
            mSocket.close();
            Log.d("service","connect thread cancel method");
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

private class ConnectedBtThread extends Thread{
    private final BluetoothSocket cSocket;
    private final InputStream inS;
    private final OutputStream outS;

    private byte[] buffer;

    public ConnectedBtThread(BluetoothSocket socket){
        cSocket = socket;
        InputStream tmpIn = null;
        OutputStream tmpOut = null;

        try {
            tmpIn = socket.getInputStream();

        } catch (IOException e) {
            e.printStackTrace();
        }

        try {
            tmpOut = socket.getOutputStream();
        } catch (IOException e) {
            e.printStackTrace();
        }

        inS = tmpIn;
        outS = tmpOut;
    }

    @Override
    public void run() {
        buffer = new byte[1024];
        int mByte;
        try {
            mByte= inS.read(buffer);
        } catch (IOException e) {
            e.printStackTrace();
        }
        Log.d("service","connected thread run method");

    }


    public void write(byte[] buff){
        try {
            outS.write(buff);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    private void cancel(){
        try {
            cSocket.close();
            Log.d("service","connected thread cancel method");
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

@Override
public void onDestroy() {
    this.stop();
    super.onDestroy();
}