I need some help in my Android application. I am trying to create an app that discovers bluetooth devices then compare the name to a string.
but I encountered 2 problems.
1: when I exit the app (back button) it exits then show me a crash message (after few seconds) .. I think the problem is with "mReceiver" (check "2nd problem).
2:(main problem) In the code bellow, the $"mReceiver = new BroadcastReceiver()" part has a problem. I have thrown multiple toasts every where just to check which part doesn't work, everything before this line works fine.
I'm not sure but I think the problem with not having "final" in declaring "mReciver" in the beginning --> "private BroadcastReceiver mReceiver;". However adding final causes problems.
The Code:
public class MainActivity extends Activity {
private final static int REQUEST_ENABLE_BT = 1; //It's really just a number that you provide for onActivityResult (>0)
//Temp objects for testing
private String StringMeeting = "meeting";
ProgressBar bar;
//Member fields
private BluetoothAdapter mBluetoothAdapter;
private ArrayAdapter<String> mPairedDevicesArrayAdapter;
private ArrayAdapter<String> mNewDevicesArrayAdapter;
// Create a BroadcastReceiver for ACTION_FOUND
private BroadcastReceiver mReceiver;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//declare & start progress bar
bar = (ProgressBar) findViewById(R.id.progressBar1);
bar.setVisibility(View.VISIBLE);
//------------Setup a Bluetooth (Get Adapter) ------------------
mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
if (mBluetoothAdapter == null) {
// Device does not support Bluetooth
Toast.makeText(getApplicationContext(), "This Device does not support Bluetooth", Toast.LENGTH_LONG).show();
}else{Toast.makeText(getApplicationContext(), "Getting the Adabter is done", Toast.LENGTH_SHORT).show();}
//------------Setup a Bluetooth (Enable Bluetooth) ------------------
if (!mBluetoothAdapter.isEnabled()) {
Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
startActivityForResult(enableBtIntent, REQUEST_ENABLE_BT);
}else{Toast.makeText(getApplicationContext(), "Enable Bluetooth is done", Toast.LENGTH_SHORT).show();}
//------------Finding Devices (Discovering Devices)----------------------
// Create a BroadcastReceiver for ACTION_FOUND
Toast.makeText(getApplicationContext(), "creating the mReceiver", Toast.LENGTH_SHORT).show(); //last thing works
mReceiver = new BroadcastReceiver() {
public void onReceive(Context context, Intent intent) {
Toast.makeText(getApplicationContext(), "accessed onReceive + will create action", Toast.LENGTH_SHORT).show();
String action = intent.getAction();
Toast.makeText(getApplicationContext(), "Waiting to discover a device", Toast.LENGTH_SHORT).show();
// When discovery finds a device
if (BluetoothDevice.ACTION_FOUND.equals(action)) {
Toast.makeText(getApplicationContext(), "enterd the if", Toast.LENGTH_SHORT).show();
// Get the BluetoothDevice object from the Intent
BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
Toast.makeText(getApplicationContext(), "Getting device names", Toast.LENGTH_SHORT).show();
Toast.makeText(getApplicationContext(), device.getName(), Toast.LENGTH_LONG).show();
Toast.makeText(getApplicationContext(), "displaying the name should be done", Toast.LENGTH_SHORT).show();
// Add the name and address to an array adapter to show in a ListView
mNewDevicesArrayAdapter.add(device.getName() + "\n" + device.getAddress());
}else{Toast.makeText(getApplicationContext(), "Error: BluetoothDevice.ACTION_FOUND.equals(action) = False", Toast.LENGTH_SHORT).show();}
}
};
// Register the BroadcastReceiver
IntentFilter filter = new IntentFilter(BluetoothDevice.ACTION_FOUND);
registerReceiver(mReceiver, filter); // Don't forget to unregister during onDestroy
} //onCreate end
#Override
protected void onDestroy() {
// TODO Auto-generated method stub
super.onDestroy();
// Make sure we're not doing discovery anymore
if (mBluetoothAdapter != null) {
mBluetoothAdapter.cancelDiscovery();
}
// Unregister broadcast listeners
this.unregisterReceiver(mReceiver);
}
}
Thank You For Your Time.
You start an activity for result in order for the user to be prompted whether the user allows Bluetooth to be enabled or not, but you don't wait for the result and try to find devices right away.
You should implement onActivityResult call back. If the result is RESULT_OK, then you start discovering devices. Enabling bluetooth takes some time.
Related
btAdapter.isDiscovering(),btAdapter.startDiscovery(); btAdapter.cancelDiscovery(); device.getName();
4four erros
Call requires permission which may be rejected by user: code should explicitly check to see if permission is available (with checkPermission) or explicitly handle a potential SecurityException
Please solve this problem
public void onClickButtonSearch(View view){
// Check if the device is already discovering
if(btAdapter.*isDiscovering()*){
*btAdapter.cancelDiscovery()*;
} else {
if (btAdapter.isEnabled()) {
*btAdapter.startDiscovery();*
btArrayAdapter.clear();
if (deviceAddressArray != null && !deviceAddressArray.isEmpty()) {
deviceAddressArray.clear();
}
IntentFilter filter = new IntentFilter(BluetoothDevice.ACTION_FOUND);
registerReceiver(receiver, filter);
} else {
Toast.makeText(getApplicationContext(), "bluetooth not on", Toast.LENGTH_SHORT).show();
}
}
}
// Create a BroadcastReceiver for ACTION_FOUND.
private final BroadcastReceiver receiver = new BroadcastReceiver() {
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if (BluetoothDevice.ACTION_FOUND.equals(action)) {
// Discovery has found a device. Get the BluetoothDevice
// object and its info from the Intent.
BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
String deviceName = device.*getName();*
String deviceHardwareAddress = device.getAddress(); // MAC address
btArrayAdapter.add(deviceName);
deviceAddressArray.add(deviceHardwareAddress);
btArrayAdapter.notifyDataSetChanged();
}
}
};
protected void onDestroy() {
super.onDestroy();
// Don't forget to unregister the ACTION_FOUND receiver.
unregisterReceiver(receiver);
}
For apps targeting Android 11 or lower, calling BluetoothAdapter#startDiscovery() requires the Manifest.permission#BLUETOOTH_ADMIN permission which can be gained with a simple manifest tag.
For apps targeting API Level 31 or higher, this requires the Manifest.permission#BLUETOOTH_SCAN permission.
In addition, this requires either the Manifest.permission#ACCESS_FINE_LOCATION permission or a strong assertion that you will never derive the physical location of the device.
A permission can be gained with the following code:
getActivity().requestPermissions(new String[]{ Manifest.permission.ACCESS_FINE_LOCATION},
YOUR_REQUEST_LOCATION_PERMISSION_CODE);
For more infos: https://developer.android.com/reference/android/bluetooth/BluetoothAdapter#startDiscovery()
I'm learning about bluetooth apps and the first sample I've come across, seems to be well documented but I cannot for the life of me get it to reproduce the "Search Devices" part, any help would be greatly appreciated.
public class MainActivity extends AppCompatActivity {
private Button onBtn, offBtn, listBtn, findBtn;
private TextView text;
private ListView myListView;
// Bluetooth global variables
private static final int REQUEST_ENABLE_BT = 1;
private BluetoothAdapter myBluetoothAdapter;
public Set<BluetoothDevice> pairedDevices;
private ArrayAdapter<String> BTArrayAdapter;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
myBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
if(myBluetoothAdapter == null) {
Toast.makeText(getApplicationContext(),"Your device does not support Bluetooth",
Toast.LENGTH_LONG).show();
}
else
{
text = (TextView) findViewById(R.id.text);
onBtn = (Button)findViewById(R.id.turnOn);
offBtn = (Button)findViewById(R.id.turnOff);
listBtn = (Button)findViewById(R.id.paired);
findBtn = (Button)findViewById(R.id.search);
myListView = (ListView)findViewById(R.id.listView1);
// create the arrayAdapter that contains the bluetooth d evices, and set it to the ListView
BTArrayAdapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1);
myListView.setAdapter(BTArrayAdapter);
myListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
String selectedFromList =(String) (myListView.getItemAtPosition(i));
Toast.makeText(getApplicationContext(),"Bluetooth remote device : " + selectedFromList,
Toast.LENGTH_LONG).show();
}
});
}
} // onCreate
public void on(View view){
if (!myBluetoothAdapter.isEnabled()) {
Intent turnOnIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
startActivityForResult(turnOnIntent, REQUEST_ENABLE_BT);
Toast.makeText(getApplicationContext(),"Bluetooth turned on" ,
Toast.LENGTH_LONG).show();
}
else{
Toast.makeText(getApplicationContext(),"Bluetooth is already on",
Toast.LENGTH_LONG).show();
}
}
public void off(View view){
myBluetoothAdapter.disable();
text.setText("Status: Disconnected");
Toast.makeText(getApplicationContext(),"Bluetooth turned off",
Toast.LENGTH_LONG).show();
}
public void list(View view){
// get paired devices
pairedDevices = myBluetoothAdapter.getBondedDevices();
// put it's one to the adapter
for(BluetoothDevice device : pairedDevices)
BTArrayAdapter.add(device.getName()+ "\n" + device.getAddress());
Toast.makeText(getApplicationContext(),"Show Paired Devices",
Toast.LENGTH_SHORT).show();
}
final BroadcastReceiver bReceiver = 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);
// add the name and the MAC address of the object to the arrayAdapter
BTArrayAdapter.add(device.getName() + "\n" + device.getAddress());
BTArrayAdapter.notifyDataSetChanged();
}
}
};
public void find(View view) {
if (myBluetoothAdapter.isDiscovering()) {
// the button is pressed when it discovers, so cancel the discovery
Toast.makeText(getApplicationContext(),"Bluetooth cancelled discovery" ,
Toast.LENGTH_LONG).show();
myBluetoothAdapter.cancelDiscovery();
} else {
BTArrayAdapter.clear();
Toast.makeText(getApplicationContext(),"Bluetooth discovery started" ,
Toast.LENGTH_LONG).show();
myBluetoothAdapter.startDiscovery();
registerReceiver(bReceiver, new IntentFilter(BluetoothDevice.ACTION_FOUND));
}
}
#Override
protected void onDestroy() {
super.onDestroy();
}
}
Using a Oneplus3 & 2 to test this, and neither device can find the other, unless already paired with each other. I want to see if I can search and get the device to populate in a list like the paired devices already do.
If there's anything else you need me to put in let me know, hope you don't mind taking the time to help out with this one!
You need to add one of the following permission to your Manifest.xml to find devices:
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
or
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
If you are working on API 23 and higher you must ensure this permission is granted because it is a dangerous level permission.
Beginning in Android 6.0 (API level 23), users grant permissions to apps while the app is running, not when they install the app
See this guide to request permission(s).
I'm trying to make an android app which has some issues about Bluetooth. I simply enable Bluetooth, find devices, connect one of the devices, send & receive data. First thing is done. But in second, there are some problems. I make a Broadcast Receiver to discover devices nearby my phone. But OnReceive method doesn't get called. The weird thing is, it was getting called at first and I was able to see devices nearby. Then something that I cannot figure out happened and now OnReceive method doesn't get called. I've searched topics about these but none of them could solve my problem. MyDevice and MyAdapter are my own classes to show Bluetooth devices in listview with my own layout. Here is my code:
public class FoundDevicesActivity extends AppCompatActivity {
BluetoothAdapter bluetoothAdapter;
ListView foundedDevicesListView;
MyDeviceAdapter deviceAdapter;
List<MyDevice> foundedDevicesList;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_found_devices);
bluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
foundedDevicesListView = (ListView) findViewById(R.id.foundDevicesListview);
if (bluetoothAdapter.isDiscovering()) {
bluetoothAdapter.cancelDiscovery();
}
IntentFilter filter = new IntentFilter(BluetoothDevice.ACTION_FOUND);
filter.addAction(BluetoothAdapter.ACTION_DISCOVERY_STARTED);
filter.addAction(BluetoothDevice.ACTION_FOUND);
filter.addAction(BluetoothAdapter.ACTION_DISCOVERY_FINISHED);
this.registerReceiver(receiver, filter);
bluetoothAdapter.startDiscovery();
deviceAdapter = new MyDeviceAdapter(this, foundedDevicesList);
foundedDevicesListView.setAdapter(deviceAdapter);
}
private final BroadcastReceiver receiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if (BluetoothAdapter.ACTION_DISCOVERY_STARTED.equals(action)) {
Toast.makeText(FoundDevicesActivity.this, "Discovery is started !!", Toast.LENGTH_SHORT).show();
Log.d("Found Devices Activity", "Discovery is started !!");
} else if (BluetoothDevice.ACTION_FOUND.equals(action)) {
BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
MyDevice dvc = new MyDevice();
if (device.getName().equals(null)) {
dvc.name = "UNDEFINED NAME";
} else {
dvc.name = device.getName();
}
if(device.getAddress().equals(null)) {
dvc.address = "UNDEFINED ADDRESS";
} else {
dvc.address = device.getAddress();
}
foundedDevicesList.add(dvc);
} else if (BluetoothAdapter.ACTION_DISCOVERY_FINISHED.equals(action)) {
bluetoothAdapter.cancelDiscovery();
Toast.makeText(FoundDevicesActivity.this, "Discovery is finished !!", Toast.LENGTH_SHORT).show();
Log.d("Found Devices Activity", "Discovery is finished !!");
}
}
};
}
Any idea ?
I have a very simple activity for discovering other android devices via bluetooth:
public void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
// Get the local Bluetooth adapter
FrameLayout f = new FrameLayout(this);
setContentView(f);
IntentFilter filter = new IntentFilter(BluetoothDevice.ACTION_FOUND);
this.registerReceiver(mReceiver, filter);
// Register for broadcasts when discovery has finished
filter = new IntentFilter(BluetoothAdapter.ACTION_DISCOVERY_FINISHED);
this.registerReceiver(mReceiver, filter);
mBtAdapter = BluetoothAdapter.getDefaultAdapter();
// Get a set of currently paired devices
Set<BluetoothDevice> pairedDevices = mBtAdapter.getBondedDevices();
// Request discover from BluetoothAdapter
Log.i("bluetooth", "about to start device discovery");
mBtAdapter.startDiscovery();
//start receiving stuff
mReceiver = new BluetoothReceiver();
}
The problem is that the BluetoothRecieiver class called at the end of the activity's onCreate() doesn't seem to find and devices, although I have one turned on in the vicinity when I am debugging this:
public class BluetoothReceiver extends BroadcastReceiver {
public ArrayAdapter<String> mNewDevicesArrayAdapter;
#Override
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);
// If it's already paired, skip it, because it's been listed already
if (device.getBondState() != BluetoothDevice.BOND_BONDED) {
Log.i("face", device.getName() + "\n" + device.getAddress());
mNewDevicesArrayAdapter.add(device.getName() + "\n" + device.getAddress());
}
// When discovery is finished, change the Activity title
} else if (BluetoothAdapter.ACTION_DISCOVERY_FINISHED.equals(action)) {
if (mNewDevicesArrayAdapter.getCount() == 0) {
Log.i("face", "found NOTHING!");
mNewDevicesArrayAdapter.add("no devices found");
}
}
}
}
Is there anything I am missing here?
I think it's because when you call registerReceiver() mReceiver is null, move mReceiver = new BluetoothReceiver(); above the first this.registerReceiver(mReceiver, filter);, also you could do something like
filter = new IntentFilter();
filter.addAction(BluetoothDevice.ACTION_FOUND);
filter.addAction(BluetoothAdapter.ACTION_DISCOVERY_FINISHED);
and then call this.registerReceiver(mReceiver, filter); only one time
I need to locate my current location in a building by scanning the strongest available Wifi to launch an activity. I want to locate only 3 places in that building. So if I am currently near any of those locations, I will click a button to scan the strongest available Wifi to launch an activity.
I need to scan available Wifi in a building.
Get the 3 strongest signal.
Then detect whether any of those 3 strongest signal's SSID is the same with the specific SSID that I want to locate.
If my SSID is one of the strongest 3 signals, then the application will launch a xml layout activity,
So far I already have the coding to scan strongest available Wifi. But I don't know how to launch an activity when the strongest specific Wifi SSID detected. I do not need the information about the Wifi, just to launch my activity layout that has my information.
At the moment I'm using the following bit of code to scan the strongest Wifi signal that I got from here:
WiFiDemo.java
public class WiFiDemo extends Activity implements OnClickListener {
private static final String TAG = "WiFiDemo";
WifiManager wifi;
BroadcastReceiver receiver;
TextView textStatus;
Button buttonScan;
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
// Setup UI
textStatus = (TextView) findViewById(R.id.textStatus);
buttonScan = (Button) findViewById(R.id.buttonScan);
buttonScan.setOnClickListener(this);
// Setup WiFi
wifi = (WifiManager) getSystemService(Context.WIFI_SERVICE);
// Get WiFi status
WifiInfo info = wifi.getConnectionInfo();
textStatus.append("\n\nWiFi Status: " + info.toString());
// List available networks
List<WifiConfiguration> configs = wifi.getConfiguredNetworks();
for (WifiConfiguration config : configs) {
textStatus.append("\n\n" + config.toString());
}
// Register Broadcast Receiver
if (receiver == null)
receiver = new WiFiScanReceiver(this);
registerReceiver(receiver, new IntentFilter(
WifiManager.SCAN_RESULTS_AVAILABLE_ACTION));
Log.d(TAG, "onCreate()");
}
#Override
public void onStop() {
unregisterReceiver(receiver);
}
public void onClick(View view) {
Toast.makeText(this, "On Click Clicked. Toast to that!!!",
Toast.LENGTH_LONG).show();
if (view.getId() == R.id.buttonScan) {
Log.d(TAG, "onClick() wifi.startScan()");
wifi.startScan();
}
} }
WiFiScanReceiver.java
public class WiFiScanReceiver extends BroadcastReceiver {
private static final String TAG = "WiFiScanReceiver";
WiFiDemo wifiDemo;
public WiFiScanReceiver(WiFiDemo wifiDemo) {
super();
this.wifiDemo = wifiDemo;
}
#Override
public void onReceive(Context c, Intent intent) {
List<ScanResult> results = wifiDemo.wifi.getScanResults();
ScanResult bestSignal = null;
for (ScanResult result : results) {
if (bestSignal == null
|| WifiManager.compareSignalLevel(bestSignal.level, result.level) < 0)
bestSignal = result;
}
String message = String.format("%s networks found. %s is the strongest.",
results.size(), bestSignal.SSID);
Toast.makeText(wifiDemo, message, Toast.LENGTH_LONG).show();
Log.d(TAG, "onReceive() message: " + message);
}
}
You just need to start your activity from onReceive. Unless I'm not understanding your question, you just need to fire off your activity.
Since you have the context on your receiver's onReceive you just need to startActivity()
Start Activity inside onReceive BroadcastReceiver
#Override
public void onReceive(Context context, Intent intent) {
//start activity
Intent i = new Intent();
i.setClassName("com.test", "com.test.MainActivity");
i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(i);
}
Don't forget to define a proper filter for it in your manifest.
http://developer.android.com/reference/android/content/BroadcastReceiver.html