Bluetooth Server and BroadCastReceiver - android

My application holds an open bluetooth server socket with a specific UUID, in order for another device to connect and transfer files. I'm a bit confused regarding the BroadcastReceiver.
In my class which extends Activity, I want to check the state of the bluetooth adapter. But my BroadcastReceiver is never triggered. I tried using the BroadcastReceiver this way:
public class MainClass extends Activity {
public void onCreate(Bundle b) {
super.onCreate(b);
IntentFilter filter = new IntentFilter(BluetoothAdapter.ACTION_STATE_CHANGED);
registerReceiver(mReceiver, filter);
}
private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
final String action = intent.getAction();
Log.w("BroadcastReceiver: ", "Inside!");
if (action.equals(BluetoothAdapter.ACTION_STATE_CHANGED)) {
final int state = intent.getIntExtra(BluetoothAdapter.EXTRA_STATE, BluetoothAdapter.ERROR);
switch (state) {
case BluetoothAdapter.STATE_OFF:
Log.d("Bluetooth Receiver", "State-off");
Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
startActivityForResult(enableBtIntent, REQUEST_ENABLE_BT);
break;
case BluetoothAdapter.STATE_TURNING_OFF:
Log.d("Bluetooth Receiver", "State turning off");
break;
case BluetoothAdapter.STATE_ON:
Log.d("Bluetooth Receiver", "State-on");
btCom = new BluetoothCommunicator(MainClass.this, lastCases, nist);
btCom.startServer();
break;
case BluetoothAdapter.STATE_TURNING_ON:
Log.d("Bluetooth Receiver", "State turning on");
break;
}
}
}
};
}
I have a question regarding the states:
The state STATE_ON is this only fired off when the bluetooth is turned on during runtime? Or can I start my application with bluetooth turned on, and this event will be fired off? Cause I want to start the method btCom.startServer() if bluetooth is turned on
I also read that I need to register the broadcast receiver in my Manifest file, how can I do so if the BroadcastReceiver is in a class which extends Activity? If I had this BroadcastReceiver in a separate class I would do it like this
Say for instace that my Package Name was com.workbench and my Class name was BluetoothReceiver
The Manifest would look something like this:
<receiver android:name="com.workbench.BluetoothReceiver"></receiver>

The broadcast action BluetoothAdapter.ACTION_STATE_CHANGED is sent when the state of the bluetooth adapter changes. You will only see this when the state of the adapter is changed.
You can check the current state of the bluetooth adapter by calling BluetoothAdapter.isEnabled().
You only need to register the BroadcastReceiver in your manifest if you want to get the broadcast Intent when your application is not running. The way you have implemented the BroadcastReceiver (as an anonymous class) it isn't possible to register it in the manifest.

Related

Android Enable/ Disable Bluetooth

I have a code, in my app, where a button press turn on bluetooth on and off.
I want to change the background of this button to green and red, when the bluetooth is either on or off. I did google answers for it and there is a stackoverflow post similar to it and the way he mentioned is not working. I registered a receiver and have a switch case as usual, where I mentioned this button color change and it s not working.
Infact the log.d in the receivers are not even being shown up in the terminal of android studio.
THE CODE IS NOT ABOUT HOW TO IMPLETMENT THE COLOR, BUT ACCESSING THE STATE CHANGE OF BLUETOOTH FROM BROADCAST RECEIVER
public void enableDisableBT(){
if(mBluetoothAdapter == null) {
Log.d(TAG, "enableDisableBT: Does not have BT capabilities");
Toast.makeText(getApplicationContext(),"No Bluetooth Capability", Toast.LENGTH_SHORT).show();
}
if (!mBluetoothAdapter.isEnabled()){
Log.d(TAG, "enableDisableBT: enabling BT");
//btnONOFF.setBackgroundColor(Color.GREEN); // Since bluetooth is NOT enabled, it enables bluetotoh and sets background color to green
Intent enableBTIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
startActivity(enableBTIntent);
IntentFilter BTIntent = new IntentFilter(BluetoothAdapter.ACTION_STATE_CHANGED);
registerReceiver(mBroadcastReceiver1, BTIntent);
}
if(mBluetoothAdapter.isEnabled()){
Log.d(TAG, "enableDisableBT: disabling BT");
mBluetoothAdapter.disable();
btnONOFF.setBackgroundColor(Color.RED);// Since bluetooth is enabled, it disables bluetotoh and sets background color to green
incomingMessages.setText("Incoming Messages");
IntentFilter BTIntent = new IntentFilter(BluetoothAdapter.ACTION_STATE_CHANGED);
registerReceiver(mBroadcastReceiver1, BTIntent);
}
}
private final BroadcastReceiver mBroadcastReceiver1 = new BroadcastReceiver() {
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
// when discovery finds a device
if (action.equals(mBluetoothAdapter.ACTION_CONNECTION_STATE_CHANGED)){
final int state = intent.getIntExtra(BluetoothAdapter.EXTRA_STATE,mBluetoothAdapter.ERROR);
switch (state){
case BluetoothAdapter.STATE_OFF:
Log.d(TAG, "onReceive: STATE OFF");
break;
case BluetoothAdapter.STATE_TURNING_OFF:
Log.d(TAG, "mBroadcastReceiver1: STATE TURNING OFF");
break;
case BluetoothAdapter.STATE_ON:
//Log.d(TAG, "mBroadcastReceiver1: STATE ON");
btnONOFF.setBackgroundColor(Color.GREEN);
break;
case BluetoothAdapter.STATE_TURNING_ON:
Log.d(TAG, "mBroadcastReceiver1: STATE TURNING ON");
break;
}
}
}
};
You need to declare a BroadcastReceiver in your manifest to listen to Bluetooth state. This article sums it up well: https://droidhat.com/broadcast-receiver-using-change-in-bluetooth-status
1)
/**
* A receiver that listens to Bluetooth getting turned on.
*/
public class BluetoothReceiver extends BroadcastReceiver {
#Override public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
int state;
switch (action) {
case BluetoothAdapter.ACTION_STATE_CHANGED:
state = intent.getIntExtra(BluetoothAdapter.EXTRA_STATE, -1);
if (state == BluetoothAdapter.STATE_ON) {
// change my button color
}
}
}
}
2)
<receiver
android:name="com.myapp.BluetoothReceiver"
android:enabled="true"
android:exported="true">
<intent-filter>
<action android:name="android.bluetooth.adapter.action.STATE_CHANGED" />
</intent-filter>
</receiver>

Detecting State changes made by Bluetooth adapter through a background service

I have been trying to develop a service that detects BLE devices in the background. The background service runs seemlesly when bluetooth is enabled. However when bluetooth is not running i turn on bluetooth via
bluetoothAdapter.enable();
In order to listen to changes made by the bluetooth adapter i declare a broadcastreceiver in my service in the onCreate() method like this:
IntentFilter filter = new IntentFilter(BluetoothAdapter.ACTION_STATE_CHANGED);
registerReceiver(receiver, filter);
My broadcast receiver looks like this:
private final BroadcastReceiver receiver = new BroadcastReceiver()
{
#Override
public void onReceive(Context context, Intent intent) {
final String action = intent.getAction();
Log.v("Broadcast called", "in service");
if (action.equals(BluetoothAdapter.ACTION_STATE_CHANGED))
{
final int state = intent.getIntExtra(BluetoothAdapter.EXTRA_STATE, BluetoothAdapter.ERROR);
switch (state) {
case BluetoothAdapter.STATE_OFF:
Log.v("Bluetooth state", "Off");
break;
case BluetoothAdapter.STATE_TURNING_OFF:
Log.v("Bluetooth state", "Turning Off");
break;
case BluetoothAdapter.STATE_ON:
Log.v("Bluetooth state", "Turned On");
scanLeDevice(true) ;
break;
case BluetoothAdapter.STATE_TURNING_ON:
Log.v("Bluetooth state", "Turning On");
break;
}
}
}
};
the adapter.enable() call turns bluetooth on successfully however the problem i am facing here is that the onReceive method in the receiver never gets triggered as a result of which i cannot run and scan for BLE devices.
When i do these exact same steps in an activity everything works perfectly.
At first i thought that the onReceive is not triggered because the service is in a background thread. So i also triggered the service via a WakefullBroadcastReceiver but that made no change in behavior.
I would like to understand what i am doing wrong here and some help in solving this.

Battery changed receiver not working

I want to react to the charging state in my app.
I registered the receiver for it in onCreate()
registerReceiver(receiver, new IntentFilter(Intent.ACTION_BATTERY_CHANGED));
the receiver looks like that:
private BroadcastReceiver receiver = new BroadcastReceiver(){
#Override
public void onReceive(Context context, Intent intent) {
plugged= intent.getIntExtra(BatteryManager.EXTRA_PLUGGED,0);
String test = Integer.valueOf(plugged).toString();
Toast.makeText(getApplicationContext(), test,
Toast.LENGTH_LONG).show();
}
};
but even if the device is plugged in the plugged variable is 0. Any idea how to fix that?
You could try to use BatteryManager.EXTRA_STATUS. The BatteryManager.EXTRA_PLUGGED can be used if you want more details about the type of power source I believe.
IntentFilter filter = new IntentFilter(Intent.ACTION_BATTERY_CHANGED);
Intent intentResult = registerReceiver(null, filter);
int state = intentResult.getIntExtra(BatteryManager.EXTRA_STATUS, -1);
switch (state) {
case BatteryManager.BATTERY_STATUS_CHARGING:
case BatteryManager.BATTERY_STATUS_FULL:
//charging
break;
default:
//not charging
}

How to check if a bluetooth device is paired

I'm trying to check if there is a bluetooth device paired when running my app.
In the main activity, I find bluetooth devices and pair to them. In the second activity, I must check if there is a device paired or not.
If a device is conected, it starts automatically sending data, but if there is no conexion, then it simply shows a toast.
I need to do this just when the second activity starts. I found this code, but I don't know how to make it to start when the activity is just created.
public void onCreate() {
//...
IntentFilter filter1 = new IntentFilter(BluetoothDevice.ACTION_ACL_CONNECTED);
IntentFilter filter2 = new IntentFilter(BluetoothDevice.ACTION_ACL_DISCONNECTED);
this.registerReceiver(mReceiver, filter1);
this.registerReceiver(mReceiver, filter2);
}
//The BroadcastReceiver that listens for bluetooth broadcasts
private final BroadcastReceiver BTReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if (BluetoothDevice.ACTION_ACL_CONNECTED.equals(action)) {
//Do something if connected
}
else if (BluetoothDevice.ACTION_ACL_DISCONNECTED.equals(action)) {
//Do something if disconnected
}
}
};
Here is a complete description of the problem, with the correct answer to solve it:
Action to know if there is any bluetooth paired device

BroadcastReceiver as it's own class or instantiate it internally in an activity or service class? which is better?

Which is better? To instantiate a Broadcast receiver inside an Activity or in Service class, or make a class that extends BroadcastReceiver?
Below is an example where I instantiate BroadcastReceiver inside a Service class.
 public BroadcastReceiver receiver = new BroadcastReceiver() {
private String filename;
#Override
public void onReceive(Context context, Intent intent){
String action = intent.getAction();
Bundle extras = intent.getExtras();
filename = extras.getString("AudioPath");
Toast.makeText(AudioService.this, "the audio file name sent: " + filename , Toast.LENGTH_LONG).show();
if(action.equals("com.porno.xxx.AudioPlay")){
selectedAudioPath = audiopath;
String state = intent.getExtras().getString("stringdata");
playSong();
Toast.makeText(AudioService.this, "play audio from service string data "+ state, Toast.LENGTH_LONG).show();
}
else if(action.equals("com.porno.xxx.AudioPause")){
pauseSong();
selectedAudioPath = audiopath;
Toast.makeText(AudioService.this, "pause audio from service", Toast.LENGTH_LONG).show();
}
else if(action.equals("com.porno.xxx.AudioSelector")){
Toast.makeText(AudioService.this, "music selector from service", Toast.LENGTH_LONG).show();
Intent i = new Intent();
audiopath = intent.getStringExtra("filename");
Toast.makeText(AudioService.this, "selelcted audio path: " + audiopath, Toast.LENGTH_LONG).show();
}
else if(action.equals("com.porno.xxx.AudioRelease")){
Toast.makeText(AudioService.this, "My Service Stopped and destoryed", Toast.LENGTH_LONG).show();
player.stop();
if (player != null) player.release();
}
}
};
First you plan what you want to do with broadcast receiver. Then you analyze the best and feasible solutions.
If you want to register and unregister the broadcast receiver inside the activity then your source code is ok.
For example if you want to invoke the broadcast receiver when the application is not executing.(which means come out of application and not force close). Then you should not register and unregister the broadcast receiver in coding.
For that you create/implement a seperate class extends from BroadcastReceiver.
In manifest file you want to add the broadcast receiver.
An answer was submitted and accepted while I was typing, so here's where I was at, glad you found your answer already! :)
Based on your (apparent) use as a media player, I'd recommend implementing the player as a Service (that can continue to run in the background if the user navigates away) or as an Activity (if this functionality isn't desired or appropriate for your app..)
A typical implementation of a BroadcastReceiver is as a stand-alone component of the application, declared in the Manifest, which allows it to receive broadcasts even when the application has been killed; it would be started to receive the broadcast, and then stopped after processing it.
Instead it might be advantageous to create the BroadcastReceiver as an inner class, as you've done. This is great when you're only handling your own actions, as it is easy to start and stop the receiver.
In your Service's onCreate() method you can create the action filter, then it can easily be enabled or disabled based on the state of your application:
/* service */
public static final ACTION_PAUSE = "com.example.action_pause";
#Override
public void onCreate() {
IntentFilter filter = new IntentFilter();
filter.addAction(Intent.ACTION_SCREEN_ON); /* Android action example */
filter.addAction(MyClass.ACTION_PAUSE); /* Custom action example*/
registerReceiver(mIntentReceiver, filter);
}
private BroadcastReceiver mIntentReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
Log.v(TAG, "mIntentReceiver.onReceive() action:"+ intent.getAction() );
handleCommand(intent);
} // end onReceive
}; /* end BroadcastReceiver */

Categories

Resources