responding to wifi availability - android

how exactly should I configure my broadcast receiver to make my app respond to changes in the wifi availability. I do not really care about reacting to it when the app is not running though.
What I am trying to accomplish here is that as the app is running I need to keep the local DB in synch with a copy on the server. If for whatever reason I lost my connection I need to know when it makes sense to try to re connect.

Since you don't care about it when the app is not running I suggest you register your receiver in code, rather then putting it in the manifest...
IntentFilter filter = new IntentFilter( WifiManager.WIFI_STATE_CHANGED_ACTION );
context.registerReceiver( wifiStateRec, filter);
WifiManager wifim = (WifiManager) context.getSystemService( Context.WIFI_SERVICE );
state = wifim.getWifiState(); // get initial state
And then call unregisterReceiver() when you are finished with it.
Your receiver could look like this:
protected BroadcastReceiver wifiStateRec = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
assertTrue( WifiManager.WIFI_STATE_CHANGED_ACTION.equalsIgnoreCase( intent.getAction() ) );
state = intent.getIntExtra(WifiManager.EXTRA_WIFI_STATE,-1);
String msg;
switch(state) {
case WifiManager.WIFI_STATE_DISABLED:
msg = "it is disabled";
break;
case WifiManager.WIFI_STATE_ENABLED:
msg = "it is enabled";
break;
case WifiManager.WIFI_STATE_DISABLING:
msg = "it is switching off";
break;
case WifiManager.WIFI_STATE_ENABLING:
msg="wifi is getting enabled";
break;
default:
msg="not working properly";
break;
}
Log.i(CTAG, "Wifi state = " + msg );
}
};
Some of the code in this function originally came from this question.

Related

Bluetooth enable time

I am using the below code as per requirement from client to internally enable Bluetooth and disable it when exit the application.
if (!bluetoothAdapter.isEnabled()) {
MMLogger.logInfo(MMLogger.LOG_BLUETOOTH, "BluetoothSyncController - Bluetooth was OFF, so Turn it ON");
bluetoothAdapter.enable();
try {
Thread.sleep(WAIT_FOR_SOMETIME_TO_START_BLUETOOTH);
} catch (InterruptedException ignore) {
}
MMLogger.logInfo(MMLogger.LOG_BLUETOOTH, "BluetoothSyncController - Bluetooth turned ON");
}
IS there any standard time for WAIT_FOR_SOMETIME_TO_START_BLUETOOTH ? I mean any documentation ?
You might try this answer. There seem to be some standard bluetooth events and handlers out there.
From that source: There are events that your activity can manage such as
STATE_OFF, STATE_TURNING_ON, STATE_ON, STATE_TURNING_OFF
and you can catch these with a BroadcastReciever. First you want to make sure that you grant permissions for bluetooth inside of your manifest with:
<uses-permission android:name="android.permission.BLUETOOTH" />
Then you can create a custom broadcast receiver that has the following onReceive():
#Override
public void onReceive(Context context, Intent intent) {
final String action = intent.getAction();
if (action.equals(BluetoothAdapter.ACTION_STATE_CHANGED)) {
final int state = intent.getIntExtra(BluetoothAdapter.EXTRA_STATE, BluetoothAdapter.ERROR);
switch(state) {
case BluetoothAdapter.STATE_OFF:
..
break;
case BluetoothAdapter.STATE_TURNING_OFF:
..
break;
case BluetoothAdapter.STATE_ON:
..
break;
case BluetoothAdapter.STATE_TURNING_ON:
..
break;
}
}
}
Then instead of making a thread to wait you can have a receive event trigger the code you want to run. For more info on using a BroadcastReciever, see the link I provided or go straight to the android documentation.

Consistent graceful disconnect from Bluetooth server when receiving BluetoothAdapter.STATE_TURNING_OFF

I am having trouble disconnecting gracefully from a server when the user turns off the bluetooth. Android generates an event when that happens that you are supposed to use to send a final disconnection message to the server; before your app loses access to bluetooth functionality.
I register the event like this:
context.registerReceiver(this, new IntentFilter(BluetoothAdapter.ACTION_STATE_CHANGED));
Then I listen for the specific event:
public void onReceive(Context context, Intent intent) {
final int state =
intent.getIntExtra(BluetoothAdapter.EXTRA_STATE, BluetoothAdapter.ERROR);
switch (state) {
case BluetoothAdapter.STATE_TURNING_OFF:
_bt.stop();
break;
//...
}
}
This works some times but not every time. I tried giving the thread a higher priority to see if it would help with (alternatively) both of these:
Thread.currentThread().setPriority(Thread.MAX_PRIORITY);
android.os.Process.setThreadPriority(android.os.Process.THREAD_PRIORITY_URGENT_DISPLAY);
... but no luck. Any ideas on how to accomplish this consistently are welcome, thanks!
So, what ended up working for me is to use both priority statements and try to send the message as soon as the event is generated. This way, I consistently get a graceful disconnection from the server. This is how my code ended up looking:
public void onReceive(Context context, Intent intent) {
Thread.currentThread().setPriority(Thread.MAX_PRIORITY);
android.os.Process.setThreadPriority(android.os.Process.THREAD_PRIORITY_URGENT_DISPLAY);
final int state =
intent.getIntExtra(BluetoothAdapter.EXTRA_STATE, BluetoothAdapter.ERROR);
switch (state) {
case BluetoothAdapter.STATE_TURNING_OFF:
// send disconnection message
_bt.stop();
break;
//...
}
}
Hope it helps someone else.

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.

What is the best way to execute a background process after some specific action?

I'm writing an android app that connects to a specific WIFI network. The tricky part is that, when the user connects manually to other network, or turns off the WIFI, or the connections lost (because the user walks away)... I need to forget this network (removeNetwork).
My question is the following: How can I do to achieve this?
Do I need to create a service that runs in the background and every 5 minutes check what is the status of the WIFI?
Is there any "hook" method to run a class, method, function when the WIFI change of some specific status?
What is the best way to achieve this problem?
Really thanks!
I would advise you to implement a broadcast receiver in your application that can activate whenever there are any changes in terms of network or wifi connectivity and in the onRecieve() method of that broadcast receiver you can do any sort of processing whenever the connection is lost.
this goes in your manifest
<receiver android:name=".WifiReceiver" >
<intent-filter>
<action android:name="android.net.wifi.WIFI_STATE_CHANGED" />
</intent-filter>
</receiver>
and this is the java code.
public class WifiReceiver extends BroadcastReceiver {
private final String TAG = "WifiReceiver";
#Override
public void onReceive(Context context, Intent intent) {
int wifiState = intent.getIntExtra(WifiManager.EXTRA_WIFI_STATE, WifiManager.WIFI_STATE_UNKNOWN);
String wifiStateText = "No State";
switch (wifiState) {
case WifiManager.WIFI_STATE_DISABLING:
wifiStateText = "WIFI_STATE_DISABLING";
break;
case WifiManager.WIFI_STATE_DISABLED:
wifiStateText = "WIFI_STATE_DISABLED";
break;
case WifiManager.WIFI_STATE_ENABLING:
wifiStateText = "WIFI_STATE_ENABLING";
break;
case WifiManager.WIFI_STATE_ENABLED:
wifiStateText = "WIFI_STATE_ENABLED";
break;
case WifiManager.WIFI_STATE_UNKNOWN:
wifiStateText = "WIFI_STATE_UNKNOWN";
break;
default:
break;
}
MyLog.d(TAG, "onReceive Broadcast > WiFiState: " + wifiStateText);
MyLog.d(TAG, "onReceive Broadcast > Time: " + new Date());
}
}
and don't forget to add the following permission
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
Please look at the following posts on creating a BroadcastReriever that will be called when network state changes:
Internet listener Android example
Network listener Android

track the incoming call action

I know this is a asked question. By using broadcast receiver and using
android.intent.action.PHONE_STATE
in receiver tag, you can know the actions of a phone. But how can I identify whether it is an incoming call or a outgoing call?
here is my code
#Override
public void onReceive(Context context, Intent intent)
{
this.context = context ;
System.out.println(":::called onReceiver:::");
TelephonyManager telephony = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
telephony.listen(phoneCallListener, PhoneStateListener.LISTEN_CALL_STATE);
}
private final PhoneStateListener phoneCallListener = new PhoneStateListener()
{
#Override
public void onCallStateChanged(int state, String incomingNumber)
{
switch(state)
{
case TelephonyManager.CALL_STATE_RINGING:
isRinging = true;
break;
case TelephonyManager.CALL_STATE_OFFHOOK:
if (isRinging)
{
hasAttended = true ;
isRinging = false;
}
break;
case TelephonyManager.CALL_STATE_IDLE:
if (hasAttended)
{
isCallEnded = true ;
hasAttended = false;
}
break;
}
if(isCallEnded)
{
isCallEnded=false;
Intent callIntent = new Intent(context.getApplicationContext(),MyActivity.class);
callIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(callIntent);
}
super.onCallStateChanged(state, incomingNumber);
}
};
here each time a phoneCallListener object is created and increases the calling rate of onCallStateChanged by one each time..
This is a handy tutorial that uses both broadcast receiver and using android.intent.action.PHONE_STATE that creates different toasts to appear depending on the calls state. When you get this working you will be able to manipulate the code to do what you want when a call is either incoming or outgoing
First your class must extend BroadcastReceiver
Next you have to create a method that will listen to the phones state... PhoneStateListener which will listen to when the Phone state changes
Then do a simple switch case to catch the call depending on if it is an incoming call or an outgoing call
EDIT
All you need to do is write some code to check if the previous state was 'ringing'. If the current state is idle and the previous state was ringing, they cancelled/missed the call. If the current state is offhook and the previous state was ringing, they answered the call.
switch(state){
case TelephonyManager.CALL_STATE_RINGING:
Log.i(LOG_TAG, "RINGING");
wasRinging = true;
break;
case TelephonyManager.CALL_STATE_OFFHOOK:
Log.i(LOG_TAG, "OFFHOOK");
if (!wasRinging) {
// Start your new activity
} else {
// Cancel your old activity
}
// this should be the last piece of code before the break
wasRinging = true;
break;
case TelephonyManager.CALL_STATE_IDLE:
Log.i(LOG_TAG, "IDLE");
// this should be the last piece of code before the break
wasRinging = true;
break;
}

Categories

Resources