Skip to content

Commit 8fb4828

Browse files
initial import
1 parent 5d055c2 commit 8fb4828

9 files changed

+421
-1
lines changed

.gitignore

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
.idea

LICENSE

+19
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
The MIT License (MIT)
2+
3+
Permission is hereby granted, free of charge, to any person obtaining a copy
4+
of this software and associated documentation files (the "Software"), to deal
5+
in the Software without restriction, including without limitation the rights
6+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7+
copies of the Software, and to permit persons to whom the Software is
8+
furnished to do so, subject to the following conditions:
9+
10+
The above copyright notice and this permission notice shall be included in all
11+
copies or substantial portions of the Software.
12+
13+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
19+
SOFTWARE.

README.md

+5-1
Original file line numberDiff line numberDiff line change
@@ -1 +1,5 @@
1-
TODO
1+
##{N} Bluetooth plugin
2+
3+
Compatible with LE (Low Energy) / Smart devices
4+
5+
_Work in progress_

bluetooth-common.js

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
var BLE = {};
2+
3+
module.exports = BLE;

bluetooth.android.js

+201
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,201 @@
1+
var application = require("application");
2+
var utils = require("utils/utils");
3+
var BLE = require("./ble-common");
4+
5+
/*
6+
LocalNotifications.addOnMessageReceivedCallback = function (callback) {
7+
return new Promise(function (resolve, reject) {
8+
try {
9+
// note that this is ONLY triggered when the user clicked the notification in the statusbar
10+
com.telerik.localnotifications.LocalNotificationsPlugin.setOnMessageReceivedCallback(
11+
new com.telerik.localnotifications.LocalNotificationsPluginListener({
12+
success: function(notification) {
13+
callback(JSON.parse(notification))
14+
}
15+
})
16+
);
17+
resolve();
18+
} catch (ex) {
19+
console.log("Error in LocalNotifications.addOnMessageReceivedCallback: " + ex);
20+
reject(ex);
21+
}
22+
});
23+
};
24+
25+
LocalNotifications.schedule = function (arg) {
26+
return new Promise(function (resolve, reject) {
27+
try {
28+
var context = application.android.foregroundActivity;
29+
30+
for (var n in arg) {
31+
var options = LocalNotifications.merge(arg[n], LocalNotifications.defaults);
32+
options.icon = application.android.nativeApp.getApplicationInfo().icon;
33+
options.atTime = options.at ? options.at.getTime() : new Date().getTime();
34+
35+
// note that setting options.sound to explicitly to null will not add the default sound
36+
if (options.sound === undefined) {
37+
options.sound = android.media.RingtoneManager.getDefaultUri(android.media.RingtoneManager.TYPE_NOTIFICATION).toString();
38+
}
39+
40+
// TODO best move this to native lib so we can reuse it in the restorereceiver (dupl for now)
41+
var builder = new android.support.v4.app.NotificationCompat.Builder(context)
42+
.setDefaults(0)
43+
.setContentTitle(options.title)
44+
.setContentText(options.body)
45+
.setSmallIcon(options.icon)
46+
.setAutoCancel(true) // removes the notification from the statusbar once tapped
47+
.setSound(options.sound == null ? null : android.net.Uri.parse(options.sound))
48+
.setNumber(options.badge)
49+
.setTicker(options.ticker || options.body);
50+
51+
// add the intent that handles the event when the notification is clicked (which should launch the app)
52+
var reqCode = new java.util.Random().nextInt();
53+
var clickIntent = new android.content.Intent(context, com.telerik.localnotifications.NotificationClickedActivity.class)
54+
.putExtra("pushBundle", JSON.stringify(options))
55+
.setFlags(android.content.Intent.FLAG_ACTIVITY_NO_HISTORY);
56+
57+
var pendingContentIntent = android.app.PendingIntent.getActivity(context, reqCode, clickIntent, android.app.PendingIntent.FLAG_UPDATE_CURRENT);
58+
builder.setContentIntent(pendingContentIntent);
59+
60+
var not = builder.build();
61+
62+
// add the intent which schedules the notification
63+
var notificationIntent = new android.content.Intent(context, com.telerik.localnotifications.NotificationPublisher.class)
64+
.setAction("" + options.id)
65+
.putExtra(com.telerik.localnotifications.NotificationPublisher.NOTIFICATION_ID, options.id)
66+
.putExtra(com.telerik.localnotifications.NotificationPublisher.NOTIFICATION, not);
67+
68+
var pendingIntent = android.app.PendingIntent.getBroadcast(context, 0, notificationIntent, android.app.PendingIntent.FLAG_CANCEL_CURRENT);
69+
70+
// configure when we'll show the event
71+
var alarmManager = utils.ad.getApplicationContext().getSystemService(android.content.Context.ALARM_SERVICE);
72+
alarmManager.set(android.app.AlarmManager.RTC_WAKEUP, options.atTime, pendingIntent);
73+
74+
LocalNotifications._persist(options);
75+
}
76+
77+
resolve();
78+
} catch (ex) {
79+
console.log("Error in LocalNotifications.schedule: " + ex);
80+
reject(ex);
81+
}
82+
});
83+
};
84+
85+
LocalNotifications._persist = function (options) {
86+
var sharedPreferences = LocalNotifications._getSharedPreferences();
87+
var sharedPreferencesEditor = sharedPreferences.edit();
88+
sharedPreferencesEditor.putString("" + options.id, JSON.stringify(options));
89+
sharedPreferencesEditor.apply();
90+
};
91+
92+
LocalNotifications._unpersist = function (id) {
93+
var sharedPreferences = LocalNotifications._getSharedPreferences();
94+
var sharedPreferencesEditor = sharedPreferences.edit();
95+
sharedPreferencesEditor.remove("" + id);
96+
sharedPreferencesEditor.apply();
97+
};
98+
99+
LocalNotifications._cancelById = function (id) {
100+
var context = application.android.foregroundActivity;
101+
102+
var notificationIntent = new android.content.Intent(context, com.telerik.localnotifications.NotificationPublisher.class)
103+
.setAction("" + id);
104+
105+
var pendingIntent = android.app.PendingIntent.getBroadcast(context, 0, notificationIntent, 0);
106+
107+
var alarmManager = utils.ad.getApplicationContext().getSystemService(android.content.Context.ALARM_SERVICE);
108+
alarmManager.cancel(pendingIntent);
109+
110+
var notificationManager = utils.ad.getApplicationContext().getSystemService(android.content.Context.NOTIFICATION_SERVICE);
111+
notificationManager.cancel(id);
112+
113+
LocalNotifications._unpersist(id);
114+
};
115+
116+
LocalNotifications.cancel = function (id) {
117+
return new Promise(function (resolve, reject) {
118+
try {
119+
LocalNotifications._cancelById(id);
120+
resolve(true);
121+
} catch (ex) {
122+
console.log("Error in LocalNotifications.cancel: " + ex);
123+
reject(ex);
124+
}
125+
});
126+
};
127+
128+
LocalNotifications.cancelAll = function () {
129+
return new Promise(function (resolve, reject) {
130+
try {
131+
var sharedPreferences = LocalNotifications._getSharedPreferences();
132+
var keys = sharedPreferences.getAll().keySet();
133+
134+
console.log("-----will cancel " + keys.size() + " notification(s): " + keys);
135+
136+
var iterator = keys.iterator();
137+
while (iterator.hasNext()) {
138+
LocalNotifications._cancelById(iterator.next());
139+
}
140+
141+
resolve();
142+
} catch (ex) {
143+
console.log("Error in LocalNotifications.cancelAll: " + ex);
144+
reject(ex);
145+
}
146+
});
147+
};
148+
149+
LocalNotifications.getScheduledIds = function () {
150+
return new Promise(function (resolve, reject) {
151+
try {
152+
var scheduledIds = [];
153+
154+
var sharedPreferences = LocalNotifications._getSharedPreferences();
155+
var keys = sharedPreferences.getAll().keySet();
156+
157+
var iterator = keys.iterator();
158+
while (iterator.hasNext()) {
159+
scheduledIds.push(iterator.next());
160+
}
161+
162+
resolve(scheduledIds);
163+
} catch (ex) {
164+
console.log("Error in LocalNotifications.getScheduledIds: " + ex);
165+
reject(ex);
166+
}
167+
});
168+
};
169+
170+
LocalNotifications.hasPermission = function (arg) {
171+
return new Promise(function (resolve, reject) {
172+
try {
173+
// nothing to do on this platform
174+
resolve(true);
175+
} catch (ex) {
176+
console.log("Error in LocalNotifications.hasPermission: " + ex);
177+
reject(ex);
178+
}
179+
});
180+
};
181+
182+
LocalNotifications.requestPermission = function (arg) {
183+
return new Promise(function (resolve, reject) {
184+
try {
185+
// nothing to do on this platform
186+
resolve(true);
187+
} catch (ex) {
188+
console.log("Error in LocalNotifications.requestPermission: " + ex);
189+
reject(ex);
190+
}
191+
});
192+
};
193+
194+
LocalNotifications._getSharedPreferences = function () {
195+
var context = application.android.foregroundActivity;
196+
var PREF_KEY = "LocalNotificationsPlugin"; // TODO get constant from native, as the restorereceiver needs it as well
197+
return context.getSharedPreferences(PREF_KEY, android.content.Context.MODE_PRIVATE);
198+
};
199+
*/
200+
201+
module.exports = BLE;

bluetooth.ios.js

+151
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,151 @@
1+
var BLE = require("./ble-common");
2+
3+
var manager,
4+
delegate,
5+
peripherals = [],
6+
onDeviceDiscovered;
7+
8+
var CBCentralManagerDelegateImpl = (function (_super) {
9+
__extends(CBCentralManagerDelegateImpl, _super);
10+
function CBCentralManagerDelegateImpl() {
11+
_super.apply(this, arguments);
12+
}
13+
14+
CBCentralManagerDelegateImpl.new = function () {
15+
return _super.new.call(this);
16+
};
17+
CBCentralManagerDelegateImpl.prototype.initWithCallback = function (callback) {
18+
this._callback = callback;
19+
return this;
20+
};
21+
CBCentralManagerDelegateImpl.prototype.centralManagerDidDiscoverPeripheralAdvertisementDataRSSI = function(central, peripheral, advData, rssi) {
22+
console.log("----- delegate centralManagerDidDiscoverPeripheralAdvertisementDataRSSI");
23+
peripherals.addObject(peripheral);
24+
BLE._findPeripheral(peripheral.identifier.UUIDString);
25+
if (onDeviceDiscovered) {
26+
onDeviceDiscovered({
27+
UUID: peripheral.identifier.UUIDString,
28+
name: peripheral.name,
29+
RSSI: rssi,
30+
state: BLE._getState(peripheral.state)
31+
})
32+
}
33+
};
34+
CBCentralManagerDelegateImpl.prototype.centralManagerDidUpdateState = function(central) {
35+
console.log("----- delegate centralManagerDidUpdateState");
36+
// this._callback(central);
37+
};
38+
CBCentralManagerDelegateImpl.prototype.centralManagerDidConnectPeripheral = function(central, peripheral) {
39+
console.log("----- delegate centralManagerDidConnectPeripheral");
40+
// this._callback(peripheral);
41+
};
42+
CBCentralManagerDelegateImpl.prototype.centralManagerDidConnectPeripheralError = function(central, peripheral, error) {
43+
console.log("----- delegate centralManagerDidConnectPeripheralError");
44+
// this._callback(peripheral);
45+
};
46+
CBCentralManagerDelegateImpl.prototype.centralManagerDidFailToConnectPeripheralError = function(central, peripheral, error) {
47+
console.log("----- delegate centralManagerDidFailToConnectPeripheralError");
48+
// this._callback(error);
49+
};
50+
CBCentralManagerDelegateImpl.ObjCProtocols = [CBCentralManagerDelegate];
51+
return CBCentralManagerDelegateImpl;
52+
})(NSObject);
53+
54+
// check for bluetooth being enabled as soon as the app starts
55+
(function () {
56+
// TODO have the dev pass in a callback when 'scan' is called
57+
delegate = CBCentralManagerDelegateImpl.new().initWithCallback(function (obj) {
58+
console.log("----- delegate obj: " + obj);
59+
});
60+
manager = CBCentralManager.alloc().initWithDelegateQueue(delegate, null);
61+
})();
62+
63+
BLE._isEnabled = function (arg) {
64+
var bluetoothState = manager.state;
65+
return bluetoothState == CBCentralManagerStatePoweredOn;
66+
};
67+
68+
BLE._getState = function(stateId) {
69+
if (stateId == 1) {
70+
return 'connecting';
71+
} else if (stateId == 2) {
72+
return 'connected';
73+
} else if (stateId == 3) {
74+
return 'disconnecting'
75+
} else {
76+
return 'disconnected';
77+
}
78+
};
79+
80+
BLE.isBluetoothEnabled = function (arg) {
81+
return new Promise(function (resolve, reject) {
82+
try {
83+
resolve(BLE._isEnabled());
84+
} catch (ex) {
85+
console.log("Error in BLE.isBluetoothEnabled: " + ex);
86+
reject(ex);
87+
}
88+
});
89+
};
90+
91+
BLE.scan = function (arg) {
92+
return new Promise(function (resolve, reject) {
93+
try {
94+
onDeviceDiscovered = arg.onDeviceDiscovered;
95+
var serviceUUIDs = [];
96+
manager.scanForPeripheralsWithServicesOptions(serviceUUIDs, null);
97+
setTimeout(function() {
98+
manager.stopScan();
99+
resolve();
100+
}, arg.seconds * 1000);
101+
} catch (ex) {
102+
console.log("Error in BLE.scan: " + ex);
103+
reject(ex);
104+
}
105+
});
106+
};
107+
108+
BLE._findPeripheral = function(UUID) {
109+
console.log("---- pppp 0y: " + typeof peripherals);
110+
console.log("---- pppp 00: " + peripherals);
111+
console.log("---- pppp 000: " + peripherals.allObjects);
112+
for (var peripheral in peripherals) {
113+
// console.log("p = " + p);
114+
// }
115+
// for (var i = 0, l = peripherals.count; i < l; i++) {
116+
// var peripheral = peripherals.objectAtIndex(i);
117+
console.log("---- pppp 1: " + peripheral);
118+
console.log("---- pppp 2: " + peripheral.identifier.UUIDString);
119+
if (UUID == peripheral.identifier.UUIDString) {
120+
return peripheral;
121+
}
122+
}
123+
return null;
124+
};
125+
126+
// note that this doesn't make much sense without scanning first
127+
BLE.connect = function (arg) {
128+
return new Promise(function (resolve, reject) {
129+
try {
130+
if (!arg.UUID) {
131+
reject("No UUID was passed");
132+
return;
133+
}
134+
var peripheral = BLE._findPeripheral(arg.UUID);
135+
if (peripheral == null) {
136+
reject("Could not find device with UUID " + arg.UUID);
137+
} else {
138+
console.log("Connecting to device with UUID: " + arg.UUID);
139+
// TODO
140+
//[connectCallbacks setObject:[command.callbackId copy] forKey:[peripheral uuidAsString]];
141+
manager.connectPeripheralOptions(peripheral, null);
142+
// TODO don't resolve here, but wait for callback
143+
}
144+
} catch (ex) {
145+
console.log("Error in BLE.connect: " + ex);
146+
reject(ex);
147+
}
148+
});
149+
};
150+
151+
module.exports = BLE;

0 commit comments

Comments
 (0)