Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/199.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android 多活动服务_Android_Android Activity_Bluetooth_Bluetooth Lowenergy_Gatt - Fatal编程技术网

Android 多活动服务

Android 多活动服务,android,android-activity,bluetooth,bluetooth-lowenergy,gatt,Android,Android Activity,Bluetooth,Bluetooth Lowenergy,Gatt,我正在开发一个与蓝牙模块(通过微芯片的RN4020)通信的应用程序。此应用程序使用处理与模块通信(连接/读取/写入)的服务。当我使用一个活动时,没有任何问题。当我使用2活动时,有一个问题。当我向模块发送数据时,手机与模块断开连接并崩溃。 我认为问题在于服务,根据我的说法,它在第二个活动中没有绑定。我怎样才能解决它 这是服务: public class BluetoothLeService extends Service { private final static String TAG = B

我正在开发一个与蓝牙模块(通过微芯片的RN4020)通信的应用程序。此应用程序使用处理与模块通信(连接/读取/写入)的服务。当我使用一个活动时,没有任何问题。当我使用2活动时,有一个问题。当我向模块发送数据时,手机与模块断开连接并崩溃。 我认为问题在于服务,根据我的说法,它在第二个活动中没有绑定。我怎样才能解决它

这是服务:

public class BluetoothLeService extends Service {

private final static String TAG = BluetoothLeService.class.getSimpleName();         //Get name of service to tag debug and warning messages
private BluetoothManager mBluetoothManager;                                         //BluetoothManager used to get the BluetoothAdapter
private BluetoothAdapter mBluetoothAdapter;                                         //The BluetoothAdapter controls the BLE radio in the phone/tablet
private BluetoothGatt mBluetoothGatt;                                               //BluetoothGatt controls the Bluetooth communication link
private String mBluetoothDeviceAddress;                                             //Address of the connected BLE device

public final static String ACTION_GATT_CONNECTED = "com.example.app.ACTION_GATT_CONNECTED"; //Strings representing actions to broadcast to activities
public final static String ACTION_GATT_DISCONNECTED = "com.example.app.ACTION_GATT_DISCONNECTED";
public final static String ACTION_GATT_SERVICES_DISCOVERED = "com.example.app.ACTION_GATT_SERVICES_DISCOVERED";
public final static String ACTION_DATA_AVAILABLE = "com.example.app.ACTION_DATA_AVAILABLE";
public final static String ACTION_DATA_WRITTEN = "com.example.app.ACTION_DATA_WRITTEN";
public final static String EXTRA_DATA = "com.example.app.EXTRA_DATA";

public final static UUID UUID_MLDP_DATA_PRIVATE_CHARACTERISTIC = UUID.fromString(WorkActivity.MLDP_DATA_PRIVATE_CHAR);
public final static UUID UUID_CHARACTERISTIC_NOTIFICATION_CONFIG = UUID.fromString(WorkActivity.CHARACTERISTIC_NOTIFICATION_CONFIG);

private final IBinder mBinder = new LocalBinder();                                  //Binder for Activity that binds to this Service

// ----------------------------------------------------------------------------------------------------------------
// An activity has bound to this service
@Override
public IBinder onBind(Intent intent) {
    return mBinder;                                                                 //Return LocalBinder when an Activity binds to this Service
}

// ----------------------------------------------------------------------------------------------------------------
// An activity has unbound from this service 
@Override
public boolean onUnbind(Intent intent) {
    /*if (mBluetoothGatt != null) {                                                   //Check for existing BluetoothGatt connection
        mBluetoothGatt.close();                                                     //Close BluetoothGatt coonection for proper cleanup
        mBluetoothGatt = null;                                                      //No longer have a BluetoothGatt connection
    }*/
    return super.onUnbind(intent);

}

// ----------------------------------------------------------------------------------------------------------------
// A Binder to return to an activity to let it bind to this service 
public class LocalBinder extends Binder {
    BluetoothLeService getService() {
        return BluetoothLeService.this;                                             //Return this instance of BluetoothLeService so clients can call its public methods
    }
}

// ----------------------------------------------------------------------------------------------------------------
// Implements callback methods for GATT events that the app cares about.  For example: connection change and services discovered.
// When onConnectionStateChange() is called with newState = STATE_CONNECTED then it calls mBluetoothGatt.discoverServices()
// resulting in another callback to onServicesDiscovered()
private final BluetoothGattCallback mGattCallback = new BluetoothGattCallback() {
    @Override
    public void onConnectionStateChange(BluetoothGatt gatt, int status, int newState) { //Change in connection state
        if (newState == BluetoothProfile.STATE_CONNECTED) {                         //See if we are connected
            broadcastUpdate(ACTION_GATT_CONNECTED);                                 //Go broadcast an intent to say we are connected
            Log.i(TAG, "Connected to GATT server, starting service discovery");
            mBluetoothGatt.discoverServices();                                      //Discover services on connected BLE device
        } 
        else if (newState == BluetoothProfile.STATE_DISCONNECTED) {                 //See if we are not connected
            broadcastUpdate(ACTION_GATT_DISCONNECTED);                              //Go broadcast an intent to say we are disconnected
            Log.i(TAG, "Disconnected from GATT server.");
        }
    }

    @Override
    public void onServicesDiscovered(BluetoothGatt gatt, int status) {              //BLE service discovery complete
        if (status == BluetoothGatt.GATT_SUCCESS) {                                 //See if the service discovery was successful
            broadcastUpdate(ACTION_GATT_SERVICES_DISCOVERED);                       //Go broadcast an intent to say we have discovered services
        } 
        else {                                                                      //Service discovery failed so log a warning
            Log.w(TAG, "onServicesDiscovered received: " + status);
        }
    }

    //For information only. This application uses Indication to receive updated characteristic data, not Read
    @Override
    public void onCharacteristicRead(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status) { //A request to Read has completed
        if (status == BluetoothGatt.GATT_SUCCESS) {                                 //See if the read was successful
            broadcastUpdate(ACTION_DATA_AVAILABLE, characteristic);                 //Go broadcast an intent with the characteristic data
        }
    }

    //For information only. This application sends small packets infrequently and does not need to know what the previous write completed
    @Override
    public void onCharacteristicWrite(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status) { //A request to Write has completed
        if (status == BluetoothGatt.GATT_SUCCESS) {                                 //See if the write was successful
            broadcastUpdate(ACTION_DATA_WRITTEN, characteristic);                   //Go broadcast an intent to say we have have written data
        }
    }

    @Override
    public void onCharacteristicChanged(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic) { //Indication or notification was received
        broadcastUpdate(ACTION_DATA_AVAILABLE, characteristic);                     //Go broadcast an intent with the characteristic data
    }
};

// ----------------------------------------------------------------------------------------------------------------
// Broadcast an intent with a string representing an action
private void broadcastUpdate(final String action) {
    final Intent intent = new Intent(action);                                       //Create new intent to broadcast the action
    sendBroadcast(intent);                                                          //Broadcast the intent
}

// ----------------------------------------------------------------------------------------------------------------
// Broadcast an intent with a string representing an action an extra string with the data
// Modify this code for data that is not in a string format 
private void broadcastUpdate(final String action, final BluetoothGattCharacteristic characteristic) {
    final Intent intent = new Intent(action);                                       //Create new intent to broadcast the action
    if(action.equals(ACTION_DATA_AVAILABLE)) {                                      //See if we need to send data
        if (UUID_MLDP_DATA_PRIVATE_CHARACTERISTIC.equals(characteristic.getUuid())) { //See if this is the correct characteristic 
            String dataValue = characteristic.getStringValue(0);                    //Get the data (in this case it is a string)
            intent.putExtra(EXTRA_DATA, dataValue);                                 //Add the data string to the intent
        }
    }
    else {                                                                          //Did not get an action string we expect 
        Log.d(TAG, "Action: " + action);
    }
    sendBroadcast(intent);                                                          //Broadcast the intent
}

// ----------------------------------------------------------------------------------------------------------------
// Initialize by getting the BluetoothManager and BluetoothAdapter 
public boolean initialize() {
    if (mBluetoothManager == null) {                                                //See if we do not already have the BluetoothManager
        mBluetoothManager = (BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE); //Get the BluetoothManager
        if (mBluetoothManager == null) {                                            //See if we failed
            Log.e(TAG, "Unable to initialize BluetoothManager.");
            return false;                                                           //Report the error
        }
    }

    mBluetoothAdapter = mBluetoothManager.getAdapter();                             //Ask the BluetoothManager to get the BluetoothAdapter
    if (mBluetoothAdapter == null) {                                                //See if we failed
        Log.e(TAG, "Unable to obtain a BluetoothAdapter.");
        return false;                                                               //Report the error
    }

    return true;                                                                    //Success, we have a BluetoothAdapter to control the radio
}

// ----------------------------------------------------------------------------------------------------------------
// Open a BluetoothGatt connection to a BLE device given its address
public boolean connect(final String address) {
    if (mBluetoothAdapter == null || address == null) {                             //Check that we have a Bluetooth adappter and device address
        Log.w(TAG, "BluetoothAdapter not initialized or unspecified address.");     //Log a warning that something went wrong
        return false;                                                               //Failed to connect
    }

    // Previously connected device.  Try to reconnect.
    if (mBluetoothDeviceAddress != null && address.equals(mBluetoothDeviceAddress) && mBluetoothGatt != null) { //See if there was previous connection to the device
        Log.d(TAG, "Trying to use an existing mBluetoothGatt for connection.");
        if (mBluetoothGatt.connect()) {                                             //See if we can connect with the existing BluetoothGatt to connect
            return true;                                                            //Success
        } 
        else {
            return false;                                                           //Were not able to connect
        }
    }

    final BluetoothDevice device = mBluetoothAdapter.getRemoteDevice(address);      //No previous device so get the Bluetooth device by referencing its address
    if (device == null) {                                                           //Check whether a device was returned
        Log.w(TAG, "Device not found.  Unable to connect.");                        //Warn that something went wrong
        return false;                                                               //Failed to find the device
    }

    mBluetoothGatt = device.connectGatt(this, false, mGattCallback);                //Directly connect to the device so autoConnect is false
    Log.d(TAG, "Trying to create a new connection.");
    mBluetoothDeviceAddress = address;                                              //Record the address in case we bneed to reconnect with the existing BluetoothGatt
    return true;
}

// ----------------------------------------------------------------------------------------------------------------
// Retrieve and return a list of supported GATT services on the connected device
public List<BluetoothGattService> getSupportedGattServices() {
    if (mBluetoothGatt == null) {                                                   //Check that we have a valid GATT connection
        return null;
    }
    return mBluetoothGatt.getServices();                                            //Get the list of services
}

// ----------------------------------------------------------------------------------------------------------------
// Disconnects an existing connection or cancel a pending connection
// BluetoothGattCallback.onConnectionStateChange() will get the result
public void disconnect() {
    if (mBluetoothAdapter == null || mBluetoothGatt == null) {                      //Check that we have a GATT connection to disconnect
        Log.w(TAG, "BluetoothAdapter not initialized");
        return;
    }
    mBluetoothGatt.disconnect();                                                    //Disconnect GATT connection
}

// ----------------------------------------------------------------------------------------------------------------
// Request a read of a given BluetoothGattCharacteristic. The Read result is reported asynchronously through the
// BluetoothGattCallback onCharacteristicRead callback method.
// For information only. This application uses Indication to receive updated characteristic data, not Read
public void readCharacteristic(BluetoothGattCharacteristic characteristic) {
    if (mBluetoothAdapter == null || mBluetoothGatt == null) {                      //Check that we have access to a Bluetooth radio
        Log.w(TAG, "BluetoothAdapter not initialized");
        return;
    }
    mBluetoothGatt.readCharacteristic(characteristic);                              //Request the BluetoothGatt to Read the characteristic
}

// ----------------------------------------------------------------------------------------------------------------
// Write to a given characteristic. The completion of the write is reported asynchronously through the
// BluetoothGattCallback onCharacteristicWrire callback method.
public void writeCharacteristic(BluetoothGattCharacteristic characteristic) {
    if (mBluetoothAdapter == null || mBluetoothGatt == null) {                      //Check that we have access to a Bluetooth radio
        Log.w(TAG, "BluetoothAdapter not initialized");
        return;
    }
    int test = characteristic.getProperties();                                      //Get the properties of the characteristic
    if ((test & BluetoothGattCharacteristic.PROPERTY_WRITE) == 0 && (test & BluetoothGattCharacteristic.PROPERTY_WRITE_NO_RESPONSE) == 0) { //Check that the property is writable 
        return;
    }

    if (mBluetoothGatt.writeCharacteristic(characteristic)) {                       //Request the BluetoothGatt to do the Write
        Log.d(TAG, "writeCharacteristic successful");                               //The request was accepted, this does not mean the write completed
    } 
    else {
        Log.d(TAG, "writeCharacteristic failed");                                   //Write request was not accepted by the BluetoothGatt
    }
}

// ----------------------------------------------------------------------------------------------------------------
// Enable notification on a characteristic
// For information only. This application uses Indication, not Notification
public void setCharacteristicNotification(BluetoothGattCharacteristic characteristic, boolean enabled) {
    if (mBluetoothAdapter == null || mBluetoothGatt == null) {                      //Check that we have a GATT connection
        Log.w(TAG, "BluetoothAdapter not initialized");
        return;
    }
    mBluetoothGatt.setCharacteristicNotification(characteristic, enabled);          //Enable notification and indication for the characteristic
//        if (UUID_MLDP_DATA_PRIVATE_CHARACTERISTIC.equals(characteristic.getUuid())) { 
    BluetoothGattDescriptor descriptor = characteristic.getDescriptor(UUID_CHARACTERISTIC_NOTIFICATION_CONFIG); //Get the descripter that enables notification on the server
    descriptor.setValue(BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE);         //Set the value of the descriptor to enable notification
    mBluetoothGatt.writeDescriptor(descriptor);                                     //Write the descriptor
//        }
}

// ----------------------------------------------------------------------------------------------------------------
// Enable indication on a characteristic
public void setCharacteristicIndication(BluetoothGattCharacteristic characteristic, boolean enabled) {
    if (mBluetoothAdapter == null || mBluetoothGatt == null) {                      //Check that we have a GATT connection
        Log.w(TAG, "BluetoothAdapter not initialized");
        return;
    }
    mBluetoothGatt.setCharacteristicNotification(characteristic, enabled);          //Enable notification and indication for the characteristic

    // This is specific to our custom profile
//        if (UUID_MLDP_DATA_PRIVATE_CHARACTERISTIC.equals(characteristic.getUuid())) {
    BluetoothGattDescriptor descriptor = characteristic.getDescriptor(UUID_CHARACTERISTIC_NOTIFICATION_CONFIG); //Get the descripter that enables indication on the server
    descriptor.setValue(BluetoothGattDescriptor.ENABLE_INDICATION_VALUE);           //Set the value of the descriptor to enable indication
    mBluetoothGatt.writeDescriptor(descriptor);                                     //Write the descriptor
//        }
}

}
在onPause()中:

在onCreate()中的第二个活动中,我调用:

提前谢谢你,对不起我的英语不好


我在@pskink的帮助下编辑了这个问题

Android中有两种类型的服务:启动绑定。你用的是第二个,邦德。此类型与启动它的组件的生命周期更相关

在您的场景中,我建议使用已启动的Android服务并拨打:

startService(intent);
在活动的
onCreate()
回调中启动它。最终,您还可以将其添加到应用程序java文件中


更多信息请访问:

在调用
bindService
之前启动服务,更多信息,请键入^F
绑定到已启动的服务
我建议您进行依赖项注入,但正如@pslink提醒我的,服务默认为单例,因此无法解决您的问题。抱歉:(@pskink在调用bindService之前,我试图启动该服务,但情况相同,这可能是因为您调用了
mbluetothgatt.close();
onUnbind
内部调用它,在其他地方调用它。它无论如何都不起作用。在第一个活动中,我调用:
gattServiceIntent=newintent(这是BluetoothLeService.class)
开始服务(gattServiceIntent);
绑定服务(gattServiceIntent,mServiceConnection,BIND_AUTO_CREATE);
在onPause()中我写:
super.onPause();
取消注册接收者(mGattUpdateReceiver);
取消绑定服务(mServiceConnection)
在另一个活动中,我只调用了
bindService(gattServiceIntent,mServiceConnection,BIND_AUTO_CREATE);
在onUnBind中,我删除了mblueouthgatt.close();但在第二个活动中它崩溃了第三种类型是:“启动并绑定”,请参见我上面的评论谢谢你的回答,我同意你的意见,最好使用它。”“已启动”而不是“绑定”。但是我如何修改我的服务以使其适应“已启动”
super.onPause();
unregisterReceiver(mGattUpdateReceiver);
unbindService(mServiceConnection);
mBluetoothLeService = null;
Intent gattServiceIntent = new Intent(this, BluetoothLeService.class);
bindService(gattServiceIntent, mServiceConnection, BIND_AUTO_CREATE);
startService(intent);