微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

应用程序关闭时蓝牙设备断开连接

如何解决应用程序关闭时蓝牙设备断开连接

我不熟悉应用中的 BLE 实现,但我能够连接到应用中的 BLE 设备。

当应用程序关闭时,连接断开,但即使应用程序关闭,我也需要能够连接,因为我将从微控制器接收数据。

谁能给我建议或帮助我解决问题?

是否只是因为正在等待数据发送而被连接,而当应用程序关闭时我遇到了问题?

package com.example.Pillwoah;

import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;

import android.app.Activity;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothGatt;
import android.bluetooth.BluetoothGattCallback;
import android.bluetooth.BluetoothGattCharacteristic;
import android.bluetooth.BluetoothGattService;
import android.bluetooth.BluetoothManager;
import android.bluetooth.BluetoothProfile;
import android.bluetooth.BluetoothSocket;
import android.bluetooth.le.BluetoothLeScanner;
import android.bluetooth.le.ScanCallback;
import android.bluetooth.le.ScanResult;
import android.bluetooth.le.ScanSettings;
import android.content.broadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.pm.PackageManager;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.util.Log;
import android.view.View;
import android.widget.ArrayAdapter;
import android.widget.AdapterView;
import android.widget.Button;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;

import java.io.IOException;
import java.lang.reflect.Method;
import java.util.List;
import java.util.Set;
import java.util.UUID;

import static android.bluetooth.BluetoothDevice.ACTION_BOND_STATE_CHANGED;
import static android.bluetooth.BluetoothDevice.BOND_BONDED;
import static android.bluetooth.BluetoothDevice.BOND_BONDING;
import static android.bluetooth.BluetoothDevice.BOND_NONE;
import static android.bluetooth.BluetoothDevice.EXTRA_BOND_STATE;

public class MainActivity4 extends AppCompatActivity {

    protected static final String TAG = "TAG";

    TextView phoneName,deviceList;

    private Handler mHandler;
    private BluetoothAdapter bluetoothAdapter;
    private Set<BluetoothDevice> pairedDevices;
    private ArrayAdapter<String> BAarray,BANewArray;
    private ListView DeviceList,NewDevice;
    private boolean mScanning;
    private BluetoothGatt mGatt;
    private BluetoothLeScanner bluetoothLeScanner = BluetoothAdapter.getDefaultAdapter().getBluetoothLeScanner();

    private BluetoothSocket BTSocket = null;
    private BluetoothDevice device = null;

    private final static UUID BTMODULEUUID = UUID.fromString("00001101-0000-1000-8000-00805F9B34FB");
    private final static int REQUEST_ENABLE_BT = 1;
    private final static int REQUEST_CONNECT_DEVICE = 2;
    private final static int REQUEST_COARSE_LOCATION = 1;
    private static final long SCAN_PERIOD = 10000;

    @Override
    protected void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main4);

        Button mEnable = (Button) findViewById(R.id.enable);
        Button mOff = (Button) findViewById(R.id.off);
        Button mPaired = (Button) findViewById(R.id.paired);
        Button mdiscover = (Button) findViewById(R.id.discover);

        deviceList = findViewById(R.id.deviceTitle);
        deviceList.setText(null);
        phoneName = findViewById(R.id.name);
        phoneName.setText(getLocalBtName());

        mHandler = new Handler();

        //BA = BluetoothAdapter.getDefaultAdapter();
        // Initializes Bluetooth adapter.
        final BluetoothManager bluetoothManager = (BluetoothManager) getSystemService(Context.BLUetoOTH_SERVICE);
        bluetoothAdapter = bluetoothManager.getAdapter();

        // Ensures Bluetooth is available on the device and it is enabled. If not,// displays a dialog requesting user permission to enable Bluetooth.
        if (bluetoothAdapter == null || !bluetoothAdapter.isEnabled()) {
            Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
            startActivityForResult(enableBtIntent,REQUEST_ENABLE_BT);
        }

        // Build ScanSetting
        ScanSettings.Builder scanSetting = new ScanSettings.Builder()
                .setScanMode(ScanSettings.SCAN_MODE_LOW_POWER)
                .setReportDelay(5000);

        scanSetting.build();

        BAarray = new ArrayAdapter<String>(this,android.R.layout.simple_list_item_1);
        BANewArray = new ArrayAdapter<String>(this,android.R.layout.simple_list_item_1);

        DeviceList = (ListView)findViewById(R.id.deviceListView);
        DeviceList.setAdapter(BAarray);
        DeviceList.setonItemClickListener(DeviceClickListener);

        NewDevice = (ListView)findViewById(R.id.newDeviceView);
        NewDevice.setAdapter(BANewArray);
        NewDevice.setonItemClickListener(DeviceClickListener);

        if (bluetoothAdapter == null) {
            Toast.makeText(this,"Bluetooth not supported",Toast.LENGTH_SHORT).show();
            finish();
        } else {
            mEnable.setonClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    checkLocationPermission();
                    bluetoothOn(v);
                }

            });

            mOff.setonClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    bluetoothOff(v);
                }
            });

            mPaired.setonClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    checkLocationPermission();
                    listPairedDevices(v);
                }
            });

            mdiscover.setonClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    checkLocationPermission();
                    discover(v);
                }
            });
        }
    };

    protected void checkLocationPermission() {
        if (ContextCompat.checkSelfPermission(this,android.Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) {

            ActivityCompat.requestPermissions(this,new String[]{android.Manifest.permission.ACCESS_FINE_LOCATION},REQUEST_COARSE_LOCATION);
        }
    }

    @Override
    public void onRequestPermissionsResult(int requestCode,String permissions[],int[] grantResults) {
        switch (requestCode) {
            case REQUEST_COARSE_LOCATION: {
                if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                    Toast.makeText(getApplicationContext(),"Permission on",Toast.LENGTH_SHORT).show();
                } else {
                    Toast.makeText(getApplicationContext(),"Permission off",Toast.LENGTH_SHORT).show();
                }
                break;
            }
        }
    }

    public String getLocalBtName(){
        if(bluetoothAdapter == null){
            bluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
        }
        String name = bluetoothAdapter.getName();
        if(name == null){
            name = bluetoothAdapter.getAddress();
        }

        return name;
    }

    @Override
    protected void onResume() {
        super.onResume();
        // Ensures Bluetooth is enabled on the device.  If Bluetooth is not currently enabled,// fire an intent to display a dialog asking the user to grant permission to enable it.
        if (!bluetoothAdapter.isEnabled()) {
            if (!bluetoothAdapter.isEnabled()) {
                Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
                startActivityForResult(enableBtIntent,REQUEST_ENABLE_BT);
            }
        }else {
            if (Build.VERSION.SDK_INT >= 21) {
                bluetoothLeScanner = bluetoothAdapter.getBluetoothLeScanner();
                ScanSettings scanSetting = new ScanSettings.Builder()
                        .setScanMode(ScanSettings.SCAN_MODE_LOW_POWER)
                        .build();

            }
            //scanLeDevice(true);
        }
    }

    @Override
    protected void onActivityResult(int requestCode,int resultCode,Intent data) {
        // User chose not to enable Bluetooth.
        if (requestCode == REQUEST_ENABLE_BT && resultCode == Activity.RESULT_CANCELED) {
            finish();
            return;
        }
        super.onActivityResult(requestCode,resultCode,data);
    }
    @Override
    protected void onPause() {
        super.onPause();
        scanLeDevice(false);
        BANewArray.clear();
        BAarray.clear();
    }

    @Override
    public void onDestroy() {
        if (mGatt == null) {
            return;
        }
        Log.i("destroy ","ble destroy");
        BANewArray.clear();
        BAarray.clear();
        mGatt.close();
        mGatt = null;
        super.onDestroy();
        System.out.println("BLE// destroy");
    }

    private void scanLeDevice(final boolean enable) {
        if (enable) {
            // Stops scanning after a pre-defined scan period.
            mHandler.postDelayed(new Runnable() {
                @Override
                public void run() {
                    mScanning = false;
                    bluetoothLeScanner.stopScan(leScanCallback);
                    System.out.println("BLE// bluetoothLeScanner.stopScan(leScanCallback)");
                }
            },SCAN_PERIOD);

            mScanning = true;
            bluetoothLeScanner.startScan(leScanCallback);
            System.out.println("BLE// bluetoothLeScanner.startScan(leScanCallback)");
        } else {
            mScanning = false;
            bluetoothLeScanner.stopScan(leScanCallback);
            System.out.println("BLE// bluetoothLeScanner.stopScan(leScanCallback)");
        }
    }

    // Device scan callback.
    private ScanCallback leScanCallback = new ScanCallback() {
        @Override
        public void onScanResult(int callbackType,ScanResult result) {
            super.onScanResult(callbackType,result);

            Log.i("callbackType",String.valueOf(callbackType));
            Log.i("result",result.toString());
            //Log.i("Device Name: ",result.getDevice().getName());
            System.out.println("Signal: " + result.getRSSi());

            BluetoothDevice btDevice = result.getDevice();
            System.out.println("name: " + btDevice);
            BANewArray.add(btDevice.getName() + "\n" + btDevice.getAddress());
        }

        @Override
        public void onBatchScanResults(List<ScanResult> results) {
            System.out.println("BLE// onBatchScanResults");
            for (ScanResult sr : results) {
                Log.i("ScanResult - Results",sr.toString());
            }
        }

        @Override
        public void onScanFailed(int errorCode) {
            System.out.println("BLE// onScanFailed");
            Log.e("Scan Failed","Error Code: " + errorCode);
        }
    };

    private void bluetoothOn(View view){
        if(!bluetoothAdapter.isEnabled()){
            Intent enableIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
            startActivityForResult(enableIntent,REQUEST_ENABLE_BT);
            Toast.makeText(getApplicationContext(),"Bluetooth turned on",Toast.LENGTH_SHORT).show();
        }
        else{
            Toast.makeText(getApplicationContext(),"Bluetooth is already on",Toast.LENGTH_SHORT).show();
        }
    }

    private void bluetoothOff(View view){
        bluetoothAdapter.disable();
        BAarray.clear();
        BANewArray.clear();
        Toast.makeText(getApplicationContext(),"Bluetooth turned off",Toast.LENGTH_SHORT).show();
    }

    public void connectToDevice(BluetoothDevice device) {
        Toast.makeText(getApplicationContext(),"BLE// connectToDevice()",Toast.LENGTH_SHORT).show();
        //System.out.println("BLE// connectToDevice()");
        bluetoothAdapter.canceldiscovery();
        if (mGatt == null) {
            mGatt = device.connectGatt(this,true,gattCallback); //Connect to a GATT Server
            scanLeDevice(false);// will stop after first device detection
        }
        else{
            //mGatt.discoverServices();
            Toast.makeText(getApplicationContext(),"Error",Toast.LENGTH_SHORT).show();
        }
    }

    private final BluetoothGattCallback gattCallback = new BluetoothGattCallback() {
        @Override
        public void onConnectionStateChange(BluetoothGatt gatt,int status,int newState) {
            System.out.println("BLE// BluetoothGattCallback");
            Log.i("onConnectionStateChange","Status: " + status);

            switch (newState) {
                case BluetoothProfile.STATE_CONNECTED:
                    Log.i("gattCallback","STATE_CONNECTED");
                    gatt.discoverServices();
                    break;
                case BluetoothProfile.STATE_CONNECTING:
                    Log.i("gattCallback","STATE_CONNECTING");
                    break;
                case BluetoothProfile.STATE_disCONNECTED:
                    Log.e("gattCallback","STATE_disCONNECTED");
                    //gatt.close();
                    break;
                default:
                    Log.e("gattCallback","STATE_OTHER");
            }
        }


        @Override
        //New services discovered
        public void onServicesdiscovered(BluetoothGatt gatt,int status) {
            List<BluetoothGattService> services = gatt.getServices();
            Log.i("onServicesdiscovered",services.toString());
            gatt.readCharacteristic(services.get(1).getcharacteristics().get(0));
        }

        @Override
        //Result of a characteristic read operation
        public void onCharacteristicRead(BluetoothGatt gatt,BluetoothGattCharacteristic characteristic,int status) {
            Log.i("onCharacteristicRead",characteristic.toString());
            gatt.disconnect();
        }
    };

    private void listPairedDevices(View view){
        BANewArray.clear();
        BAarray.clear();
        deviceList.setText("PrevIoUsly Connected Devices");
        pairedDevices = bluetoothAdapter.getBondedDevices();
        if(bluetoothAdapter.isEnabled()){
            BANewArray.clear();
            BAarray.clear();
            for(BluetoothDevice device : pairedDevices)
                BAarray.add(device.getName() + "\n" + device.getAddress());

            Toast.makeText(getApplicationContext(),"Show paired devices","Bluetooth not on",Toast.LENGTH_SHORT).show();
        }
    }

    private void discover(View view) {
        deviceList.setText("Available Devices");
        BANewArray.clear();
        BAarray.clear();
        scanLeDevice(true);
    }

    private AdapterView.OnItemClickListener DeviceClickListener = new AdapterView.OnItemClickListener() {
        public void onItemClick(AdapterView<?> av,View v,int arg2,long arg3) {

            //BTSocket = null;
            String info = ((TextView) v).getText().toString();
            final String address = info.substring(info.length() - 17);
            final String name = info.substring(0,info.length() - 17);

            device = bluetoothAdapter.getRemoteDevice(address);

            Log.d(TAG,"You clicked");
            Log.d(TAG,"Device name" + name);
            Log.d(TAG,"Address" + address);

            Toast.makeText(getApplicationContext(),address,Toast.LENGTH_SHORT).show();
            connectToDevice(device);
        }
    };
}

解决方法

您可以使用 FroegroundService 在后台工作,在您的应用关闭后,将有不可关闭的通知,您的应用将继续工作。这是Android新版本中最好的解决方案,因为简单的服务会被Android杀死。您可以在 this article 中找到有关使用 FroegroundService 的更多信息。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。