我的 android 应用程序在我的虚拟设备上运行,但在我的 android 物理设备上运行不正常

My android app is working on my virtual device, but not on my physical android device

我有问题,当我 运行 我的应用程序在虚拟设备上一切正常时,但是当我 运行 它在我的物理设备上 phone 时,在我按下按钮后应用程序崩溃。有时它会在屏幕上查看设备列表,但只有几秒钟,然后应用程序崩溃。

我发现有类似的问题,但还是不行。 我知道有时 arraylist 可能为空,但我不知道如何修复它。

我的代码:

package com.example.drop_java_test2;

import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.ActivityCompat;

import android.Manifest;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Bundle;
import android.view.View;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.ListView;

import java.util.ArrayList;

public class MainActivity extends AppCompatActivity {

    Button scanBt;
    ListView scanList;
    ArrayList<String> devicesList = new ArrayList<String>();
    ArrayAdapter<String> arrayAdapter;

    BluetoothAdapter btAdapter = BluetoothAdapter.getDefaultAdapter();


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);


        scanBt = (Button) findViewById(R.id.bt);
        scanList = (ListView) findViewById(R.id.list);

        ActivityCompat.requestPermissions(this,new String[]{Manifest.permission.ACCESS_FINE_LOCATION, Manifest.permission.ACCESS_COARSE_LOCATION}, 1001); //Any number
        
        scanBt.setOnClickListener(new View.OnClickListener(){

            @Override
            public void onClick(View v){
                if(devicesList == null){
                    devicesList = new ArrayList<String>();
                }

                System.out.println("Status:"+ btAdapter.startDiscovery());
            }
        });

        IntentFilter intentFilter = new IntentFilter(BluetoothDevice.ACTION_FOUND);
        registerReceiver(myReciver,intentFilter);

        arrayAdapter = new ArrayAdapter<String>(getApplicationContext(), android.R.layout.simple_list_item_1,devicesList);
        scanList.setAdapter(arrayAdapter);


    }

    BroadcastReceiver myReciver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            String action = intent.getAction();
            if(BluetoothDevice.ACTION_FOUND.equals(action)){
                BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
                devicesList.add(device.getName());
                arrayAdapter.notifyDataSetChanged();
                System.out.println("Name:"+ device.getName()+ "\nAddress:"+ device.getAddress());
            }
        }

    };
}

XML:

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <Button
        android:id="@+id/bt"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Scan"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintHorizontal_bias="0.498"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <ListView
        android:id="@+id/list"
        android:layout_width="248dp"
        android:layout_height="417dp"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/bt" />

</androidx.constraintlayout.widget.ConstraintLayout>

日志:

2021-11-06 18:37:51.131 582-582/com.example.drop_java_test2 E/AndroidRuntime: FATAL EXCEPTION: main
    Process: com.example.drop_java_test2, PID: 582
    java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.String java.lang.Object.toString()' on a null object reference
        at android.widget.ArrayAdapter.createViewFromResource(ArrayAdapter.java:454)
        at android.widget.ArrayAdapter.getView(ArrayAdapter.java:416)
        at android.widget.AbsListView.obtainView(AbsListView.java:2424)
        at android.widget.ListView.makeAndAddView(ListView.java:2098)
        at android.widget.ListView.fillDown(ListView.java:813)
        at android.widget.ListView.fillSpecific(ListView.java:1524)
        at android.widget.ListView.originalLayoutChildren(ListView.java:1833)
        at android.widget.ListView.layoutChildren(ListView.java:1662)
        at android.widget.AbsListView.onLayout(AbsListView.java:2218)
        at android.view.View.layout(View.java:23058)
        at android.view.ViewGroup.layout(ViewGroup.java:6479)
        at androidx.constraintlayout.widget.ConstraintLayout.onLayout(ConstraintLayout.java:1873)
        at android.view.View.layout(View.java:23058)
        at android.view.ViewGroup.layout(ViewGroup.java:6479)
        at android.widget.FrameLayout.layoutChildren(FrameLayout.java:332)
        at android.widget.FrameLayout.onLayout(FrameLayout.java:270)
        at android.view.View.layout(View.java:23058)
        at android.view.ViewGroup.layout(ViewGroup.java:6479)
        at androidx.appcompat.widget.ActionBarOverlayLayout.onLayout(ActionBarOverlayLayout.java:536)
        at android.view.View.layout(View.java:23058)
        at android.view.ViewGroup.layout(ViewGroup.java:6479)
        at android.widget.FrameLayout.layoutChildren(FrameLayout.java:332)
        at android.widget.FrameLayout.onLayout(FrameLayout.java:270)
        at android.view.View.layout(View.java:23058)
        at android.view.ViewGroup.layout(ViewGroup.java:6479)
        at android.widget.LinearLayout.setChildFrame(LinearLayout.java:1829)
        at android.widget.LinearLayout.layoutVertical(LinearLayout.java:1673)
        at android.widget.LinearLayout.onLayout(LinearLayout.java:1582)
        at android.view.View.layout(View.java:23058)
        at android.view.ViewGroup.layout(ViewGroup.java:6479)
        at android.widget.FrameLayout.layoutChildren(FrameLayout.java:332)
        at android.widget.FrameLayout.onLayout(FrameLayout.java:270)
        at com.android.internal.policy.DecorView.onLayout(DecorView.java:804)
        at android.view.View.layout(View.java:23058)
        at android.view.ViewGroup.layout(ViewGroup.java:6479)
        at android.view.ViewRootImpl.performLayout(ViewRootImpl.java:3613)
        at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:3073)
        at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:2066)
        at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:8496)
        at android.view.Choreographer$CallbackRecord.run(Choreographer.java:1076)
        at android.view.Choreographer.doCallbacks(Choreographer.java:897)
        at android.view.Choreographer.doFrame(Choreographer.java:826)
        at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:1061)
        at android.os.Handler.handleCallback(Handler.java:938)
        at android.os.Handler.dispatchMessage(Handler.java:99)
        at android.os.Looper.loop(Looper.java:236)
        at android.app.ActivityThread.main(ActivityThread.java:8061)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:656)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:967)
2021-11-06 18:37:51.167 582-582/com.example.drop_java_test2 I/Process: Sending signal. PID: 582 SIG: 9

您假设 device.getName() 将始终 return 一个 String,但有时它会 return null。我的猜测是您从 getName() 得到 null 并将其放入您的 ArrayList,而这正是 ArrayAdapter 不喜欢的。尝试检查 null 并跳过该蓝牙设备或替换一些默认名称。

此外,getApplicationContext() 很少是 UI 事情的正确答案。使用 this 来引用您的 activity。

翻转这两行

registerReceiver(myReciver,intentFilter);

arrayAdapter = new ArrayAdapter<String>(getApplicationContext(), android.R.layout.simple_list_item_1,devicesList);

调用registerReceiver时,有一行:

arrayAdapter.notifyDataSetChanged();

但是您的 arrayAdapter 此时尚未初始化。所以它是空的。