I am very new to android dev. I've watched a few youtube video's and read some documentation. Today is like day 5, so be patient with me. I am trying to build a BluetoothLE app. I stole some code from here, but when I try to run in on my device. I get a "Unfortunately, (app name) has stopped" message. After commenting out different blocks of code I have pinned it down to the declaration of:
private ScanCallback mScanCallback = new ScanCallback() {};
If I include that line, it crashes. If I don't, then it lives. Here is the full Java Class:
package com.tremor.creech.bluetoothExample;
import android.annotation.TargetApi;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothGatt;
import android.bluetooth.le.BluetoothLeScanner;
import android.bluetooth.le.ScanCallback;
import android.bluetooth.le.ScanFilter;
import android.bluetooth.le.ScanSettings;
import android.os.Bundle;
import android.os.Handler;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import java.util.List;
@TargetApi(21)
public class MainActivity extends AppCompatActivity {
private BluetoothAdapter mBluetoothAdapter;
private int REQUEST_ENABLE_BT = 1;
private Handler mHandler;
private static final long SCAN_PERIOD = 10000;
private BluetoothLeScanner mLEScanner;
private ScanSettings settings;
private List<ScanFilter> filters;
private BluetoothGatt mGatt;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
private ScanCallback mScanCallback = new ScanCallback() { }; //If I include this line, then it crashes. If I take it out, then I see my Hello World activity.
}
LogCat errors:
09-15 19:16:17.503 1878-1878/com.roberts.croberts.mantis E/dalvikvm﹕ Could not find class 'com.roberts.croberts.mantis.MainActivity$1', referenced from method com.roberts.croberts.mantis.MainActivity.<init>
09-15 19:16:17.523 1878-1878/com.roberts.croberts.mantis E/AndroidRuntime﹕ FATAL EXCEPTION: main
Process: com.roberts.croberts.mantis, PID: 1878
java.lang.NoClassDefFoundError: com.roberts.croberts.mantis.MainActivity$1
at com.roberts.croberts.mantis.MainActivity.<init>(MainActivity.java:154)
at java.lang.Class.newInstanceImpl(Native Method)
at java.lang.Class.newInstance(Class.java:1208)
at android.app.Instrumentation.newActivity(Instrumentation.java:1061)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2119)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2252)
at android.app.ActivityThread.access$800(ActivityThread.java:139)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1200)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:136)
at android.app.ActivityThread.main(ActivityThread.java:5103)
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:790)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:606)
at dalvik.system.NativeStart.main(Native Method)
09-15 19:16:18.023 461-717/? E/Diag_Lib﹕ Thread state: conn_id=0, state=RX_THREAD_WAIT_READ
09-15 19:16:18.023 461-717/? E/Diag_Lib﹕ Thread state: conn_id=0, state=RX_THREAD_CLIENT_TX
09-15 19:16:18.023 461-717/? E/Diag_Lib﹕ qmi_qmux: TX/RX - RX 30 bytes on conn_id=0
09-15 19:16:18.023 461-717/? E/Diag_Lib﹕ 01 1D 00 80 03 01 04 00 00 51 00 11 00 10 03 00
09-15 19:16:18.023 461-717/? E/Diag_Lib﹕ BA 0E 00 11 08 00 BE 08 00 07 00 00 00 00
09-15 19:16:18.023 461-717/? E/Diag_Lib﹕ qmuxd: TX message on fd=29, to qmux_client_id=2, len=64
09-15 19:16:18.023 461-717/? E/Diag_Lib﹕ Thread state: conn_id=0, state=RX_THREAD_WAIT_POLL
09-15 19:16:18.033 454-454/? E/Parcel﹕ Reading a NULL string not supported here.
09-15 19:16:18.033 454-454/? E/Parcel﹕ Reading a NULL string not supported here.
09-15 19:16:18.033 454-454/? E/Parcel﹕ Reading a NULL string not supported here.
09-15 19:16:18.033 454-454/? E/Parcel﹕ Reading a NULL string not supported here.
Unfortunately, to build a BLE application under android you will have to separate android Jelly Bean MR2(18) + Kitkat(19) and Lollipop (21+).
Because you just start, I will give you an overview of how to check.
First declare these variables for both JellyBean/Kitkat and lollipop.
//For Jelly Bean MR2 and Kitkat
private BluetoothAdapter.LeScanCallback leScanCallback;
//For Lollipop.
private BluetoothLeScanner bluetoothLeScanner;
private ScanCallback scanCallback;
Since they are not initiate, there is no error when you run the app. In order to initiate what the target api is, you can use Build:
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) {
//JellyBean/Kitkat
} else {
//lollipop+
}
Also don't forget to check if a phone really have the Ble feature and is required or not with the uses feature into the manifest:
<uses-feature android:name="android.hardware.bluetooth_le" android:required="true"/>
And check from the PackageManager :
boolean hasBle = getPackageManager().hasSystemFeature(PackageManager.FEATURE_BLUETOOTH_LE);
This check must be performed because some phones (like the galaxy nexus) is available with jelly bean MR2 but doesn't have the BLE feature)
And last advice, be very careful about callback leaks and stop/remove callbacks properly ;)