如何通过getSystemService(java.lang.String)修复NullPointerException?

时间:2019-01-21 17:15:25

标签: android nullpointerexception bluetooth bluetooth-lowenergy

我正在为现有应用程序实现心脏传感器,我使用google BLE连接示例作为我的基础(https://github.com/googlesamples/android-BluetoothLeGatt)。问题是,在示例中,当他们连接到设备时,它们显示了所有特征,因此您需要按一下以实际查看数据。我正在尝试使该部分自动化,因此最后您应该只按一下心脏监护仪设备,正确的特性应会自动连接。

因此,我对原始代码进行了一些更改,因此现在我得到“试图在空对象上调用虚拟方法'java.lang.Object android.content.Context.getSystemService(java.lang.String)'”错误。完全错误:

java.lang.RuntimeException: Unable to start activity ComponentInfo{com.bookbeo.vapa/com.bookbeo.vapa.controller.DeviceControlActivity}: java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.Object android.content.Context.getSystemService(java.lang.String)' on a null object reference
    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2974)
    at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3059)
    at android.app.ActivityThread.-wrap11(Unknown Source:0)
    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1724)
    at android.os.Handler.dispatchMessage(Handler.java:106)
    at android.os.Looper.loop(Looper.java:164)
    at android.app.ActivityThread.main(ActivityThread.java:7000)
    at java.lang.reflect.Method.invoke(Native Method)
    at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:441)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1408)
 Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.Object android.content.Context.getSystemService(java.lang.String)' on a null object reference
    at android.content.ContextWrapper.getSystemService(ContextWrapper.java:733)
    at com.bookbeo.vapa.controller.BluetoothLeService.initialize(BluetoothLeService.java:187)
    at com.bookbeo.vapa.controller.DeviceControlActivity.onCreate(DeviceControlActivity.java:190)
    at android.app.Activity.performCreate(Activity.java:7258)
    at android.app.Activity.performCreate(Activity.java:7249)
    at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1222)
    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2927)
    at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3059) 
    at android.app.ActivityThread.-wrap11(Unknown Source:0) 
    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1724) 
    at android.os.Handler.dispatchMessage(Handler.java:106) 
    at android.os.Looper.loop(Looper.java:164) 
    at android.app.ActivityThread.main(ActivityThread.java:7000) 
    at java.lang.reflect.Method.invoke(Native Method) 
    at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:441) 
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1408) 

我在StackOverflow上阅读了所有类似的问题,但没有getApplicationContext()或this.getSystemService ...的建议都无效。

所以我有DeviceScanActivity显示所有设备,当您单击其中一个设备时,DeviceControlActivity使用BluetoothLeService类。

DeviceScanActivity重要部分:

public class DeviceScanActivity extends ListActivity {
private LeDeviceListAdapter mLeDeviceListAdapter;
private BluetoothAdapter mBluetoothAdapter;
private boolean mScanning;
private Handler mHandler;

private static final int REQUEST_ENABLE_BT = 1;
// Stops scanning after 10 seconds.
private static final long SCAN_PERIOD = 10000;

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    /*getActionBar().setTitle(R.string.title_devices);*/
    mHandler = new Handler();
    // Use this check to determine whether BLE is supported on the device.  Then you can
    // selectively disable BLE-related features.
    if (!getPackageManager().hasSystemFeature(PackageManager.FEATURE_BLUETOOTH_LE)) {
        Toast.makeText(this, R.string.ble_not_supported, Toast.LENGTH_SHORT).show();
        finish();
    }
    // Initializes a Bluetooth adapter.  For API level 18 and above, get a reference to
    // BluetoothAdapter through BluetoothManager.
    final BluetoothManager bluetoothManager =
            (BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE);
    mBluetoothAdapter = bluetoothManager.getAdapter();
    // Checks if Bluetooth is supported on the device.
    if (mBluetoothAdapter == null) {
        Toast.makeText(this, R.string.error_bluetooth_not_supported, Toast.LENGTH_SHORT).show();
        finish();
        return;
    }
}
@Override
protected void onListItemClick(ListView l, View v, int position, long id) {
    final BluetoothDevice device = mLeDeviceListAdapter.getDevice(position);
    if (device == null) return;
    final Intent intent = new Intent(this, DeviceControlActivity.class);
    intent.putExtra(DeviceControlActivity.EXTRAS_DEVICE_NAME, device.getName());
    intent.putExtra(DeviceControlActivity.EXTRAS_DEVICE_ADDRESS, device.getAddress());
    //TODO: add here the sensor heart rate setting
    System.out.println("list item clicked");
    if (mScanning) {
        mBluetoothAdapter.stopLeScan(mLeScanCallback);
        mScanning = false;
    }
    startActivity(intent);
}

DeviceControlActivity重要部分:

public class DeviceControlActivity extends Activity {
private final static String TAG = DeviceControlActivity.class.getSimpleName();

public static final String EXTRAS_DEVICE_NAME = "DEVICE_NAME";
public static final String EXTRAS_DEVICE_ADDRESS = "DEVICE_ADDRESS";

private TextView mConnectionState;
private TextView mDataField;
private String mDeviceName;
private String mDeviceAddress;
private ExpandableListView mGattServicesList;
private BluetoothLeService mBluetoothLeService = new BluetoothLeService();
private ArrayList<ArrayList<BluetoothGattCharacteristic>> mGattCharacteristics =
        new ArrayList<ArrayList<BluetoothGattCharacteristic>>();
private boolean mConnected = false;
private BluetoothGattCharacteristic mNotifyCharacteristic;

private final String LIST_NAME = "NAME";
private final String LIST_UUID = "UUID";


// Code to manage Service lifecycle.
private final ServiceConnection mServiceConnection = new ServiceConnection() {

    @Override
    public void onServiceConnected(ComponentName componentName, IBinder service) {
        mBluetoothLeService = ((BluetoothLeService.LocalBinder) service).getService();
        mBluetoothLeService.initialize();
        if (!mBluetoothLeService.initialize()) {
            Log.e(TAG, "Unable to initialize Bluetooth");
            finish();
        }

        // Automatically connects to the device upon successful start-up initialization.
        mBluetoothLeService.connect(mDeviceAddress);
        Log.d(TAG, "service connection initialized");
    }

    @Override
    public void onServiceDisconnected(ComponentName componentName) {
        mBluetoothLeService = null;
    }
};
@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    final Intent intent = getIntent();
    mDeviceName = intent.getStringExtra(EXTRAS_DEVICE_NAME);
    mDeviceAddress = intent.getStringExtra(EXTRAS_DEVICE_ADDRESS);
    Intent gattServiceIntent = new Intent(this, BluetoothLeService.class);
    this.bindService(gattServiceIntent, mServiceConnection, BIND_AUTO_CREATE);
    mBluetoothLeService.initialize();
    mBluetoothLeService.connect(mDeviceAddress);
    Log.d(TAG, "Trying to connect...");
}

BluetoothLeService重要部分:

public class BluetoothLeService extends Service {
private final static String TAG = BluetoothLeService.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 =
        "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 UUID UUID_HEART_RATE_MEASUREMENT =
        UUID.fromString(SampleGattAttributes.HEART_RATE_MEASUREMENT);


// Implements callback methods for GATT events that the app cares about.  For example,
// connection change and services discovered.
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;
            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);
        }
    }

    @Override
    public void onServicesDiscovered(BluetoothGatt gatt, int status) {
        if (status == BluetoothGatt.GATT_SUCCESS) {
            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);
        }
    }

    @Override
    public void onCharacteristicChanged(BluetoothGatt gatt,
                                        BluetoothGattCharacteristic characteristic) {
        broadcastUpdate(ACTION_DATA_AVAILABLE, characteristic);
    }
};
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;
}

该错误发生在BluetoothLeService方法initialize()内部

请帮助。

编辑:

我做了CommonWire的建议,返回的是我以前遇到的错误。 那是因为bindService(...)方法不起作用,所以未初始化mServiceConnection。通过将以下行添加到清单文件中,可以更正该问题:

<application>
....
<service android:name=".BluetoothLeService" android:enabled="true"/>
</application>

2 个答案:

答案 0 :(得分:0)

删除:

private BluetoothLeService mBluetoothLeService = new BluetoothLeService();

您不会自己创建服务实例。 Android在startService()bindService()处理过程中创建它们。

BluetoothLeService用其onCreate()方法处理其蓝牙初始化。

答案 1 :(得分:0)

您尝试调用getContext()。getSystemService()吗?