I've made a screen in android studio that manages some aspects of bluetooth like searching for devices, on and off and so on. The problem appeared when I ran the app, I get a NullPointer error when changing the bluetooth images from on to off and viceversa.
My code so far (simplified):
private ListView listView;
private ArrayList<String> mDeviceList = new ArrayList<>();
Button mBotOn, mBotOff,mBotDescubrir, mBotEmparejar, mBotEmp;
private BluetoothAdapter mBlueAdapter;
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.ajustes_conexion_sensores);
listView = findViewById(R.id.listView);
mBlueAdapter = BluetoothAdapter.getDefaultAdapter();
final IntentFilter filter = new IntentFilter(BluetoothDevice.ACTION_FOUND);
if (mBlueAdapter == null) {
mEstadoBlueTv.setText("Bluetooth no disponible.");
} else {
mEstadoBlueTv.setText("Bluetooth está disponible.");
}
mBotDescubrir.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
registerReceiver(mReceiver, filter);
mBlueAdapter.startDiscovery();
}
});
}
private final BroadcastReceiver mReceiver = 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);
mDeviceList.add(device.getName() + "\n" + device.getAddress());
listView.setAdapter(new ArrayAdapter<String>(context,
android.R.layout.simple_list_item_1, mDeviceList));
}
}
};
I get the NullPointer Exception here:
if (mBlueAdapter.isEnabled()) {
mBluetIv.setImageResource(R.drawable.bt_on);
} else {
mBluetIv.setImageResource(R.drawable.bt_off);
}
The error:
Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'boolean
android.bluetooth.BluetoothAdapter.isEnabled()' on a null object reference
at serenaApp.serenaapp.AjustesConexionSensores.onCreate(AjustesConexionSensores.java:62)
Thank your in advance
if(mBlueAdapter!=null && mBlueAdapter.isEnabled() !=null && mBluetIv!=null){
if (mBlueAdapter.isEnabled()) {
mBluetIv.setImageResource(R.drawable.bt_on);
} else {
mBluetIv.setImageResource(R.drawable.bt_off);
}
}
Related
I am developing a bluetooth chat following a Youtube tutorial, saveral days ago the function of search bluetooth devices availables around me, worked but suddenly to the next day, it did not nothing.
I tried search information and videos, maybe i changed something but nothing, after this for last chance i tried my app in a friend´s mobile phone, and it worked well. So i do not know how can I proceed or how can i fix this.
I am using a Honor 9X (STK-LX1) with Android 10 and EMUI 10.0.0, the API is 30.
Now I test the app in another friend´s mobile, and it worked.
public class DeviceListActivity extends AppCompatActivity {
private Context context;
private ListView listPairedDevices, listAvailableDevices;
private ArrayAdapter<String> adapterPairedDevices, adapterAvailableDevices;
private BluetoothAdapter bluetoothAdapter;
private ProgressBar progressScanDevices;
private Set<BluetoothDevice> foundDevices = new HashSet<>();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_device_list);
context = this;
init();
}
private void init(){
listPairedDevices = findViewById(R.id.list_paired_devices);
listAvailableDevices = findViewById(R.id.list_available_devices);
progressScanDevices = findViewById(R.id.progress_scan_devices);
adapterPairedDevices = new ArrayAdapter<String>(context,R.layout.device_list_item);
adapterAvailableDevices = new ArrayAdapter<String>(context, R.layout.device_list_item);
listPairedDevices.setAdapter(adapterPairedDevices);
listAvailableDevices.setAdapter(adapterAvailableDevices);
listAvailableDevices.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
String info = ((TextView)view).getText().toString();
String mac = info.substring(info.length()-17);
Intent intent = new Intent();
intent.putExtra("deviceAddress",mac);
setResult(RESULT_OK,intent);
finish();
}
});
listPairedDevices.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
String info = ((TextView)view).getText().toString();
String address = info.substring(info.length()-17);
Intent intent = new Intent();
intent.putExtra("deviceAddress",address);
setResult(RESULT_OK,intent);
finish();
}
});
bluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
Set<BluetoothDevice> pairedDevices = bluetoothAdapter.getBondedDevices();
if(pairedDevices != null && pairedDevices.size()>0){
for( BluetoothDevice device: pairedDevices){
adapterPairedDevices.add(device.getName() + "\n"+ device.getAddress());
}
}
IntentFilter intentFilter = new IntentFilter(BluetoothDevice.ACTION_FOUND);
registerReceiver(bluetoothDeviceListener,intentFilter);
IntentFilter intentFilter1 = new IntentFilter(BluetoothAdapter.ACTION_DISCOVERY_FINISHED);
registerReceiver(bluetoothDeviceListener,intentFilter1);
IntentFilter intentFilter2 = new IntentFilter(BluetoothAdapter.ACTION_DISCOVERY_STARTED);
registerReceiver(bluetoothDeviceListener,intentFilter2);
}
private BroadcastReceiver bluetoothDeviceListener = 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);
if (device.getBondState() != BluetoothDevice.BOND_BONDED) {
String deviceName = device.getName();
if(deviceName!=null){
if(foundDevices.contains(device))
return;
foundDevices.add(device);
adapterAvailableDevices.add(device.getName() + "\n" + device.getAddress());
}
}
}else if(BluetoothAdapter.ACTION_DISCOVERY_FINISHED.equals(action)){
progressScanDevices.setVisibility(View.GONE);
if(adapterAvailableDevices.getCount() == 0){
Toast.makeText(context, "No new devices found",Toast.LENGTH_SHORT).show();
}else{
Toast.makeText(context, "Click on the device to start the chat",Toast.LENGTH_SHORT).show();
}
}else if(BluetoothAdapter.ACTION_DISCOVERY_STARTED.equals(action)){
}
}
};
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.menu_device_list, menu);
return super.onCreateOptionsMenu(menu);
}
#Override
public boolean onOptionsItemSelected(#NonNull MenuItem item) {
switch (item.getItemId()){
case R.id.menu_scan_devices:
scanDevices();
return true;
default:
return super.onOptionsItemSelected(item);
}
}
private void scanDevices(){
progressScanDevices.setVisibility(View.VISIBLE);
adapterAvailableDevices.clear();
//Toast.makeText(context, "Scan Devices",Toast.LENGTH_SHORT).show();
if(bluetoothAdapter.isDiscovering()){
bluetoothAdapter.cancelDiscovery();
}
bluetoothAdapter.startDiscovery();
}
}
Edit 1: I put Log.e("Tag 1", "Start search") at the end of the function scanDevices and another Log.e("Tag2","BroadcastReceiver") inside the onReceive function of BroadcastReceiver
When i use the Honor 9x, only appears the first Log.e, but when i use the anothers mobile phones, it appears the first and second.
Edit 2: I have the uses permission on my manifest, BLUETOOTH_ADMIN, BLUETOOTH, ACCESS_FINE_LOCATION.
I would appreciate any help.
I am developing an app which scans the bluetooth devices and list them all. My requirement is that I have to scan for devices as soon as application starts..Now my problem is when i run the app for the first time it only turns on the bluetooth but does not scan for devices..
I can see the bluetooth icon on screen but in log cat getState() method of the BluetoothAdapter shows state as STATE_OFF.
Please anyone help me about this issue ??
Here is my code snippet
public class MainActivity extends Activity {
private BluetoothAdapter bluetoothAdapter;
Set<String> BTList;
ArrayAdapter<String> BTAdapter;
private ListView listView;
private BroadcastReceiver mReceiver;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main_activity);
listView = (ListView) findViewById(R.id.listView1);
bluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
if (bluetoothAdapter == null)
Toast.makeText(this, "Devices does not support Bluetooth",
Toast.LENGTH_SHORT).show();
if (!bluetoothAdapter.isEnabled())
bluetoothAdapter.enable();
if(bluetoothAdapter.isEnabled()) {
if(bluetoothAdapter.isDiscovering()) {
bluetoothAdapter.cancelDiscovery();
}
}
bluetoothAdapter.startDiscovery();
mReceiver = 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);
BTAdapter.add(device.getName() + "\n" + device.getAddress());
BTAdapter.notifyDataSetChanged();
}
}
};
IntentFilter filter = new IntentFilter(BluetoothDevice.ACTION_FOUND);
registerReceiver(mReceiver, filter);
BTAdapter = new ArrayAdapter<String>(this,
android.R.layout.simple_expandable_list_item_1);
listView.setAdapter(BTAdapter);
}
#Override
protected void onDestroy() {
super.onDestroy();
//if(bluetoothAdapter != null)
// bluetoothAdapter.cancelDiscovery();
unregisterReceiver(mReceiver);
}
}
Check in your AndroidManifest.xml file, if you have these below entries
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
<uses-permission android:name="android.permission.BLUETOOTH" />
i am listing all paired devices,and it well work but now want to get Bluetooth signal strength of paired devices...i know it will get by use rssi but cannot implement get it continuously in my app..
plz me by giving suitable code as my code...my code is here...
public class Security extends Fragment implements OnClickListener{
private BluetoothAdapter BA;
private Set<BluetoothDevice>pairedDevices;
ArrayList<String> mylist = new ArrayList<String>();
//private Object ImageView;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.security, null);
BA = BluetoothAdapter.getDefaultAdapter();
/* starting the bluetooth*/
on(v);
pairedDevices = BA.getBondedDevices();
//length=4;
// int j=1;
for(BluetoothDevice bt : pairedDevices) {
mylist.add(bt.getName());
length=j;
j++;
bt.getBondState();
}
return v;
}
#Override
public void onResume() {
super.onResume();
// Toast.makeText(getActivity(), "On resume", Toast.LENGTH_LONG).show();
}
/*************************Bluetooth function****************************/
public void on(View view){
if (!BA.isEnabled()) {
Intent turnOn = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
startActivityForResult(turnOn, 0);
Toast.makeText(getActivity(),"Turned on"
,Toast.LENGTH_LONG).show();
} else{
// Toast.makeText(getActivity(),"Already on",
// Toast.LENGTH_LONG).show();
}
}
public void Discovery(View view) {
if(BA.isDiscovering()) {
BA.cancelDiscovery();
}
}
public void list(View view){
Toast.makeText(getActivity(),"Showing Paired Devices",
Toast.LENGTH_SHORT).show();
}
#Override
public void onClick(View v) {
for(int j=0;j<length;j++) {
if(v.getId()==j)
Toast.makeText(getActivity(), mylist.get(j), Toast.LENGTH_LONG).show();
//hand.update(run,1000);
}
}
}
You can get the signal from following code.
Code your activity
#Override
public void onCreate(Bundle savedInstanceState) {
.....
// Registering Broadcast. this will fire when Bluetoothdevice Found
registerReceiver(receiver, new IntentFilter(BluetoothDevice.ACTION_ACL_CONNECTED));
}
private final BroadcastReceiver BroadcastReceiver = new BroadcastReceiver(){
#Override
public void onReceive(Context context, Intent intent) {
String mIntentAction = intent.getAction();
if(BluetoothDevice.ACTION_ACL_CONNECTED.equals(mIntentAction)) {
short rssi = intent.getShortExtra(BluetoothDevice.EXTRA_RSSI,Short.MIN_VALUE);
String mDeviceName = intent.getStringExtra(BluetoothDevice.EXTRA_NAME);
}
}
};
This broadcast will execute when your device will be connected to the remote device.
There are several other action on which you can fire this broadcast. have a look at here(BluetoothDevice)
Check following link for constant reading of RSSI
Tutorial to continuously measure the Bluetooth RSSI of a connected Android device (Java)
Output of link :
Then if you want to do it in continuously, you need to run it in a service or in a thread. So that you can even add time slots or sleep (waits) measuring the RSSI.
I have a PreferenceFragment with the following preference xml resource:
<?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"
android:title="#string/Preferences">
<PreferenceCategory
android:title="#string/Bluetooth">
<CheckBoxPreference
android:key="pref_bt_enabled"
android:title="#string/Bt_checkbox"
android:summary="#string/Bt_checkbox_summary"
android:defaultValue="false" />
<ListPreference
android:key="pref_bt_devices"
android:summary="#string/Bt_devices_summary"
android:title="#string/Bt_devices"
android:enabled="false" />
</PreferenceCategory>
</PreferenceScreen>
What I'm trying to do is this:
When I enable the pref_bt_enabled, I turn on Bluetooth, look for paired devices and also discover other devices and add them all to the ListPreference. This is the code I use so far:
public class SettingsFragment extends PreferenceFragment implements OnSharedPreferenceChangeListener {
private static final int REQUEST_ENABLE_BT = 100;
BluetoothAdapter btAdapter;
Set<BluetoothDevice> pairedDevices;
Set<BluetoothDevice> discoveredDevices;
ListPreference btDevicesList;
ArrayList<CharSequence> entries;
ArrayList<CharSequence> entryValues;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Load the preferences from an XML resource
addPreferencesFromResource(R.xml.preferences);
btDevicesList = (ListPreference) findPreference("pref_bt_devices");
btAdapter = getBtAdapter();
if (btAdapter != null) {
findPreference("pref_bt_enabled").setEnabled(true);
}
IntentFilter filter = new IntentFilter(BluetoothDevice.ACTION_FOUND);
getActivity().registerReceiver(btDiscoveryReceiver, filter);
}
#Override
public void onResume() {
super.onResume();
// Set up a listener whenever a key changes
getPreferenceScreen().getSharedPreferences().registerOnSharedPreferenceChangeListener(this);
}
#Override
public void onPause() {
super.onPause();
// Set up a listener whenever a key changes
getPreferenceScreen().getSharedPreferences().unregisterOnSharedPreferenceChangeListener(this);
}
#Override
public void onDestroy() {
super.onPause();
getActivity().unregisterReceiver(btDiscoveryReceiver);
}
public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
if (key.equals("pref_bt_enabled")) {
if (sharedPreferences.getBoolean(key, false) == true) {
enableBluetooth();
findPairedDevices();
discoverDevices();
btDevicesList.setEnabled(true);
}
else {
btAdapter.disable();
btDevicesList.setEnabled(false);
}
}
}
public BluetoothAdapter getBtAdapter() {
BluetoothAdapter mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
if (mBluetoothAdapter == null) {
// Device does not support Bluetooth
return null;
}
else {
return mBluetoothAdapter;
}
}
public void enableBluetooth() {
if (!btAdapter.isEnabled()) {
Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
startActivityForResult(enableBtIntent, REQUEST_ENABLE_BT);
}
}
public void findPairedDevices() {
pairedDevices = btAdapter.getBondedDevices();
entries = new ArrayList<CharSequence>();
entryValues = new ArrayList<CharSequence>();
for (BluetoothDevice d : pairedDevices) {
entries.add("paired: " + d.getName());
entryValues.add(d.getAddress());
}
btDevicesList.setEntries(listToArray(entries));
btDevicesList.setEntryValues(listToArray(entryValues));
}
public void discoverDevices() {
btAdapter.startDiscovery();
}
public CharSequence[] listToArray(ArrayList<CharSequence> list) {
CharSequence[] sequence = new CharSequence[list.size()];
for (int i = 0; i < list.size(); i++) {
sequence[i] = list.get(i);
}
return sequence;
}
private final BroadcastReceiver btDiscoveryReceiver = new BroadcastReceiver() {
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
// When discovery finds a device
if (BluetoothDevice.ACTION_FOUND.equals(action)) {
// Get the BluetoothDevice object from the Intent
BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
discoveredDevices.add(device);
entries.add("discovered: " + device.getName());
btDevicesList.setEntries(listToArray(entries));
entryValues.add(device.getAddress());
btDevicesList.setEntryValues(listToArray(entryValues));
}
}
};
}
When I turn on Bluetooth using my checkbox, Bluetooth turns on, but my ListPreference remains empty even when I have a Bluetooth device nerby and It is discoverable. I get no errors running this code. Thanks for your advice!
You code is actually throwing an exception in btDiscoveryReceiver, discoveredDevices is never initialized.
I have two activities Main nd AvaiableDevices in Main activity i have a button btnAdvc in AvailableDevices
public class MainActivity extends Activity
{
Button btnAdvc;
Button btnPdvc;
Button btnDdvc;
Button btnMdvc;
public BluetoothAdapter mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
public static final int REQUEST_ENABLE_BT = 1;
public static UUID MY_UUID=null;
public BluetoothServerSocket mmServerSocket;
public void onCreate(Bundle savedInstanceState)
{
try{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
MY_UUID= UUID.fromString("00001101-0000-1000-8000-00805F9B34FB");
//Function enbling Bluetooth
enableBluetooth();
///Function to initialize components
init();
//Calling AvailableDevices class's method searchDevice to get AvailableDevices
btnAdvc.setOnClickListener(new View.OnClickListener() {
public void onClick(View v)
{
call();
}
});
}catch(Exception e){Toast.makeText(getApplicationContext(), e.toString(), Toast.LENGTH_LONG).show();}
}
public void init()
{
btnAdvc=(Button)findViewById(R.id.btnAdvc);
btnPdvc=(Button)findViewById(R.id.btnPdvc);
btnDdvc=(Button)findViewById(R.id.btnDdvc);
btnMdvc=(Button)findViewById(R.id.btnMdvc);
}
public void call()
{
Intent intent=new Intent(this,AvailableDevices.class);
startActivity(intent);
}
}
I have a method searchDevices() in AvailableDevices activity
public class AvailableDevices extends Activity
{
public BluetoothAdapter mBluetoothAdapter;
public BluetoothDevice device;
public ListView lv;//for Available Devices
public ArrayList<String> s=new ArrayList<String>();
public HashSet<String> hs = new HashSet<String>();
public ArrayAdapter<String> adapter;
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_available_devices);
adapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, s);
lv=(ListView)findViewById(R.id.listView1);
Intent intent=getIntent();
}
public AvailableDevices(BluetoothAdapter bt)
{
mBluetoothAdapter =bt;
}
public void searchDevice()
{
if(mBluetoothAdapter.isEnabled())
{
mBluetoothAdapter.startDiscovery();
// Create a BroadcastReceiver for ACTION_FOUND
final BroadcastReceiver mReceiver = new BroadcastReceiver()
{
public void onReceive(Context context, Intent intent)
{
String action = intent.getAction();
// When discovery finds a device
if (BluetoothDevice.ACTION_FOUND.equals(action))
{
try{
// Get the BluetoothDevice object from the Intent
device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
// Add the name and address to an array adapter to show in a ListView
s.add(device.getName()+ "\n" + "#"+ device.getAddress());
//To avoid duplicate devices put it in to hash set which doesn't allow duplicates
hs.addAll(s);
//Clear all the devices in String array S
s.clear();
//Replace with hash set
s.addAll(hs);
//
lv.setAdapter(adapter);
}catch(Exception e){Toast.makeText(getApplicationContext(), e.toString(), Toast.LENGTH_LONG).show();}
}
lv.setOnItemClickListener(new AdapterView.OnItemClickListener()
{
//A local bluetooth device to Hold the selected device to connect
BluetoothDevice devtoconnect;
public void onItemClick(AdapterView<?> parentAdapter, View view, int position, long id)
{
try{
mBluetoothAdapter.cancelDiscovery();
//A local String array to hold the Name and address of the selected bluetooth device
String[] separated = adapter.getItem(position).split("#");
if(mBluetoothAdapter.checkBluetoothAddress(separated[1])==true)
{
devtoconnect = mBluetoothAdapter.getRemoteDevice(separated[1]);
}
// Create object of Connect Thread Class to get connection
// ConnectThread t1=new ConnectThread(devtoconnect);
}catch(Exception e){}
}//Closes onItemClick(AdapterView<?> parentAdapter, View view, int position, long id)
}); //Closes lv.setOnItemClickListener(new AdapterView.OnItemClickListener()
}//Coses function onReceive
};//Closes BroadcastReceiver
// Register the BroadcastReceiver
IntentFilter filter = new IntentFilter(BluetoothDevice.ACTION_FOUND);
registerReceiver(mReceiver, filter); // Don't forget to unregister during onDestroy
}//if
}// function searchDevices
}
when i click in btnAdvc of main the searchDevices() method of AvailableDevices activity should be called how can i do it?
you can use broadcast messages. after the button click send a broadcast. and in the other activity register a BroadcastReceiver which will handle the brodcast. so whenever you have got the desired message then call the method in second activity.
From the code provided, it looks like searchDevices() method is not a kind of independent method and uses variables/properties decalred in AvaiableDevices class. So probably what you can try is some like
Intent intent=new Intent(this,AvailableDevices.class);
intent.putExtra("CallSearchDevices", true);
startActivity(intent);
And in AvailableDevices at the end of the onCreate method,
Intent intent=getIntent();
boolean flag = intent.getBooleanExtra("CallSearchDevices", false);
if (flag){
searchDevices();
}
I hope this helps
You should declare your method static so you can call it like that AvailableDevices.searchDevices() from your other activity