Skip to content

Commit

Permalink
request location on android 6.0
Browse files Browse the repository at this point in the history
  • Loading branch information
randdusing committed Mar 23, 2016
1 parent 449925a commit 6d878b2
Show file tree
Hide file tree
Showing 8 changed files with 90 additions and 21 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
## 3.3.0 - 2016-03-23
- Added requestLocation function to help enable location on Android 6.0. Location services must be enabled to scan for unpaired devices. [\#238](https://github.com/randdusing/BluetoothLE/issues/238)
- Updated readme with walkthrough example - Thanks [normesta](https://github.com/normesta)

## 3.2.0 - 2016-03-21
- Added writeQ function for faster writes.
- Updated config.xml to support Windows 10 [\#242](https://github.com/randdusing/cordova-plugin-bluetoothle/pull/242) - Thanks [TimBarham](https://github.com/TimBarham)
Expand Down
12 changes: 8 additions & 4 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "cordova-plugin-bluetoothle",
"version": "3.2.0",
"version": "3.3.0",
"description": "Use the Bluetooth Low Energy plugin to connect your Cordova app to new Bluetooth devices like heart rate monitors, thermometers, etc...",
"cordova": {
"id": "cordova-plugin-bluetoothle",
Expand All @@ -26,12 +26,16 @@
],
"engines": [
{
"name": "cordova",
"version": ">=3.0.0"
"name": "cordova-plugman",
"version": ">=5.0.0"
},
{
"name": "cordova-android",
"version": ">=5.0.0"
}
],
"author": "Rand Dusing",
"license": "Apache 2.0",
"license": "MIT",
"bugs": {
"url": "https://github.com/randdusing/cordova-plugin-bluetoothle/issues"
},
Expand Down
4 changes: 2 additions & 2 deletions plugin.xml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<plugin xmlns="http://apache.org/cordova/ns/plugins/1.0" xmlns:android="http://schemas.android.com/apk/res/android" xmlns:m2="http://schemas.microsoft.com/appx/2013/manifest" id="cordova-plugin-bluetoothle" version="3.2.0">
<plugin xmlns="http://apache.org/cordova/ns/plugins/1.0" xmlns:android="http://schemas.android.com/apk/res/android" xmlns:m2="http://schemas.microsoft.com/appx/2013/manifest" id="cordova-plugin-bluetoothle" version="3.3.0">
<engines>
<engine name="cordova-plugman" version=">=5.0.0" />
<engine name="cordova-android" version=">=5.0.0" />
Expand All @@ -8,7 +8,7 @@
<description>Use the Bluetooth Low Energy plugin to connect your Cordova app to new Bluetooth devices like heart rate monitors, thermometers, etc...</description>
<author>Rand Dusing</author>
<keywords>bluetooth,bluetoothle,bluetooth le,cordova</keywords>
<license>Apache 2.0</license>
<license>MIT</license>
<js-module src="www/bluetoothle.js" name="BluetoothLe">
<clobbers target="window.bluetoothle" />
</js-module>
Expand Down
37 changes: 27 additions & 10 deletions readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,7 @@ Neither Android nor iOS support Bluetooth on emulators, so you'll need to test o
* [bluetoothle.disable] (#disable) (Android)
* [bluetoothle.startScan] (#startscan)
* [bluetoothle.stopScan] (#stopscan)
* [bluetoothle.retrieveConnected] (#retrieveconnected) (iOS)
* [bluetoothle.retrieveConnected] (#retrieveconnected)
* [bluetoothle.connect] (#connect)
* [bluetoothle.reconnect] (#reconnect)
* [bluetoothle.disconnect] (#disconnect)
Expand All @@ -130,17 +130,17 @@ Neither Android nor iOS support Bluetooth on emulators, so you'll need to test o
* [bluetoothle.readDescriptor] (#readdescriptor)
* [bluetoothle.writeDescriptor] (#writedescriptor)
* [bluetoothle.rssi] (#rssi)
* [bluetoothle.mtu] (#mtu)
* [bluetoothle.rssi] (#rssi)
* [bluetoothle.requestConnectionPriority] (#requestconnectionpriority)
* [bluetoothle.mtu] (#mtu) (Android 5+)
* [bluetoothle.requestConnectionPriority] (#requestconnectionpriority) (Android 5+)
* [bluetoothle.isInitialized] (#isinitialized)
* [bluetoothle.isEnabled] (#isenabled)
* [bluetoothle.isScanning] (#isscanning)
* [bluetoothle.isConnected] (#isconnected)
* [bluetoothle.isDiscovered] (#isdiscovered)
* [bluetoothle.hasPermission] (#haspermission) (Android)
* [bluetoothle.requestPermission] (#requestpermission) (Android)
* [bluetoothle.isLocationEnabled] (#islocationenabled) (Android)
* [bluetoothle.hasPermission] (#haspermission) (Android 6+)
* [bluetoothle.requestPermission] (#requestpermission) (Android 6+)
* [bluetoothle.isLocationEnabled] (#islocationenabled) (Android 6+)
* [bluetoothle.requestLocation] (#requestlocation) (Android 6+)
* [bluetoothle.encodedStringToBytes] (#encodedstringtobytes)
* [bluetoothle.bytesToEncodedString] (#bytestoencodedstring)
* [bluetoothle.stringToBytes] (#stringtobytes)
Expand Down Expand Up @@ -276,7 +276,7 @@ The successCallback isn't actually used. Listen to initialize callbacks for chan


### startScan ###
Scan for Bluetooth LE devices. Since scanning is expensive, stop as soon as possible. The Cordova app should use a timer to limit the scan interval. Also, Android uses an AND operator for filtering, while iOS uses an OR operator. Android API >= 23 requires ACCESS_COARSE_LOCATION permissions to find unpaired devices. Permissions can be requested by using the hasPermission and requestPermission functions. Android API >= 23 also requires location services to be enabled. Use isLocationEnabled to determine whether location services are enabled. If not, you may want to prompt the user to enabled them.
Scan for Bluetooth LE devices. Since scanning is expensive, stop as soon as possible. The Cordova app should use a timer to limit the scan interval. Also, Android uses an AND operator for filtering, while iOS uses an OR operator. Android API >= 23 requires ACCESS_COARSE_LOCATION permissions to find unpaired devices. Permissions can be requested by using the hasPermission and requestPermission functions. Android API >= 23 also requires location services to be enabled. Use ```isLocationEnabled``` to determine whether location services are enabled. If not enabled, use ```requestLocation``` to prompt the location services settings page.

```javascript
bluetoothle.startScan(startScanSuccess, startScanError, params);
Expand Down Expand Up @@ -1415,7 +1415,7 @@ bluetoothle.requestPermission(requestPermissionSuccess, requestPermissionError);
Determine if location services are enabled or not. Location Services are required to find devices in Android API 23.

```javascript
bluetoothle.isLocationEnabled(isLocationEnabledSuccess);
bluetoothle.isLocationEnabled(isLocationEnabledSuccess, isLocationEnabledError);
```

##### Success #####
Expand All @@ -1428,6 +1428,23 @@ bluetoothle.isLocationEnabled(isLocationEnabledSuccess);
```


### requestLocation ###
Prompt location services settings pages. ```requestLocation``` property returns whether location services are enabled or disabled. Location Services are required to find devices in Android API 23.

```javascript
bluetoothle.requestLocation(requestLocationSuccess, requestLocationError);
```

##### Success #####
* status => requestLocation = true/false

```javascript
{
"requestLocation": true
}
```



### encodedStringToBytes ###
Helper function to convert a base64 encoded string from a characteristic or descriptor value into a uint8Array object.
Expand Down Expand Up @@ -1952,7 +1969,7 @@ function discoverSuccess(result) {

If the call to the [services](#services) function succeeds, we'll get an array of services.

we'll call the [Characteristics](#characteristics) function to get all of the characteristics of the service.
we'll call the [Characteristics](#characteristics) function to get all of the characteristics of the service.

```javascript

Expand Down
42 changes: 37 additions & 5 deletions src/android/BluetoothLePlugin.java
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ public class BluetoothLePlugin extends CordovaPlugin
//Initialization related variables
private final int REQUEST_BT_ENABLE = 59627; /*Random integer*/
private final int REQUEST_ACCESS_COARSE_LOCATION = 59628;
private final int REQUEST_LOCATION_SOURCE_SETTINGS = 59629;
private BluetoothAdapter bluetoothAdapter;
private boolean isReceiverRegistered = false;

Expand All @@ -61,6 +62,7 @@ public class BluetoothLePlugin extends CordovaPlugin
private CallbackContext scanCallbackContext;
private Object scanLock = new Object();
private CallbackContext permissionsCallback;
private CallbackContext locationCallback;

//Store connections and all their callbacks
private HashMap<Object, HashMap<Object,Object>> connections;
Expand Down Expand Up @@ -582,6 +584,15 @@ public void run() {
});
return true;
}
else if ("requestLocation".equals(action))
{
cordova.getThreadPool().execute(new Runnable() {
public void run() {
requestLocationAction(callbackContext);
}
});
return true;
}
return false;
}

Expand All @@ -599,15 +610,15 @@ public void onRequestPermissionResult(int requestCode, String[] permissions, int
permissionsCallback.success(returnObj);
}

public void hasPermissionAction(CallbackContext callbackContext) {
private void hasPermissionAction(CallbackContext callbackContext) {
JSONObject returnObj = new JSONObject();

addProperty(returnObj, "hasPermission", cordova.hasPermission(Manifest.permission.ACCESS_COARSE_LOCATION));

callbackContext.success(returnObj);
}

public void requestPermissionAction(CallbackContext callbackContext) {
private void requestPermissionAction(CallbackContext callbackContext) {
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M){
JSONObject returnObj = new JSONObject();
addProperty(returnObj, keyError, "requestPermission");
Expand All @@ -620,9 +631,15 @@ public void requestPermissionAction(CallbackContext callbackContext) {
cordova.requestPermission(this, REQUEST_ACCESS_COARSE_LOCATION, Manifest.permission.ACCESS_COARSE_LOCATION);
}

public void isLocationEnabledAction(CallbackContext callbackContext) {
private void isLocationEnabledAction(CallbackContext callbackContext) {
JSONObject returnObj = new JSONObject();

addProperty(returnObj, "isLocationEnabled", isLocationEnabled());

callbackContext.success(returnObj);
}

private boolean isLocationEnabled() {
boolean result = true;

//Only applies to Android 6.0, which requires the users to have location services enabled to scan for devices
Expand All @@ -634,9 +651,14 @@ public void isLocationEnabledAction(CallbackContext callbackContext) {
}
}

addProperty(returnObj, "isLocationEnabled", result);
return result;
}

callbackContext.success(returnObj);
private void requestLocationAction(CallbackContext callbackContext) {
locationCallback = callbackContext;

Intent intent = new Intent(android.provider.Settings.ACTION_LOCATION_SOURCE_SETTINGS);
cordova.startActivityForResult(this, intent, REQUEST_LOCATION_SOURCE_SETTINGS);
}

private void initializeAction(JSONArray args, CallbackContext callbackContext)
Expand Down Expand Up @@ -2373,6 +2395,16 @@ public void onActivityResult(int requestCode, int resultCode, Intent intent)
pluginResult.setKeepCallback(true);
initCallbackContext.sendPluginResult(pluginResult);
}
} else if (requestCode == REQUEST_LOCATION_SOURCE_SETTINGS) {
if (locationCallback != null) {
JSONObject returnObj = new JSONObject();

addProperty(returnObj, "requestLocation", isLocationEnabled());

locationCallback.success(returnObj);

locationCallback = null;
}
}
}

Expand Down
1 change: 1 addition & 0 deletions src/ios/BluetoothLePlugin.h
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@
- (void)hasPermission:(CDVInvokedUrlCommand *)command;
- (void)requestPermission:(CDVInvokedUrlCommand *)command;
- (void)isLocationEnabled:(CDVInvokedUrlCommand *)command;
- (void)requestLocation:(CDVInvokedUrlCommand *)command;

@end

Expand Down
8 changes: 8 additions & 0 deletions src/ios/BluetoothLePlugin.m
Original file line number Diff line number Diff line change
Expand Up @@ -1498,6 +1498,14 @@ - (void)isLocationEnabled:(CDVInvokedUrlCommand *)command
[self.commandDelegate sendPluginResult:pluginResult callbackId:command.callbackId];
}

- (void)requestLocation:(CDVInvokedUrlCommand *)command
{
NSDictionary* returnObj = [NSDictionary dictionaryWithObjectsAndKeys: @"requestLocation", keyError, logOperationUnsupported, keyMessage, nil];
CDVPluginResult *pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsDictionary:returnObj];
[pluginResult setKeepCallbackAsBool:false];
[self.commandDelegate sendPluginResult:pluginResult callbackId:command.callbackId];
}

//Central Manager Delegates
- (void) centralManagerDidUpdateState:(CBCentralManager *)central
{
Expand Down
3 changes: 3 additions & 0 deletions www/bluetoothle.js
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,9 @@ var bluetoothle = {
isLocationEnabled: function(successCallback, errorCallback) {
cordova.exec(successCallback, errorCallback, bluetoothleName, "isLocationEnabled", []);
},
requestLocation: function(successCallback, errorCallback) {
cordova.exec(successCallback, errorCallback, bluetoothleName, "requestLocation", []);
},
encodedStringToBytes: function(string) {
var data = atob(string);
var bytes = new Uint8Array(data.length);
Expand Down

0 comments on commit 6d878b2

Please sign in to comment.