-1

I am a beginner android app user. i am trying to make a BLE scanner based on a online example. however my app keep crashing and not working at all. can anyone please help me identify the problem?

I have looked into various online solutions. the example i am following is this:
https://github.com/kaviles/BLE_Tutorials

this is my manifest:
    <?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.ble_scanner">

    <uses-permission android:name="android.permission.BLUETOOTH"/>
    <uses-permission android:name="android.permission.BLUETOOTH_ADMIN"/>
    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
    <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
    <uses-feature android:name="android.hardware.bluetooth_le" android:required="true"/>

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        <activity android:name=".MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

</manifest>

here is my MainActivity:

public class MainActivity extends AppCompatActivity implements View.OnClickListener, AdapterView.OnItemClickListener {

private final static String TAG = MainActivity.class.getSimpleName();

public static final int REQUEST_ENABLE_BT = 1;

private HashMap<String, BTLE_Device> mBTDevicesHashMap;
private ArrayList<BTLE_Device> mBTDevicesArrayList;
private ListAdapter_BTLE_Devices adapter;

private Button btn_Scan;

private BroadcastReceiver_BTState mBTStateUpdateReceiver;
private Scanner_BTLE mBTLeScanner;

private static final int MY_PERMISSIONS_REQUEST_LOCATION = 99;
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    checkLocationPermission();

    if(!getPackageManager().hasSystemFeature(PackageManager.FEATURE_BLUETOOTH_LE)){
        Utils.toast(getApplicationContext(),"BLE not supported");
        finish();
    }


    mBTStateUpdateReceiver = new BroadcastReceiver_BTState(getApplicationContext());
    mBTLeScanner = new Scanner_BTLE(this,7500,-75);

    mBTDevicesHashMap = new HashMap<>();
    mBTDevicesArrayList = new ArrayList<>();

    adapter = new ListAdapter_BTLE_Devices(this, R.layout.btle_device_list_item, mBTDevicesArrayList);

    ListView listView = new ListView(this);
    listView.setAdapter(adapter);
    listView.setOnItemClickListener(this);

    btn_Scan = (Button) findViewById(R.id.btn_scan);
    ((ScrollView) findViewById(R.id.scrollView)).addView(listView);
    findViewById(R.id.btn_scan).setOnClickListener(this);
}
@Override
protected void onStart(){
    super.onStart();

    registerReceiver(mBTStateUpdateReceiver, new IntentFilter(BluetoothAdapter.ACTION_STATE_CHANGED));
}

@Override
protected void onResume(){
    super.onResume();
}

@Override
protected void onPause(){
    super.onPause();
    stopScan();
}

protected void onStop(){
    super.onStop();
    unregisterReceiver(mBTStateUpdateReceiver);
    startScan();
}

@Override
protected void onDestroy(){
    super.onDestroy();
}

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data){

    if (requestCode == REQUEST_ENABLE_BT){
        if (resultCode == RESULT_OK){
            Utils.toast(getApplicationContext(),"Bluetooth is ready to use");
        }
        else if (resultCode == RESULT_CANCELED){
            Utils.toast(getApplicationContext(),"Please turn on Bluetooth");
        }
    }
}

@Override
public void onClick(View v) {
    switch (v.getId()){
        case R.id.btn_scan:
            Utils.toast(getApplicationContext(),"Scan button pressed");

            if(!mBTLeScanner.isScanning()){
                startScan();
            } else {
                startScan();
            }
            break;
        default:
            break;
    }

}

@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {


}

public void addDevice(BluetoothDevice device, int new_rssi) {

    String address = device.getAddress();
    if(!mBTDevicesHashMap.containsKey(address)){
        BTLE_Device btle_device = new BTLE_Device(device);
        btle_device.setRssi(new_rssi);

        mBTDevicesHashMap.put(address, btle_device);
        mBTDevicesArrayList.add(btle_device);
    } else {
        mBTDevicesHashMap.get(address).setRssi(new_rssi);
    }
    adapter.notifyDataSetChanged();

}

public void startScan(){
    btn_Scan.setText("Scanning...");

    mBTDevicesArrayList.clear();
    mBTDevicesHashMap.clear();

    adapter.notifyDataSetChanged();
    mBTLeScanner.start();
}

public void stopScan() {
    btn_Scan.setText("Scan Again");

    mBTLeScanner.stop();
}

public boolean checkLocationPermission() {
    if (ContextCompat.checkSelfPermission(this,
            Manifest.permission.ACCESS_FINE_LOCATION)
            != PackageManager.PERMISSION_GRANTED) {

        // Should we show an explanation?
        if (ActivityCompat.shouldShowRequestPermissionRationale(this,
                Manifest.permission.ACCESS_FINE_LOCATION)) {

            // Show an explanation to the user *asynchronously* -- don't block
            // this thread waiting for the user's response! After the user
            // sees the explanation, try again to request the permission.
            new AlertDialog.Builder(this)
                    .setPositiveButton(R.string.ok, new DialogInterface.OnClickListener() {
                        @Override
                        public void onClick(DialogInterface dialogInterface, int i) {
                            //Prompt the user once explanation has been shown
                            ActivityCompat.requestPermissions(MainActivity.this,
                                    new String[]{Manifest.permission.ACCESS_FINE_LOCATION},
                                    MY_PERMISSIONS_REQUEST_LOCATION);
                        }
                    })
                    .create()
                    .show();


        } else {
            // No explanation needed, we can request the permission.
            ActivityCompat.requestPermissions(this,
                    new String[]{Manifest.permission.ACCESS_FINE_LOCATION},
                    MY_PERMISSIONS_REQUEST_LOCATION);
        }
        return false;
    } else {
        return true;
    }
}

@Override
public void onRequestPermissionsResult(int requestCode,
                                       String permissions[], int[] grantResults) {
    switch (requestCode) {
        case MY_PERMISSIONS_REQUEST_LOCATION: {
            // If request is cancelled, the result arrays are empty.
            if (grantResults.length > 0
                    && grantResults[0] == PackageManager.PERMISSION_GRANTED) {

                // permission was granted, yay! Do the
                // location-related task you need to do.
                if (ContextCompat.checkSelfPermission(this,
                        Manifest.permission.ACCESS_FINE_LOCATION)
                        == PackageManager.PERMISSION_GRANTED) {
                    onResume();
                }

            } else {

                onDestroy();

            }
            return;
        }

    }
}
}

Here is the logcat:

2019-07-16 14:45:14.758 26071-26071/com.example.ble_scanner I/ple.ble_scanne: Not late-enabling -Xcheck:jni (already on)
2019-07-16 14:45:14.837 26071-26071/com.example.ble_scanner W/ple.ble_scanne: Unexpected CPU variant for X86 using defaults: x86
2019-07-16 14:45:14.935 26071-26079/com.example.ble_scanner E/ple.ble_scanne: Failed to send DDMS packet REAQ to debugger (-1 of 20): Broken pipe
2019-07-16 14:45:15.164 26071-26071/com.example.ble_scanner W/ple.ble_scanne: JIT profile information will not be recorded: profile file does not exits.
2019-07-16 14:45:15.166 26071-26071/com.example.ble_scanner I/chatty: uid=10096(com.example.ble_scanner) identical 10 lines
2019-07-16 14:45:15.166 26071-26071/com.example.ble_scanner W/ple.ble_scanne: JIT profile information will not be recorded: profile file does not exits.
2019-07-16 14:45:15.215 26071-26071/com.example.ble_scanner I/InstantRun: starting instant run server: is main process
2019-07-16 14:45:15.610 26071-26071/com.example.ble_scanner W/ple.ble_scanne: Accessing hidden method Landroid/view/View;->computeFitSystemWindows(Landroid/graphics/Rect;Landroid/graphics/Rect;)Z (light greylist, reflection)
2019-07-16 14:45:15.612 26071-26071/com.example.ble_scanner W/ple.ble_scanne: Accessing hidden method Landroid/view/ViewGroup;->makeOptionalFitsSystemWindows()V (light greylist, reflection)
2019-07-16 14:45:15.824 26071-26071/com.example.ble_scanner E/BluetoothAdapter: Bluetooth binder is null
2019-07-16 14:45:15.831 26071-26071/com.example.ble_scanner D/AndroidRuntime: Shutting down VM
2019-07-16 14:45:15.834 26071-26071/com.example.ble_scanner E/AndroidRuntime: FATAL EXCEPTION: main
    Process: com.example.ble_scanner, PID: 26071
    java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.ble_scanner/com.example.ble_scanner.MainActivity}: java.lang.NullPointerException: Attempt to invoke virtual method 'void android.widget.ScrollView.addView(android.view.View)' on a null object reference
        at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2913)
        at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3048)
        at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:78)
        at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:108)
        at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:68)
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1808)
        at android.os.Handler.dispatchMessage(Handler.java:106)
        at android.os.Looper.loop(Looper.java:193)
        at android.app.ActivityThread.main(ActivityThread.java:6669)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:858)
     Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'void android.widget.ScrollView.addView(android.view.View)' on a null object reference
        at com.example.ble_scanner.MainActivity.onCreate(MainActivity.java:65)
        at android.app.Activity.performCreate(Activity.java:7136)
        at android.app.Activity.performCreate(Activity.java:7127)
        at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1271)
        at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2893)
        at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3048) 
        at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:78) 
        at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:108) 
        at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:68) 
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1808) 
        at android.os.Handler.dispatchMessage(Handler.java:106) 
        at android.os.Looper.loop(Looper.java:193) 
        at android.app.ActivityThread.main(ActivityThread.java:6669) 
        at java.lang.reflect.Method.invoke(Native Method) 
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493) 
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:858) 
Markus Kauppinen
  • 3,025
  • 4
  • 20
  • 30

2 Answers2

0

In your xml layout try to check if the id of ScrollView is "scrollView", if not change it to scrollView the same as how you initialize in this line.

 ((ScrollView) findViewById(R.id.scrollView)).addView(listView); 

or check your xml layout if ScrollView widget exist. It throws the null pointer Exception because it cannot bind the layout, the id maybe misspelled or there is no scrollview widget in your layout.

MJ_
  • 63
  • 1
  • 1
  • 10
0

Thank you everyone for your suggestion. The issue is solved. this code has two issue for which it did not work. 1. ((ScrollView) findViewById(R.id.scrollView)).addView(listView); in this line scrollView is the wrong ID name. it should be the ID of your scrollview which for my case is device_list. it was making the app crash.

  1. second issue is that i didnot call call for the permission function which will not give the list of BLE devices for android 6+ devices.