Как исправить NullPointerException из getSystemService (java.lang.String)? - PullRequest
0 голосов
/ 21 января 2019

Я внедряю датчик сердца в существующее приложение, я использую пример подключения 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 называется, DeviceControlActivity использует BluetoothLeSкласс обслуживания.

Важные части 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, и это вернулось к предыдущей моей ошибке.И это было то, что mServiceConnection не был инициализирован, потому что метод bindService (...) не работал.Это было исправлено добавлением следующей строки в файл манифеста:

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

Ответы [ 2 ]

0 голосов
/ 23 января 2019

Вы пытались вызвать getContext (). GetSystemService ()?

0 голосов
/ 21 января 2019

Удалить:

private BluetoothLeService mBluetoothLeService = new BluetoothLeService();

Вы сами не создаете экземпляры сервисов. Android создает их как часть обработки startService() или bindService().

Пусть BluetoothLeService обрабатывает инициализацию Bluetooth в методе onCreate().

...