首页 > 解决方案 > 应用程序不断崩溃

问题描述

我是一个初学者 android 应用程序用户。我正在尝试根据在线示例制作 BLE 扫描仪。但是我的应用程序不断崩溃并且根本无法正常工作。谁能帮我确定问题?

我研究了各种在线解决方案。我下面的例子是这样的:
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>

这是我的主要活动:

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;
        }

    }
}
}

这是日志猫:

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) 

标签: javaandroidbluetooth-lowenergy

解决方案


在您的 xml 布局中尝试检查 ScrollView 的 id 是否为“ scrollView ”,如果没有将其更改为scrollView,则与您在这一行中的初始化方式相同。

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

或者如果存在 ScrollView 小部件,请检查您的 xml 布局。它抛出空指针异常,因为它无法绑定布局,id 可能拼写错误或布局中没有滚动视图小部件。


推荐阅读