后台服务崩溃

时间:2020-10-09 10:57:58

标签: java android service bluetooth-lowenergy

所以由于某种原因,我的后台服务崩溃了,我也不知道为什么。 因此,我的服务包含BLE,我使用以下方法从MainActivity绑定到该服务:

public void startBluetoothService() {
    // Start the BLE Service
    Log.d(TAG, "Starting BLE Service");
    Intent gattServiceIntent = new Intent(this, BLE_Service.class);
    bindService(gattServiceIntent, mServiceConnection, BIND_AUTO_CREATE);
    Log.d(TAG, "Bluetooth is Enabled");
}

这会运行,但随后出现以下错误

10-09 12:51:31.104 14007-14081/com.example.wrd I/ProviderInstaller: Installed default security provider GmsCore_OpenSSL
10-09 12:51:31.114 14007-14007/com.example.wrd D/AndroidRuntime: Shutting down VM
10-09 12:51:31.114 14007-14007/com.example.wrd E/AndroidRuntime: FATAL EXCEPTION: main
    Process: com.example.wrd, PID: 14007
    java.lang.RuntimeException: Unable to instantiate service com.example.wrd.ble.BLE_Service: java.lang.InstantiationException: java.lang.Class<com.example.wrd.ble.BLE_Service> has no zero argument constructor
        at android.app.ActivityThread.handleCreateService(ActivityThread.java:3841)
        at android.app.ActivityThread.access$2100(ActivityThread.java:229)
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1909)
        at android.os.Handler.dispatchMessage(Handler.java:102)
        at android.os.Looper.loop(Looper.java:148)
        at android.app.ActivityThread.main(ActivityThread.java:7325)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1230)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1120)
     Caused by: java.lang.InstantiationException: java.lang.Class<com.example.wrd.ble.BLE_Service> has no zero argument constructor
        at java.lang.Class.newInstance(Native Method)
        at android.app.ActivityThread.handleCreateService(ActivityThread.java:3838)
        at android.app.ActivityThread.access$2100(ActivityThread.java:229) 
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1909) 
        at android.os.Handler.dispatchMessage(Handler.java:102) 
        at android.os.Looper.loop(Looper.java:148) 
        at android.app.ActivityThread.main(ActivityThread.java:7325) 
        at java.lang.reflect.Method.invoke(Native Method) 
        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1230) 
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1120) 

我的服务如下:


public class BLE_Service extends Service {

    private Home ma;

    private boolean mscanning;
    public boolean Read = false;
    private Handler mHandler;

    private long scanPeriod;
    private int signalStrength;

    //Intent string
    private static String DeviceAddress;

    private static final String TAG = "BLE_Service";
    // Bluetooth objects that we need to interact with
    private static BluetoothManager mBluetoothManager;
    private static BluetoothAdapter mBluetoothAdapter;
    private static BluetoothGatt mBluetoothGatt;
    private static BluetoothDevice device;

    private static BluetoothGattCharacteristic BLECharacterisitc;
    private final static String BaseUuid = "00000000-0000-1000-8000-00805f9b34f";
    private final static String CSUuid = "00002902-0000-1000-8000-00805f9b34fb";
    private final static String UuidWrite = BaseUuid + "0";
    private final static String UuidRead = BaseUuid + "1";
    private final static String UuidRead2 = BaseUuid + "2";
    private final static String state_RW = BaseUuid + "0";
    private final static String treatmentSettings_RW = BaseUuid + "1";
    private final static String adjustment_RW = BaseUuid + "2";
    private final static String validation_R = BaseUuid + "3";

    //Broadcasts
    public final static String BROADCAST_ADDED = "added";
    public final static String BROADCAST_ADDEDFrag = "added";

    // Bluetooth characteristics that we need to read/write
    private static BluetoothGattCharacteristic mCharacterisitc, mCharacterisitc2, mCharacterisitcWrite, mCharacterisitc_state_RW,
            mCharacterisitc_treatmentSettings_RW, mCharacterisitc_adjustment_RW, mCharacterisitc_validation_R;


    private static StringBuilder sb = new StringBuilder();


    @Override
    public IBinder onBind(Intent intent) {
        return mBinder;
    }

    @RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN_MR2)
    public boolean connecting(String DeviceAddress) {
        Log.d(TAG, "Connection State: connect");
        device = mBluetoothAdapter.getRemoteDevice(DeviceAddress);
        if (device == null) {
            Log.d(TAG, "Connection State Device Not Available ");
            return false;
        } else {
            Log.d(TAG, "Connection State Connecting...");
            device.connectGatt(this, false, mGattCallback);
            return true;
        }
    }

    @RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN_MR2)
    public boolean disconnect() {
        mBluetoothGatt.disconnect();
        mBluetoothGatt.close();
        return true;
    }

    @RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN_MR2)
    public void checkConnectedDevices() {
        if (mBluetoothGatt != null){
            String DeviceString = mBluetoothGatt.getDevice().getAddress();
            String NameString = mBluetoothGatt.getDevice().getName();
            Log.d(TAG, "checkConnectedDevices: " + NameString);
            //broadCastHEX(BROADCAST_ADDEDFrag, NameString+";"+DeviceString, "get_conn_BLE_return");
        }else{
            //broadCastHEX(BROADCAST_ADDEDFrag, null, "Connected_BLE_Devices_return");
        }
    }

    public class LocalBinder extends Binder {
        public BLE_Service getService() {
            return BLE_Service.this;
        }
    }

    private final IBinder mBinder = new LocalBinder();

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        return super.onStartCommand(intent, flags, startId);
    }

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

    /**
     * Initializes a reference to the local Bluetooth adapter.
     *
     * @return Return true if the initialization is successful.
     */
    @RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN_MR2)
    public boolean initialize() {

        Log.d(TAG, "mBluetoothManager: service");
        // For API level 18 and above, get a reference to BluetoothAdapter through
        // BluetoothManager.
        if (mBluetoothManager == null) {
            mBluetoothManager = (BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE);
            if (mBluetoothManager == null) {
                Log.e(TAG, "Unable to initialize BluetoothManager.");
                return false;
            }
        }
        Log.d(TAG, "mBluetoothManager: initialize");
        BluetoothManager bluetoothManager = (BluetoothManager) getBaseContext().getSystemService(Context.BLUETOOTH_SERVICE);
        List<BluetoothDevice> devices = bluetoothManager.getConnectedDevices(BluetoothProfile.GATT);
        Log.d(TAG, "mBluetoothManager: initialize device" + devices.toString());
        for(BluetoothDevice device : devices) {
            if(device.getType() == BluetoothDevice.DEVICE_TYPE_LE) {
                Log.d(TAG, "mBluetoothManager: running loop" + device.getName() + "\n");
            }else{
                Log.d(TAG, "mBluetoothManager: nothing" + device.getName() + "\n");
            }
        }
        mBluetoothAdapter = mBluetoothManager.getAdapter();
        if (mBluetoothAdapter == null) {
            Log.e(TAG, "Unable to obtain a BluetoothAdapter.");
            return false;
        }

        return true;
    }

    @RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN_MR2)
    public BLE_Service(Home home, long scanPeriod, int signalStrength) {

        ma = home;

        mHandler = new Handler();

        this.scanPeriod = scanPeriod;
        this.signalStrength = signalStrength;

        final BluetoothManager bluetoothManager =
                (BluetoothManager) ma.getSystemService(Context.BLUETOOTH_SERVICE);

        mBluetoothAdapter = bluetoothManager.getAdapter();
    }

    public boolean isScanning() {
        return mscanning;
    }

    @RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN_MR2)
    public void start() {
        if (!Utils.checkBluetooth(mBluetoothAdapter)) {
            Utils.requestUserBluetooth(ma);
            ma.stopScan();
        } else {
            scanLeDevice(true);
        }
    }

    @RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN_MR2)
    public void stop() {
        scanLeDevice(false);
    }

    @RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN_MR2)
    private void scanLeDevice(final boolean enable) {
        if (enable && !mscanning) {
            Utils.toast(ma.getApplication(), "Starting BLE Scan...");
            mHandler.postDelayed(new Runnable() {
                @RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN_MR2)
                @Override
                public void run() {
                    Utils.toast(ma.getApplicationContext(), "Stopping BLE scan...");

                    mscanning = false;
                    mBluetoothAdapter.stopLeScan(mLeScanCallback);
                    ma.stopScan();
                }
            }, scanPeriod);

            mscanning = true;
            mBluetoothAdapter.startLeScan(mLeScanCallback);
        }
    }


    private BluetoothGattCallback mGattCallback = new BluetoothGattCallback() {
        @RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN_MR2)
        @Override
        public void onConnectionStateChange(final BluetoothGatt gatt, int status, int newState) {
            Log.d(TAG, "Connection State Change: " + status + " -> " + connectionState(newState));
            gatt.discoverServices();
            if (status == BluetoothGatt.GATT_SUCCESS && newState == BluetoothProfile.STATE_CONNECTED) {
                /*
                 * Once successfully connected, we must next discover all the services on the
                 * device before we can read and write their characteristics.
                 */
                mBluetoothGatt = gatt;
                BluetoothDevice device = gatt.getDevice();
                Log.d(TAG, "Connection State onConnectionStateChange: " + device);
            } else if (status == BluetoothGatt.GATT_SUCCESS && newState == BluetoothProfile.STATE_DISCONNECTED) {
                /*
                 * If at any point we disconnect, send a message to clear the weather values
                 * out of the UI
                 */
                Log.d(TAG, "Connection State: 2");
            } else if (status != BluetoothGatt.GATT_SUCCESS) {
                /*
                 * If there is a failure at any stage, simply disconnect
                 */
            }
        }

        /**
         * This is called when a service discovery has completed.
         *
         * It gets the characteristics we are interested in and then
         * broadcasts an update to the main activity.
         *
         * @param gatt The GATT database object
         * @param status Status of whether the write was successful.
         */
        @RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN_MR2)
        @Override
        public void onServicesDiscovered(final BluetoothGatt gatt, int status) {//prøv med ekstra status på denne
            if (status == BluetoothGatt.GATT_SUCCESS) {
                BluetoothGattService mBluetoothGattService = gatt.getService(UUID.fromString(CSUuid));
                if (mBluetoothGattService != null) {
                    Log.i(TAG, "Connection State: Service characteristic UUID found: " + mBluetoothGattService.getUuid().toString());
                    mCharacterisitc = mBluetoothGattService.getCharacteristic(UUID.fromString(UuidRead));
                    mCharacterisitc2 = mBluetoothGattService.getCharacteristic(UUID.fromString(UuidRead2));
                    mCharacterisitcWrite = mBluetoothGattService.getCharacteristic(UUID.fromString(UuidWrite));
                    //First activate buttons here....
                    Log.w(TAG, "Connection State 1: mCharacterisitc " + mCharacterisitc + " " + mCharacterisitc2);
                    Intent broadcastIntent = new Intent().putExtra("ConnState", true);
                    broadcastIntent.setAction(BLE_Service.BROADCAST_ADDED);
                    LocalBroadcastManager.getInstance(BLE_Service.this).sendBroadcast(broadcastIntent);
                    if(Read){
                        readCharacteristic(gatt, mCharacterisitc);
                    }
                } else {
                    Log.i(TAG, "Connection State: Service characteristic not found for UUID: " + UuidRead);
                }
            }
        }

        private String connectionState(int status) {
            switch (status) {
                case BluetoothProfile.STATE_CONNECTED:
                    return "Connection State: Connected";
                case BluetoothProfile.STATE_DISCONNECTED:
                    return "Connection State: Disconnected";
                case BluetoothProfile.STATE_CONNECTING:
                    return "Connection State: Connecting";
                case BluetoothProfile.STATE_DISCONNECTING:
                    return "Connection State: Disconnecting";
                default:
                    return String.valueOf(status);
            }
        }

        @RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN_MR2)
        @Override
        public void onCharacteristicRead(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status) {
            super.onCharacteristicRead(gatt, characteristic, status);
            if (status == BluetoothGatt.GATT_SUCCESS) {
                Log.d(TAG, "Connection State: onCharacteristicRead");
                Log.w(TAG, "Connection State: Read 1");
                // Verify that the read was the LED state
                String uuid = characteristic.getUuid().toString();
                // In this case, the only read the app does is the LED state.
                // If the application had additional characteristics to read we could
                // use a switch statement here to operate on each one separately.
                if (uuid.equalsIgnoreCase(UuidRead)) {
                    Log.w(TAG, "Connection State: Read 2");
                    final int Val = characteristic.getIntValue(BluetoothGattCharacteristic.FORMAT_UINT8, 0);
                    broadCast(BROADCAST_ADDEDFrag, Val, "read_Service");
                    Log.i(TAG, "Connection State: onCharacteristicRead: " + Val);
                    Log.d(TAG, "Connection State Read state: "+Read);
                    readCharacteristic(gatt, mCharacterisitc2);
                }
                if (uuid.equalsIgnoreCase(UuidRead2)) {
                    Log.w(TAG, "Connection State: Read 3");
                    final byte[] data = characteristic.getValue();
                    if (data != null && data.length > 0) {
                        final StringBuilder stringBuilder = new StringBuilder(data.length);
                        for (byte byteChar : data)
                            stringBuilder.append(String.format("%02X ", byteChar));
                        String msg = "letter: " + new String(data) + "\nHEX: " + stringBuilder.toString();
                        Log.d(TAG, "Connection State: onCharacteristicRead2: 4 " + msg);
                        broadCastHEX(BROADCAST_ADDEDFrag, msg, "read_Service2");
                    }
                    Read = false; //Has to be set to false in the last read message..
                    Log.d(TAG, "Connection State Read state: "+Read);
                }
            }
        }
    };

    /**
     * Runs service discovery on the connected device.
     *
     * @return
     */
    @RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN_MR2)
    public void discoverServices() {
        if (mBluetoothAdapter == null || mBluetoothGatt == null) {
            Log.d(TAG, "Connection State BluetoothAdapter not initialized");
            return;
        }
        mBluetoothGatt.discoverServices();
    }

    @RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN_MR2)
    public void Write(Integer integer) {
        if (mBluetoothAdapter == null || mBluetoothGatt == null) {
            Log.d(TAG, "Connection State BluetoothAdapter not initialized");
            return;
        }
        Integer Val = integer;
        byte[] byteVal;
        byteVal = intToByteArray(Val);
        mCharacterisitcWrite.setValue(byteVal);
        Log.d(TAG, "Connection State write 1: " + byteVal);
        mBluetoothGatt.writeCharacteristic(mCharacterisitcWrite);
    }

    public static byte[] intToByteArray(int a) {
        byte[] ret = new byte[4];
        ret[3] = (byte) (a & 0xFF);
        ret[2] = (byte) ((a >> 8) & 0xFF);
        ret[1] = (byte) ((a >> 16) & 0xFF);
        ret[0] = (byte) ((a >> 24) & 0xFF);
        return ret;
    }

    /**
     * This method is used to read the state of the LED from the device
     */
    @RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN_MR2)
    public void readCharacteristic(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic) {
        if (mBluetoothAdapter == null || gatt == null) {
            Log.w(TAG, "Connection State: BluetoothAdapter not initialized 2");
            return;
        }
        Log.w(TAG, "Connection State: BluetoothAdapter initialized");
        gatt.readCharacteristic(characteristic);
    }

    @RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN_MR2)
    private BluetoothAdapter.LeScanCallback mLeScanCallback =
            new BluetoothAdapter.LeScanCallback() {
                @Override
                public void onLeScan(final BluetoothDevice device, int rssi, byte[] scanRecord) {
                    final int new_rssi = rssi;
                    if (rssi > signalStrength && device.getName() != null) {
                        mHandler.post(new Runnable() {
                            @Override
                            public void run() {
                                try {
                                    FragmentBLE.addDevice(device, new_rssi);
                                } catch (Exception e) {
                                    e.printStackTrace();
                                }
                            }
                        });
                    }
                }
            };

    public void broadCast(String broadcastTXT, Integer Val, String key) {
        Log.d(TAG, "Connection State: -> broadCast: Service Broadcast");
        Intent broadcastIntent = new Intent().putExtra(key, Val);
        broadcastIntent.setAction(broadcastTXT);
        LocalBroadcastManager.getInstance(this).sendBroadcast(broadcastIntent);
    }

    public void broadCastHEX(String broadcastTXT, String Val, String key) {
        Log.d(TAG, "Connection State: -> broadCast: Service Broadcast");
        Intent broadcastIntent = new Intent().putExtra(key, Val);
        broadcastIntent.setAction(broadcastTXT);
        LocalBroadcastManager.getInstance(this).sendBroadcast(broadcastIntent);
    }
}

那么导致此错误发生的原因是什么? 似乎与java.lang.RuntimeException: Unable to instantiate service com.example.wrd.ble.BLE_Service有关,而且我一直在忙于探索,但似乎找不到任何有用的东西。

编辑

因此,在设置空的构造器之前,已完成填充的构造器。我绑定了onStart()

@RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN_MR2)
@Override
protected void onStart() {
    super.onStart();
    // Start the BLE Service
    Log.d(TAG, "Starting BLE Service");
    Intent gattServiceIntent = new Intent(this, BLE_Service.class);
    bindService(gattServiceIntent, mServiceConnection, BIND_AUTO_CREATE);
    Log.d(TAG, "Bluetooth is Enabled");
    registerReceiver(mBTStateUpdateReceiver, new IntentFilter(BluetoothAdapter.ACTION_STATE_CHANGED));
}

然后在我的oncreate中运行以下命令

mBTLeScanner = new BLE_Service(this, 7500, -75);

但是以某种方式BLE_Service(this, 7500, -75)onStart()之前完成

1 个答案:

答案 0 :(得分:1)

创建一个空的构造函数。

BLE_Service(){
}