我的 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 此时尚未初始化。所以它是空的。
我有问题,当我 运行 我的应用程序在虚拟设备上一切正常时,但是当我 运行 它在我的物理设备上 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 此时尚未初始化。所以它是空的。