Skip to content

Commit

Permalink
Register explicit broadcast receivers for location/Bluetooth/NFC stat…
Browse files Browse the repository at this point in the history
…e change listeners, due to removal of support for implicit broadcast receivers in Android 8.0 (API 26). Fixes #279.
  • Loading branch information
dpa99c committed Mar 5, 2018
1 parent 0a03c35 commit c141856
Show file tree
Hide file tree
Showing 9 changed files with 113 additions and 119 deletions.
17 changes: 0 additions & 17 deletions plugin.xml
Original file line number Diff line number Diff line change
Expand Up @@ -285,15 +285,6 @@
</js-module>

<source-file src="src/android/Diagnostic_Location.java" target-dir="src/cordova/plugins" />

<config-file target="AndroidManifest.xml" parent="/manifest/application">
<receiver
android:name="cordova.plugins.Diagnostic_Location$LocationProviderChangedReceiver">
<intent-filter>
<action android:name="android.location.PROVIDERS_CHANGED" />
</intent-filter>
</receiver>
</config-file>
<!--END_MODULE LOCATION-->

<!--BEGIN_MODULE BLUETOOTH-->
Expand Down Expand Up @@ -386,14 +377,6 @@
<merges target="cordova.plugins.diagnostic.nfc" />
</js-module>

<config-file target="AndroidManifest.xml" parent="/manifest/application">
<receiver android:name="cordova.plugins.Diagnostic_NFC$NFCStateChangedReceiver">
<intent-filter>
<action android:name="android.nfc.action.ADAPTER_STATE_CHANGED" />
</intent-filter>
</receiver>
</config-file>

<source-file src="src/android/Diagnostic_NFC.java" target-dir="src/cordova/plugins" />
<!--END_MODULE NFC-->

Expand Down
11 changes: 7 additions & 4 deletions src/android/Diagnostic.java
Original file line number Diff line number Diff line change
Expand Up @@ -162,6 +162,8 @@ public class Diagnostic extends CordovaPlugin{
*/
protected CallbackContext currentContext;

protected Context applicationContext;

/*************
* Public API
************/
Expand All @@ -186,6 +188,8 @@ public void initialize(CordovaInterface cordova, CordovaWebView webView) {
Log.d(TAG, "initialize()");
instance = this;

applicationContext = this.cordova.getActivity().getApplicationContext();

super.initialize(cordova, webView);
}

Expand Down Expand Up @@ -323,11 +327,10 @@ public void requestRuntimePermission(String permission, int requestId) throws Ex
*/
public int getADBMode(){
int mode;
Context context = this.cordova.getActivity().getApplicationContext();
if (Build.VERSION.SDK_INT >= 17){ // Jelly_Bean_MR1 and above
mode = Settings.Global.getInt(context.getContentResolver(), Settings.Global.ADB_ENABLED, 0);
mode = Settings.Global.getInt(applicationContext.getContentResolver(), Settings.Global.ADB_ENABLED, 0);
} else { // Pre-Jelly_Bean_MR1
mode = Settings.Secure.getInt(context.getContentResolver(), Settings.Secure.ADB_ENABLED, 0);
mode = Settings.Secure.getInt(applicationContext.getContentResolver(), Settings.Secure.ADB_ENABLED, 0);
}
return mode;
}
Expand Down Expand Up @@ -663,7 +666,7 @@ protected void doColdRestart() {
String baseError = "Unable to cold restart application: ";
try {
logInfo("Cold restarting application");
Context c = this.cordova.getActivity().getApplicationContext();
Context c = applicationContext;
//check if the context is given
if (c != null) {
//fetch the packagemanager so we can get the default launch activity
Expand Down
57 changes: 21 additions & 36 deletions src/android/Diagnostic_Bluetooth.java
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,8 @@ public class Diagnostic_Bluetooth extends CordovaPlugin{
*/
public static final String TAG = "Diagnostic_Bluetooth";

private String currentBluetoothState = null;


/*************
* Variables *
Expand All @@ -91,8 +93,6 @@ public class Diagnostic_Bluetooth extends CordovaPlugin{

private Diagnostic diagnostic;

protected boolean bluetoothListenerInitialized = false;

/**
* Current Cordova callback context (on this thread)
*/
Expand Down Expand Up @@ -120,6 +120,9 @@ public void initialize(CordovaInterface cordova, CordovaWebView webView) {
instance = this;
diagnostic = Diagnostic.getInstance();

diagnostic.applicationContext.registerReceiver(bluetoothStateChangeReceiver, new IntentFilter(BluetoothAdapter.ACTION_STATE_CHANGED));
currentBluetoothState = getBluetoothState();

super.initialize(cordova, webView);
}

Expand All @@ -128,11 +131,9 @@ public void initialize(CordovaInterface cordova, CordovaWebView webView) {
*/
public void onDestroy() {
try {
if (bluetoothListenerInitialized) {
this.cordova.getActivity().unregisterReceiver(blueoothStateChangeReceiver);
}
diagnostic.applicationContext.unregisterReceiver(bluetoothStateChangeReceiver);
}catch(Exception e){
diagnostic.logWarning("Unable to unregister Bluetooth receiver: " + e.getMessage());
diagnostic.logWarning("Unable to unregister Bluetooth state change receiver: " + e.getMessage());
}
}

Expand Down Expand Up @@ -166,9 +167,6 @@ public boolean execute(String action, JSONArray args, CallbackContext callbackCo
callbackContext.success();
} else if(action.equals("getBluetoothState")) {
callbackContext.success(getBluetoothState());
} else if(action.equals("initializeBluetoothListener")) {
initializeBluetoothListener();
callbackContext.success();
} else {
diagnostic.handleError("Invalid action");
return false;
Expand Down Expand Up @@ -261,43 +259,30 @@ public String getBluetoothState(){
return bluetoothState;
}

protected void initializeBluetoothListener(){
if(!bluetoothListenerInitialized){
this.cordova.getActivity().registerReceiver(blueoothStateChangeReceiver, new IntentFilter(BluetoothAdapter.ACTION_STATE_CHANGED));
bluetoothListenerInitialized = true;
public void notifyBluetoothStateChange(){
try {
String newState = getBluetoothState();
if(!newState.equals(currentBluetoothState)){
diagnostic.logDebug("Bluetooth state changed to: " + newState);
diagnostic.executePluginJavascript("bluetooth._onBluetoothStateChange(\""+newState+"\");");
currentBluetoothState = newState;
}
}catch(Exception e){
diagnostic.logError("Error retrieving current Bluetooth state on Bluetooth state change: "+e.toString());
}
}

/************
* Overrides
***********/

protected final BroadcastReceiver blueoothStateChangeReceiver = new BroadcastReceiver() {
protected final BroadcastReceiver bluetoothStateChangeReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
final String action = intent.getAction();
String bluetoothState;

if (action.equals(BluetoothAdapter.ACTION_STATE_CHANGED)) {
final int state = intent.getIntExtra(BluetoothAdapter.EXTRA_STATE,
BluetoothAdapter.ERROR);
switch (state) {
case BluetoothAdapter.STATE_OFF:
bluetoothState = BLUETOOTH_STATE_POWERED_OFF;
break;
case BluetoothAdapter.STATE_TURNING_OFF:
bluetoothState = BLUETOOTH_STATE_POWERING_OFF;
break;
case BluetoothAdapter.STATE_ON:
bluetoothState = BLUETOOTH_STATE_POWERED_ON;
break;
case BluetoothAdapter.STATE_TURNING_ON:
bluetoothState = BLUETOOTH_STATE_POWERING_ON;
break;
default:
bluetoothState = BLUETOOTH_STATE_UNKNOWN;
}
diagnostic.executePluginJavascript("bluetooth._onBluetoothStateChange(\""+bluetoothState+"\");");
if(instance != null && action.equals(BluetoothAdapter.ACTION_STATE_CHANGED)){
Log.v(TAG, "bluetoothStateChangeReceiver");
instance.notifyBluetoothStateChange();
}
}
};
Expand Down
38 changes: 29 additions & 9 deletions src/android/Diagnostic_Location.java
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ Licensed to the Apache Software Foundation (ASF) under one
import org.json.JSONException;

import android.content.BroadcastReceiver;
import android.content.IntentFilter;
import android.location.LocationManager;
import android.os.Build;
import android.util.Log;
Expand Down Expand Up @@ -102,10 +103,30 @@ public void initialize(CordovaInterface cordova, CordovaWebView webView) {
Log.d(TAG, "initialize()");
instance = this;
diagnostic = Diagnostic.getInstance();

diagnostic.applicationContext.registerReceiver(locationProviderChangedReceiver, new IntentFilter(LocationManager.PROVIDERS_CHANGED_ACTION));
locationManager = (LocationManager) this.cordova.getActivity().getSystemService(Context.LOCATION_SERVICE);

try {
currentLocationMode = getLocationModeName();
}catch(Exception e){
diagnostic.logWarning("Unable to get initial location mode: " + e.getMessage());
}

super.initialize(cordova, webView);
}

/**
* Called on destroying activity
*/
public void onDestroy() {
try {
diagnostic.applicationContext.unregisterReceiver(locationProviderChangedReceiver);
}catch(Exception e){
diagnostic.logWarning("Unable to unregister Location Provider Change receiver: " + e.getMessage());
}
}

/**
* Executes the request and returns PluginResult.
*
Expand Down Expand Up @@ -191,17 +212,16 @@ public String getLocationModeName() throws Exception {
default:
modeName = LOCATION_MODE_UNKNOWN;
}
currentLocationMode = modeName;
return modeName;
}

public void notifyLocationStateChange(){
try {
String currentMode = currentLocationMode;
String newMode = getLocationModeName();
if(!newMode.equals(currentMode)){
diagnostic.logDebug("Location mode change to: " + getLocationModeName());
diagnostic.executePluginJavascript("location._onLocationStateChange(\"" + getLocationModeName() +"\");");
if(!newMode.equals(currentLocationMode)){
diagnostic.logDebug("Location mode change to: " + newMode);
diagnostic.executePluginJavascript("location._onLocationStateChange(\"" + newMode +"\");");
currentLocationMode = newMode;
}
}catch(Exception e){
diagnostic.logError("Error retrieving current location mode on location state change: "+e.toString());
Expand Down Expand Up @@ -255,14 +275,14 @@ private boolean isLocationProviderEnabled(String provider) {
* Overrides
***********/

public static class LocationProviderChangedReceiver extends BroadcastReceiver{

protected final BroadcastReceiver locationProviderChangedReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
if(instance != null){ // if app is running
final String action = intent.getAction();
if(instance != null && action.equals(LocationManager.PROVIDERS_CHANGED_ACTION)){
Log.v(TAG, "onReceiveLocationProviderChange");
instance.notifyLocationStateChange();
}
}
}
};
}
83 changes: 51 additions & 32 deletions src/android/Diagnostic_NFC.java
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ Licensed to the Apache Software Foundation (ASF) under one
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.provider.Settings;
import android.util.Log;

Expand Down Expand Up @@ -110,12 +111,24 @@ public void initialize(CordovaInterface cordova, CordovaWebView webView) {
instance = this;
diagnostic = Diagnostic.getInstance();

nfcManager = (NfcManager) this.cordova.getActivity().getApplicationContext().getSystemService(Context.NFC_SERVICE);
diagnostic.applicationContext.registerReceiver(NFCStateChangedReceiver, new IntentFilter(NfcAdapter.ACTION_ADAPTER_STATE_CHANGED));
nfcManager = (NfcManager) diagnostic.applicationContext.getSystemService(Context.NFC_SERVICE);
currentNFCState = isNFCAvailable() ? NFC_STATE_ON : NFC_STATE_OFF;

super.initialize(cordova, webView);
}

/**
* Called on destroying activity
*/
public void onDestroy() {
try {
diagnostic.applicationContext.unregisterReceiver(NFCStateChangedReceiver);
}catch(Exception e){
diagnostic.logWarning("Unable to unregister NFC state change receiver: " + e.getMessage());
}
}


/**
* Executes the request and returns PluginResult.
Expand Down Expand Up @@ -190,49 +203,55 @@ public boolean isNFCAvailable() {
return result;
}

public void notifyNFCStateChange(String state){
public void notifyNFCStateChange(int stateValue){
String newState = getNFCState(stateValue);
try {
if(state != currentNFCState){
diagnostic.logDebug("NFC state changed to: " + state);
diagnostic.executePluginJavascript("_onNFCStateChange(\"" + state +"\");");
currentNFCState = state;
if(newState != currentNFCState){
diagnostic.logDebug("NFC state changed to: " + newState);
diagnostic.executePluginJavascript("nfc._onNFCStateChange(\"" + newState +"\");");
currentNFCState = newState;
}
}catch(Exception e){
diagnostic.logError("Error retrieving current NFC state on state change: "+e.toString());
}
}

public String getNFCState(int stateValue){

String state;
switch(stateValue){
case NFC_STATE_VALUE_OFF:
state = NFC_STATE_OFF;
break;
case NFC_STATE_VALUE_TURNING_ON:
state = NFC_STATE_TURNING_ON;
break;
case NFC_STATE_VALUE_ON:
state = NFC_STATE_ON;
break;
case NFC_STATE_VALUE_TURNING_OFF:
state = NFC_STATE_TURNING_OFF;
break;
default:
state = NFC_STATE_UNKNOWN;
}
return state;
}

/************
* Overrides
***********/

public static class NFCStateChangedReceiver extends BroadcastReceiver {

protected final BroadcastReceiver NFCStateChangedReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
final int stateValue = intent.getIntExtra(EXTRA_ADAPTER_STATE, -1);
if(instance != null){ // if app is running
String state;
switch(stateValue){
case NFC_STATE_VALUE_OFF:
state = NFC_STATE_OFF;
break;
case NFC_STATE_VALUE_TURNING_ON:
state = NFC_STATE_TURNING_ON;
break;
case NFC_STATE_VALUE_ON:
state = NFC_STATE_ON;
break;
case NFC_STATE_VALUE_TURNING_OFF:
state = NFC_STATE_TURNING_OFF;
break;
default:
state = NFC_STATE_UNKNOWN;
}
Log.v(TAG, "onReceiveNFCStateChange: "+state);
instance.notifyNFCStateChange(state);
final String action = intent.getAction();
if(instance != null && action.equals(NfcAdapter.ACTION_ADAPTER_STATE_CHANGED)){

Log.v(TAG, "onReceiveNFCStateChange");
final int stateValue = intent.getIntExtra(EXTRA_ADAPTER_STATE, -1);
instance.notifyNFCStateChange(stateValue);
}
}

}
}
};
}
Loading

0 comments on commit c141856

Please sign in to comment.