Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Chrome Extension Alarms go off when Chrome is reopened after time runs out?

When using Google Chrome extension alarms, the alarm will go off if it was set and Chrome is closed and reopened after the time expires for the alarm.

How can I stop this?

Here is a small code sample to explain what I mean.

/* 
If we perform Browser Action to create alarm, then 
close the browser, wait about 2 minutes for the alarm to expire
and then reopen the browser, the alarm will go off and the DoSomething 
function will get called twice, once by the onStartup event and once
by the onAlarm event.
*/
chrome.browserAction.onClicked.addListener(function (tab) {
    chrome.alarms.create('myAlarm', {
        delayInMinutes : 2.0
    });
});

chrome.alarms.onAlarm.addListener(function (alarm) {
    console.log('Fired alarm!');
    if (alarm.name == 'myAlarm') {
        createListener();
    }
});

chrome.runtime.onStartup.addListener(function () {
    console.log('Extension started up...');
    DoSomething();
});

function DoSomething() {
    alert('Function executed!');
}

So if you will read the comment at the top of my code sample you will see what happens.

What I want though, is for the alarm to get cleared if the browser is closed as I want the DoSomething function to get executed only by the onStartup event if the browser is just started, and let the alarm execute the DoSomething function only after the browser is started and my code creates a new alarm.

I never want an alarm to stay around after the browser is closed and then execute onAlarm when the browser is reopened.

How can achieve this?

like image 595
user1876122 Avatar asked Dec 31 '12 12:12

user1876122


1 Answers

It's not possible for a Chrome extension to reliably run some code when the browser closes.

Instead of cleaning up on shutdown, just make sure that old alarms are not run on startup. This can be achieved by generating an unique (to the session) identifier.

If you're using event pages, store the identifier in chrome.storage.local (don't forget to set the storage permission in the manifest file). Otherwise, store it in the global scope.

// ID generation:
chrome.runtime.onStartup.addListener(function () {
    console.log('Extension started up...');
    chrome.storage.local.set({
        alarm_suffix: Date.now()
    }, function() {
        // Initialize your extension, e.g. create browser action handler
        // and bind alarm listener
        doSomething();
    });
});

// Alarm setter:
chrome.storage.local.get('alarm_suffix', function(items) {
    chrome.alarms.create('myAlarm' + items.alarm_suffix, {
        delayInMinutes : 2.0
    });
});

// Bind alarm listener. Note: this must happen *after* the unique ID has been set
chrome.alarms.onAlarm.addListener(function(alarm) {
    var parsedName = alarm.name.match(/^([\S\s]*?)(\d+)$/);
    if (parsedName) {
        alarm.name = parsedName[0];
        alarm.suffix = +parsedName[1];
    }
    if (alarm.name == 'myAlarm') {
        chrome.storage.local.get('alarm_suffix', function(data) {
            if (data.alarm_suffix === alarm.suffix) {
                doSomething();
            }
        });
    }
});

If you're not using event pages, but normal background pages, just store the variable globally (advantage: id reading/writing becomes synchronous, which requires less code):

chrome.runtime.onStartup.addListener(function () {
    window.alarm_suffix = Date.now();
});
chrome.alarms.create('myAlarm' + window.alarm_suffix, {
    delayInMinutes : 2.0
});
chrome.alarms.onAlarm.addListener(function(alarm) {
    var parsedName = alarm.name.match(/^([\S\s]*?)(\d+)$/);
    if (parsedName) {
        alarm.name = parsedName[0];
        alarm.suffix = +parsedName[1];
    }
    if (alarm.name == 'myAlarm') {
        if (alarm.suffix === window.alarm_suffix) {
            doSomething();
        }
    }
});

Or just use the good old setTimeout to achieve the same goal without side effects.

setTimeout(function() {
    doSomething();
}, 2*60*1000); // 2 minutes
like image 123
Rob W Avatar answered Sep 28 '22 06:09

Rob W