2014-05-18 53 views
0

我得到下一個異常,當我調用服務中的方法,並且在調試時,我看到onServiceConnected從不執行。我試圖把日誌放在裏面,但它永遠不會執行,我厭倦了等待它。OnServiceConnected從不執行

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

什麼行代碼是'ActivityMain.java:249'? –

+0

該行包含:bleService.connect(deviceAddress); – emirbet

+0

在這種情況下'b'很可能是空的。你初始化了它嗎? –

回答

1

嘗試在AndroidManifest.xml中爲BLEService類聲明完整的包路徑。例如

<service android:name="com.example.bluetooth.le.BLEService" android:enabled="true"/>

+0

這幫了我。 –