我的理解是,可以一次绑定多个活动中的同一服务。但是,尝试从MainActivity.java之外的第二个活动(使用startService启动服务)绑定到服务时,经常遇到问题。
在这里,我尝试从新活动(SensorDataDisplay.java)绑定到服务(BluetoothLeService.java)。该服务最初是在我的MainActivity.java活动中启动的,然后绑定在MainActivity中。
我已经编写了一些代码来检查绑定是否成功,并不断返回false。
与第二个活动绑定时,有什么需要做不同的事情吗?
SensorDataDisplay.java(第二项活动)
package com.august.customtisensortagclient;
import android.bluetooth.BluetoothGatt;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.IBinder;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.widget.TextView;
public class SensorDataDisplay extends AppCompatActivity {
private static final String TAG = "SensorDataDisplay";
TextView tester;
BluetoothLeServiceForLeft mBluetoothLeServiceForLeft;
boolean mBoundLeft = false;
BluetoothLeServiceForRight mBluetoothLeServiceForRight;
boolean mBoundRight;
BluetoothGatt bluetoothGattLeft;
BluetoothGatt bluetoothGattRight;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_sensor_data_display);
Intent intent = getIntent(); //From MainActivity.java
String value = intent.getStringExtra("key");//if it's a string you stored.
// Checker code (to see if successful bind)
tester = (TextView) findViewById(R.id.textView2);
tester.append(value);
if (mBoundLeft) {
tester.append("TRUEEEEE");
} else if (!mBoundLeft)
tester.append("FALSEEEEE");
}
@Override
protected void onStart() {
super.onStart();
// Bind to LocalService
Intent intentLeft = new Intent(this, BluetoothLeServiceForLeft.class);
bindService(intentLeft, mServiceConnectionLeft, Context.BIND_AUTO_CREATE);
}
@Override
protected void onStop() {
super.onStop();
unbindService(mServiceConnectionLeft);
mBoundLeft = false;
}
private ServiceConnection mServiceConnectionLeft = new ServiceConnection() {
// Called when the connection with the service is established
@Override
public void onServiceConnected(ComponentName className, IBinder service) {
// Because we have bound to an explicit
// service that is running in our own process, we can
// cast its IBinder to a concrete class and directly access it.
BluetoothLeServiceForLeft.LocalBinder binder = (BluetoothLeServiceForLeft.LocalBinder) service;
mBluetoothLeServiceForLeft = binder.getService();
mBoundLeft = true;
}
// Called when the connection with the service disconnects unexpectedly
@Override
public void onServiceDisconnected(ComponentName className) {
Log.e(TAG, "onServiceDisconnected");
mBoundLeft = false;
}
};
}
BluetoothLeServiceForLeft.java(请原谅。为了防止有人验证我对LocalBinder方法的使用,我只是想包含它。
package com.august.customtisensortagclient;
import android.app.Service;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothGatt;
import android.bluetooth.BluetoothGattCallback;
import android.bluetooth.BluetoothGattCharacteristic;
import android.bluetooth.BluetoothManager;
import android.bluetooth.BluetoothProfile;
import android.content.Context;
import android.content.Intent;
import android.os.Binder;
import android.os.IBinder;
import android.util.Log;
import java.util.UUID;
public class BluetoothLeServiceForLeft extends Service {
private final static String TAG = BluetoothLeServiceForLeft.class.getSimpleName();
private BluetoothManager mBluetoothManager;
private BluetoothAdapter mBluetoothAdapter;
private String mBluetoothDeviceAddress;
private BluetoothGatt mBluetoothGatt;
private int mConnectionState = STATE_DISCONNECTED;
private static final int STATE_DISCONNECTED = 0;
private static final int STATE_CONNECTING = 1;
private static final int STATE_CONNECTED = 2;
public final static String ACTION_GATT_CONNECTED_LEFT =
"com.example.bluetooth.le.ACTION_GATT_CONNECTED_LEFT";
public final static String ACTION_GATT_DISCONNECTED_LEFT =
"com.example.bluetooth.le.ACTION_GATT_DISCONNECTED_LEFT";
public final static String ACTION_GATT_SERVICES_DISCOVERED_LEFT =
"com.example.bluetooth.le.ACTION_GATT_SERVICES_DISCOVERED_LEFT";
public final static String ACTION_DATA_AVAILABLE_LEFT =
"com.example.bluetooth.le.ACTION_DATA_AVAILABLE_LEFT";
public final static String EXTRA_DATA_LEFT =
"com.example.bluetooth.le.EXTRA_DATA_LEFT";
// Various callback methods defined by the BLE API.
private final BluetoothGattCallback mGattCallback =
new BluetoothGattCallback() {
@Override
public void onConnectionStateChange(BluetoothGatt gatt, int status,
int newState) {
String intentAction;
if (newState == BluetoothProfile.STATE_CONNECTED) {
intentAction = ACTION_GATT_CONNECTED_LEFT;
mConnectionState = STATE_CONNECTED;
broadcastUpdate(intentAction);
Log.i(TAG, "Connected to GATT server.");
Log.i(TAG, "Attempting to start service discovery:" +
mBluetoothGatt.discoverServices());
} else if (newState == BluetoothProfile.STATE_DISCONNECTED) {
intentAction = ACTION_GATT_DISCONNECTED_LEFT;
mConnectionState = STATE_DISCONNECTED;
close();
Log.i(TAG, "Disconnected from GATT server and closed.");
broadcastUpdate(intentAction);
}
}
@Override
// New services discovered
public void onServicesDiscovered(BluetoothGatt gatt, int status) {
if (status == BluetoothGatt.GATT_SUCCESS) {
broadcastUpdate(ACTION_GATT_SERVICES_DISCOVERED_LEFT);
Log.w(TAG, "GATT services discovered.");
} else {
Log.w(TAG, "onServicesDiscovered received: " + status);
}
}
@Override
// Result of a characteristic read operation
public void onCharacteristicRead(BluetoothGatt gatt,
BluetoothGattCharacteristic characteristic,
int status) {
if (status == BluetoothGatt.GATT_SUCCESS) {
broadcastUpdate(ACTION_DATA_AVAILABLE_LEFT, characteristic);
}
}
};
/**
* Initializes a reference to the local Bluetooth adapter.
*
* @return Return true if the initialization is successful.
*/
public boolean initialize() {
// 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;
}
}
mBluetoothAdapter = mBluetoothManager.getAdapter();
if (mBluetoothAdapter == null) {
Log.e(TAG, "Unable to obtain a BluetoothAdapter.");
return false;
}
return true;
}
private void broadcastUpdate(final String action) {
final Intent intent = new Intent(action);
sendBroadcast(intent);
}
private void broadcastUpdate(final String action,
final BluetoothGattCharacteristic characteristic) {
final Intent intent = new Intent(action);
sendBroadcast(intent);
}
public class LocalBinder extends Binder {
BluetoothLeServiceForLeft getService() {
return BluetoothLeServiceForLeft.this;
}
}
@Override
public IBinder onBind(Intent intent) {
return mBinder;
}
@Override
public boolean onUnbind(Intent intent) {
// After using a given device, you should make sure that BluetoothGatt.close() is called
// such that resources are cleaned up properly. In this particular example, close() is
// invoked when the UI is disconnected from the Service.
close();
return super.onUnbind(intent);
}
public void close() {
if (mBluetoothGatt == null) {
return;
}
mBluetoothGatt.close();
mBluetoothGatt = null;
}
public boolean connect(final String address) {
if (mBluetoothAdapter == null || address == null) {
Log.w(TAG, "BluetoothAdapter not initialized or unspecified address.");
return false;
}
// Previously connected device. Try to reconnect.
if (mBluetoothDeviceAddress != null && address.equals(mBluetoothDeviceAddress)
&& mBluetoothGatt != null) {
Log.d(TAG, "Trying to use an existing mBluetoothGatt for connection.");
if (mBluetoothGatt.connect()) {
mConnectionState = STATE_CONNECTING;
return true;
} else {
return false;
}
}
final BluetoothDevice device = mBluetoothAdapter.getRemoteDevice(address);
if (device == null) {
Log.w(TAG, "Device not found. Unable to connect.");
return false;
}
// We want to directly connect to the device, so we are setting the autoConnect
// parameter to false.
mBluetoothGatt = device.connectGatt(this, false, mGattCallback);
Log.d(TAG, "Trying to create a new connection.");
mBluetoothDeviceAddress = address;
mConnectionState = STATE_CONNECTING;
return true;
}
public boolean disconnect(final String address) {
if (mBluetoothAdapter == null || address == null) {
Log.w(TAG, "BluetoothAdapter not initialized or unspecified address.");
return false;
}
final BluetoothDevice device = mBluetoothAdapter.getRemoteDevice(address);
if (device == null) {
Log.w(TAG, "Device not found. Unable to connect.");
return false;
}
mBluetoothGatt.disconnect();
Log.w(TAG, "Bluetooth device disconnected from GATT");
return true;
}
public BluetoothGatt getBluetoothGatt() {
return mBluetoothGatt;
}
private final IBinder mBinder = new LocalBinder();
}
答案 0 :(得分:0)
由于您在mBoundLeft
方法中测试了onCreate()
,并在onStart()
中绑定了服务,并在onStop()
中取消了绑定(同样,您也没有将瞬态保存到(如果您的应用被终止),您将永远看不到mBoundLeft
是否为真(请查看活动生命周期)。您应该使用例如onServiceConnected()
测试服务是否已绑定在log.d
内部。您应该执行以下操作:
public void onServiceConnected(ComponentName className, IBinder service) {
// Because we have bound to an explicit
// service that is running in our own process, we can
// cast its IBinder to a concrete class and directly access it.
BluetoothLeServiceForLeft.LocalBinder binder =
(BluetoothLeServiceForLeft.LocalBinder) service;
mBluetoothLeServiceForLeft = binder.getService();
mBoundLeft = true;
Log.d("ServiceConnection", "Service is connected");
}
我建议您学习使用Android中的Log
类进行调试,这在Android开发人员中会更好(也是一种标准)。