当我在Service中调用一个方法时,我得到了下一个异常,当调试时,我发现onServiceConnected永远不会执行。我试图将Logs放入其中,但它永远不会执行,我厌倦了等待它。
05-18 19:31:13.998 7031-7031/? E/AndroidRuntime﹕ FATAL EXCEPTION: main
Process: com.geochildfragment.app, PID: 7031
java.lang.NullPointerException
at com.geochildfragment.app.ActivityMain.sendPin(ActivityMain.java:249)
at com.geochildfragment.app.FragmentLinkDevice$4.onClick(FragmentLinkDevice.java:224)
at android.view.View.performClick(View.java:4626)
at android.view.View$PerformClick.run(View.java:19293)
at android.os.Handler.handleCallback(Handler.java:733)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:157)
at android.app.ActivityThread.main(ActivityThread.java:5293)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:515)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1265)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1081)
at dalvik.system.NativeStart.main(Native Method)
这是我的活动,我调用sendPin方法,它从片段中抛出异常:
int bStatus;
Boolean connected = false;
BluetoothDevice bDevice;
private BLEService bleService;
BluetoothGattService gattService;
public static final String EXTRA_BLUETOOTH_DEVICE = "BT_DEVICE";
BluetoothAdapter bAdapter;
Context context;
private final ServiceConnection mServiceConnection = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName componentName, IBinder service) {
bleService = ((BLEService.LocalBinder) service).getService();
if (!bleService.initialize()){
finish();
}
bleService.context = context;
}
@Override
public void onServiceDisconnected(ComponentName componentName) {
bleService=null;
}
};
private final BroadcastReceiver serviceUpdateReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
final String action = intent.getAction();
if (BLEService.ACTION_GATT_CONNECTED.equals(action)) {
connected = true;
//invalidateOptionsMenu();
} else if (BLEService.ACTION_GATT_DISCONNECTED.equals(action)) {
connected = false;
//invalidateOptionsMenu();
} else if (BLEService.ACTION_GATT_SERVICES_DISCOVERED.equals(action)) {
List<BluetoothGattService> servicesList;
servicesList = bleService.getSupportedGattServices();
Iterator<BluetoothGattService> iter = servicesList.iterator();
while (iter.hasNext()) {
BluetoothGattService bService = (BluetoothGattService) iter.next();
if (bService.getUuid().toString().equals(BLEUUID.SERVICE)){
gattService = bService;
}
}
} else if (BLEService.ACTION_DATA_AVAILABLE.equals(action)) {
........
}
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
context = getApplicationContext();
Bundle extra = this.getIntent().getExtras();
getConnectedDevices(extra);
if (mServiceConnection == null){
Log.v("NULL", "mServiceConnection NULL");
}
Intent gattServiceIntent = new Intent(this, BLEService.class);
if (gattServiceIntent==null){
Log.v("NULL", "mServiceConnection NULL");
}
bindService(gattServiceIntent, mServiceConnection, BIND_AUTO_CREATE);
bStatus = BluetoothProfile.STATE_DISCONNECTED;
}
@Override
public void onDestroy() {
super.onDestroy();
unbindService(mServiceConnection);
bleService = null;
}
@Override
public void onResume() {
super.onResume();
registerReceiver(serviceUpdateReceiver, makeGattUpdateIntentFilter());
}
@Override
public void onPause() {
super.onPause();
unregisterReceiver(serviceUpdateReceiver);
}
private static IntentFilter makeGattUpdateIntentFilter() {
final IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction(BLEService.ACTION_GATT_CONNECTED);
intentFilter.addAction(BLEService.ACTION_GATT_DISCONNECTED);
intentFilter.addAction(BLEService.ACTION_GATT_SERVICES_DISCOVERED);
intentFilter.addAction(BLEService.ACTION_DATA_AVAILABLE);
return intentFilter;
}
@Override
public void sendPin(BluetoothDevice bDevice, String pin) {
String deviceAddress = bDevice.getAddress();
bleService.connect(deviceAddress);
bleService.sendPINCharacteristic(pin, bDevice);
}
public void verifyPIN(String data){
FragmentLinkDevice f = (FragmentLinkDevice) getSupportFragmentManager().findFragmentById(R.id.link_device_fragment);
if (data.contains(BroadcastIDs.OK)){
f.launchDeviceConfigActivity()
} else if (data.contains(BroadcastIDs.FAIL)){
f.launchAlertDialog();
}
}
}
在清单中,我通过以下方式宣布:
<service android:name="Bluetooth.BLEService" android:enabled="true"/>
这是服务:
public class BLEService extends Service {
private static int DELAY = 3000;
private final static String TAG = BLEService.class.getSimpleName();
public Context context;
private BluetoothManager mBluetoothManager;
private BluetoothAdapter mBluetoothAdapter;
private String mBluetoothDeviceAddress;
private BluetoothGatt mBluetoothGatt;
private int mConnectionState = STATE_DISCONNECTED;
BluetoothGattService mService;
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 ="com.example.bluetooth.le.ACTION_GATT_CONNECTED";
public final static String ACTION_GATT_DISCONNECTED ="com.example.bluetooth.le.ACTION_GATT_DISCONNECTED";
public final static String ACTION_GATT_SERVICES_DISCOVERED ="com.example.bluetooth.le.ACTION_GATT_SERVICES_DISCOVERED";
public final static String ACTION_DATA_AVAILABLE ="com.example.bluetooth.le.ACTION_DATA_AVAILABLE";
public final static String EXTRA_DATA ="com.example.bluetooth.le.EXTRA_DATA";
public final static String SERVICE = BLEUUID.SERVICE;
public final static UUID PIN_CHARACTERISTIC = UUID.fromString(BLEUUID.PIN_CHARACTERISTIC_UUID);
public final static UUID PUK_CHARACTERISTIC = UUID.fromString(BLEUUID.PUK_UUID);
public final static UUID INTERVAL_CHARACTERISTIC = UUID.fromString(BLEUUID.INTERVAL_UUID);
public final static UUID ROUTE_INTERVAL_CHARACTERISTIC = UUID.fromString(BLEUUID.ROUTE_INTERVAL_UUID);
public final static UUID ON_OFF_CHARACTERISTIC = UUID.fromString(BLEUUID.ON_OFF_UUID);
public final static UUID GPS1_CHARACTERISTIC= UUID.fromString(BLEUUID.GPS1_UUID);
public final static UUID GPS2_CHARACTERISTIC= UUID.fromString(BLEUUID.GPS2_UUID);
public final static UUID BATTERY_CHARACTERISTIC = UUID.fromString(BLEUUID.BATTERY_LEVEL_UUID);
public final static UUID DEVICE_NAME_CHARACTERISTIC = UUID.fromString(BLEUUID.DEVICE_NAME_UUID);
私人决赛BluetoothGattCallback mGattCallback =新的BluetoothGattCallback(){
@Override
public void onConnectionStateChange(BluetoothGatt gatt, int status, int newState) {
String intentAction;
if (newState == BluetoothProfile.STATE_CONNECTED) {
intentAction = ACTION_GATT_CONNECTED;
mConnectionState = STATE_CONNECTED;
broadcastUpdate(intentAction);
Log.i(TAG, "Connected to GATT server.");
// Attempts to discover services after successful connection.
Log.i(TAG, "Attempting to start service discovery:" +
mBluetoothGatt.discoverServices());
} else if (newState == BluetoothProfile.STATE_DISCONNECTED) {
intentAction = ACTION_GATT_DISCONNECTED;
mConnectionState = STATE_DISCONNECTED;
Log.i(TAG, "Disconnected from GATT server.");
broadcastUpdate(intentAction);
Devices device = new Devices();
device = device.FindByDeviceAddress(mBluetoothDeviceAddress);
//showPerimeterNotification(device);
}
}
@Override
public void onServicesDiscovered(BluetoothGatt gatt, int status) {
if (status == BluetoothGatt.GATT_SUCCESS) {
for (BluetoothGattService service : gatt.getServices()) {
if ((service == null) || (service.getUuid() == null)) {
continue;
}
if (BLEUUID.SERVICE.equalsIgnoreCase(service.getUuid().toString())) {
mService = service;
}
}
broadcastUpdate(ACTION_GATT_SERVICES_DISCOVERED);
} else {
Log.w(TAG, "onServicesDiscovered received: " + status);
}
}
@Override
public void onCharacteristicRead(BluetoothGatt gatt,BluetoothGattCharacteristic characteristic,int status) {
if (status == BluetoothGatt.GATT_SUCCESS) {
broadcastUpdate(ACTION_DATA_AVAILABLE, characteristic);
broadcastUpdate(EXTRA_DATA, characteristic);
}
}
@Override
public void onCharacteristicChanged(BluetoothGatt gatt,BluetoothGattCharacteristic characteristic) {
readCharacteristic(characteristic);
broadcastUpdate(ACTION_DATA_AVAILABLE, characteristic);
}
@Override
public void onDescriptorWrite(BluetoothGatt gatt, BluetoothGattDescriptor descriptor, int status){
if (status== BluetoothGatt.GATT_SUCCESS){
Toast.makeText(context, "onDescriptorWrite: SUCCESS", Toast.LENGTH_LONG).show();
}else{
Toast.makeText(context, "onDescriptorWrite: FAILURE", Toast.LENGTH_LONG).show();
}
}
};
private void broadcastUpdate(final String action) {
final Intent intent = new Intent(action);
sendBroadcast(intent);
}
@TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR2)
private void broadcastUpdate(final String action,final BluetoothGattCharacteristic characteristic) {
final Intent intent = new Intent(action);
if (PIN_CHARACTERISTIC.equals(characteristic.getUuid())) {
final String pin = characteristic.getStringValue(0);
intent.putExtra(EXTRA_DATA, BroadcastIDs.PIN + String.valueOf(pin));
disconnect();
}
sendBroadcast(intent);
}
public class LocalBinder extends Binder {
public BLEService getService() {
return BLEService.this;
}
}
@Override
public IBinder onBind(Intent intent) {
return mBinder;
}
@Override
public boolean onUnbind(Intent intent) {
close();
return super.onUnbind(intent);
}
private final IBinder mBinder = new LocalBinder();
public boolean initialize() {
if (mBluetoothManager == null) {
mBluetoothManager = (BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE);
if (mBluetoothManager == null) {
return false;
}
}
mBluetoothAdapter = mBluetoothManager.getAdapter();
if (mBluetoothAdapter == null) {
return false;
}
return true;
}
public boolean connect(final String address) {
if (mBluetoothAdapter == null || address == null) {
return false;
}
// Previously connected device. Try to reconnect.
if (mBluetoothDeviceAddress != null && address.equals(mBluetoothDeviceAddress)
&& mBluetoothGatt != null) {
if (mBluetoothGatt.connect()) {
mConnectionState = STATE_CONNECTING;
return true;
} else {
return false;
}
}
final BluetoothDevice device = mBluetoothAdapter.getRemoteDevice(address);
if (device == null) {
return false;
}
mBluetoothGatt = device.connectGatt(this, false, mGattCallback);
mBluetoothDeviceAddress = address;
mConnectionState = STATE_CONNECTING;
return true;
}
public void disconnect() {
if (mBluetoothAdapter == null || mBluetoothGatt == null) {
return;
}
mBluetoothGatt.disconnect();
}
public void close() {
if (mBluetoothGatt == null) {
return;
}
mBluetoothGatt.close();
mBluetoothGatt = null;
}
public void readCharacteristic(BluetoothGattCharacteristic characteristic) {
if (mBluetoothAdapter == null || mBluetoothGatt == null) {
return;
}
mBluetoothGatt.readCharacteristic(characteristic);
Log.i("READ", "CARACTERISTICA LEIDA");
}
public void setCharacteristicNotification(BluetoothGattCharacteristic characteristic, boolean enabled) {
if (mBluetoothAdapter == null || mBluetoothGatt == null) {
return;
}
mBluetoothGatt.setCharacteristicNotification(characteristic, enabled);
if (PIN_CHARACTERISTIC.equals(characteristic.getUuid())){
/*BluetoothGattDescriptor descriptor = characteristic.getDescriptor
(UUID.nameUUIDFromBytes(BLEUUID.fromHexToString(BLEUUID.PIN_CHARACTERISTIC_CONFIG_DESCRIPTOR)));*/
BluetoothGattDescriptor descriptor =
new BluetoothGattDescriptor(UUID.fromString(BLEUUID.CONFIG_UUID),BluetoothGattDescriptor.PERMISSION_WRITE_SIGNED);
//descriptor.setValue(BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE);
descriptor.setValue(BluetoothGattDescriptor.ENABLE_INDICATION_VALUE);
mBluetoothGatt.writeDescriptor(descriptor);
}
}
public List<BluetoothGattService> getSupportedGattServices() {
if (mBluetoothGatt == null) return null;
return mBluetoothGatt.getServices();
}
public void sendPINCharacteristic(String pin, BluetoothDevice device){
byte[] pinByte = pin.getBytes();
int pinInt = Integer.valueOf(pin);
connect(device.getAddress());
final BluetoothGattCharacteristic ch = (BluetoothGattCharacteristic) mService.getCharacteristic(UUID
.fromString(BLEUUID.PIN_CHARACTERISTIC_UUID));
ch.setWriteType(BluetoothGattCharacteristic.WRITE_TYPE_DEFAULT);
ch.setValue(pin);
mBluetoothGatt = device.connectGatt(this, false, mGattCallback);
setCharacteristicNotification(ch, true);
mBluetoothGatt.writeCharacteristic(ch);
}
}
有人知道这是什么问题吗?
答案 0 :(得分:1)
尝试在AndroidManifest.xml中声明BLEService类的完整包路径。例如
<service android:name="com.example.bluetooth.le.BLEService" android:enabled="true"/>