I have problem, when i run my app in virtual device everthing works, but when i run it on my physical phone, after i press button app crash. Sometimes it view list of devices on the screen, but only for a few second, then app crash.
I found there similar problem, but it still dont work.
I know that sometimes probably arraylist is null, but i dont know how to fix it.
My code:
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>
Log:
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
2
Answers
You are assuming that
device.getName()
will always return aString
, but sometimes it will returnnull
. My guess is that you are gettingnull
fromgetName()
and are putting that into yourArrayList
, and that is whatArrayAdapter
does not like. Try checking fornull
and either skipping that Bluetooth device or substituting some default name.Also,
getApplicationContext()
is rarely the right answer for UI things. Usethis
to reference your activity instead.Flip these two lines
When you call registerReceiver, there is the line:
But your arrayAdapter hasn’t been initialized at that point. So it is null.