Skip to content

Instantly share code, notes, and snippets.

@jimschubert
Created November 2, 2012 13:56
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jimschubert/4001499 to your computer and use it in GitHub Desktop.
Save jimschubert/4001499 to your computer and use it in GitHub Desktop.
on{x} script: Between 11:00 PM and 7:00 AM, 50% ringer for known contacts and 5% other audio

on{x} script: Between 11:00 PM and 7:00 AM, 50% ringer for known contacts and 5% other audio

on{x} is an application developed by Microsoft for Android phones. It exposes a pretty large amount of the Android API to be scripted using JavaScript. This allows you to script actions like "Disable the wringer when I flip the phone over" or "Display a weather notification at 7:50am" or any number of other things.

This script automates something I think should be a part of Android: disabling/lowering ringer and notification sounds during bedtime while allowing calls from your contacts to be heard. I'd previously used an application called 'Bedside' or something, but I had to remember to enable it at night and disable it in the morning. Other applications either don't provide a whitelist of allowed contact phone numbers.

TODO

When I'm able to query contact groups, I'd like to apply a filter to the contacts loop to allow only calls from my 'Favorites' to be heard.

// Initializing variables
var timeFrom = "11:00 PM";
var timeTo = "7:00 AM";
var bedtimeAudioVolume = 5;
var bedtimeCallVolume = 50;
// End of variables initializing
var save = { ringer: "ringer", volume: "volume", media: "media"};
var storage = device.localStorage;
var started = false;
var oneHour = 60 * 60 * 1000;
var oneDay = 24 * oneHour;
var startTimerName = "jimschubert-11pm-7am-startMonitor";
var stopTimerName = "jimschubert-11pm-7am-stopMonitor";
// console.log('Started Script:' + device.currentSource);
function setOriginal(type, value) {
// Only set the value for this type if it's not already set, values are cleared when script ends.
if(getOriginal(type) == null) {
storage.setItem(type, value);
console.log("setOriginal: " + type + ":" + value);
}
}
function getOriginal(type) {
var value = storage.getItem(type);
console.log("getOriginal: " + type + ":" + value);
return value;
}
function stopMonitoring() {
var mode, ringer, media;
mode = getOriginal(save.ringer);
ringer = parseInt(getOriginal(save.volume),10);
media = parseInt(getOriginal(save.media),10);
device.audio.ringerMode = mode || 'normal';
device.audio.ringerVolume = ringer || 80;
device.media.volume = media || 80;
// set the started flag
started = false;
// remove telephony event
device.telephony.off("incomingCall", bedtimeCallManager);
// remove any possibly duplicated stopMonitoring timers
device.scheduler.removeTimer(stopTimerName)
// clear storage so getOriginal(x) will return nulls
storage.clear();
console.log("Stop monitoring: reset to " + mode + "/" + ringer + "/" + media);
}
function startMonitoring(stop) {
if(started) {
console.debug("startMonitoring() returning early: already started.");
return;
}
started = true;
device.scheduler.setTimer({ name: stopTimerName, time: stop.getTime(), interval: "day" }, stopMonitoring);
// save the original ringer state
setOriginal(save.ringer, device.audio.ringerMode);
setOriginal(save.volume, device.audio.ringerVolume);
setOriginal(save.media, device.media.volume);
console.log("Start monitoring: original values: " +
device.audio.ringerMode + "/" +
device.audio.ringerVolume + "/" +
device.media.volume);
device.audio.ringerMode = 'normal';
device.audio.ringerVolume = bedtimeAudioVolume;
device.media.volume = bedtimeAudioVolume;
device.telephony.on("incomingCall", bedtimeCallManager);
}
function bedtimeCallManager(signal) {
// console.debug("bedtimeCallManager entry point.");
var phoneNumber = signal.phoneNumber;
var contacts = device.contacts.findByPhone(phoneNumber);
contacts = contacts || [];
if(contacts.length === 0) {
console.log("Received a phone call from an unknown number: " + phoneNumber);
} else {
var found = false;
for(var i in contacts) {
if(!found) {
var contact = contacts[i];
device.audio.ringerVolume = bedtimeCallVolume;
console.log("Received a call from " + contact.displayName + ", setting volume to " + bedtimeCallVolume);
found = true;
}
}
}
var answeredListener = function(s) {
console.log("Phone call was answered.");
device.audio.ringerVolume = bedtimeAudioVolume;
// don't handle idle with idleListener
device.telephony.off("idle",idleListener);
};
var idleListener = function(s) {
console.log("Phone call was not answered.");
device.audio.ringerVolume = bedtimeAudioVolume;
device.telephony.off("offHook", answeredListener);
showCallNotification(phoneNumber);
};
device.telephony.once("offHook", answeredListener);
device.telephony.once("idle", idleListener);
console.debug("bedtimeCallManager exit point.");
}
function showCallNotification(phoneNumber) {
try {
var time = new Date().toDateString();
var notification = device.notifications.createNotification('Someone called last night');
var msg = "Call from " + phoneNumber + ", " + time + ".";
console.debug("Showing notification: " + msg);
notification.content = msg;
notification.show();
} catch (e) {
console.error("Error: " + e);
}
}
function createTime(timeString, addDays) {
var today = new Date();
var adjusted = new Date(today.getTime() + ( (addDays||0) * oneDay) );
var time = new Date(adjusted.toDateString() + ' ' + timeString);
console.debug("createTime: " + time);
return time;
}
function init() {
// remove any existing timers with these names
device.scheduler.removeTimer(stopTimerName);
device.scheduler.removeTimer(startTimerName);
// GO TIME!
var stop, start;
var currentHour = (new Date()).getHours();
if(0 <= currentHour && currentHour < 7) {
// We're in the morning hours, stop time is today, start time is yesterday.
stop = createTime(timeTo);
start = createTime(timeFrom, -1);
} else {
// We're alright to assume start time is tonight, stop time is tomorrow morning
stop = createTime(timeTo, 1);
start = createTime(timeFrom);
}
console.log("Watching for calls between " + start + " and " + stop);
device.scheduler.setTimer({ name: startTimerName, time: start.getTime(), interval: "day" }, function() { startMonitoring(stop); });
}
init();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment