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
CodePudding user response:
You are assuming that device.getName()
will always return a String
, but sometimes it will return null
. My guess is that you are getting null
from getName()
and are putting that into your ArrayList
, and that is what ArrayAdapter
does not like. Try checking for null
and either skipping that Bluetooth device or substituting some default name.
Also, getApplicationContext()
is rarely the right answer for UI things. Use this
to reference your activity instead.
CodePudding user response:
Flip these two lines
registerReceiver(myReciver,intentFilter);
arrayAdapter = new ArrayAdapter<String>(getApplicationContext(), android.R.layout.simple_list_item_1,devicesList);
When you call registerReceiver, there is the line:
arrayAdapter.notifyDataSetChanged();
But your arrayAdapter hasn't been initialized at that point. So it is null.