バッテリー監視のためにバックグラウンドタスクについて調べたらなくなってたから泣く泣くタイマーapiを使ってみた話...

15
バッテリー監視のためにバックグラウンド タスクについて調べたらなくなってたから 泣く泣くタイマーAPIを使ってみた話 のはずだった 株式会社 グローバルサイバーグループ 藪下正美

Upload: masami-yabushita

Post on 24-May-2015

4.533 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: バッテリー監視のためにバックグラウンドタスクについて調べたらなくなってたから泣く泣くタイマーApiを使ってみた話

バッテリー監視のためにバックグラウンド タスクについて調べたらなくなってたから

泣く泣くタイマーAPIを使ってみた話

のはずだった

株式会社

グローバルサイバーグループ

藪下正美

Page 2: バッテリー監視のためにバックグラウンドタスクについて調べたらなくなってたから泣く泣くタイマーApiを使ってみた話

自己紹介

•自己紹介の時間が ありません!

• サクサク行きます

@aoi_nagatsuki

Page 3: バッテリー監視のためにバックグラウンドタスクについて調べたらなくなってたから泣く泣くタイマーApiを使ってみた話

バッテリーログがとりたい!

• バックグラウンド動作させておいて バッテリーAPIのコールバックを受ければ いいんじゃね?

• バックグラウンド動作ないかマニフェストの ドキュメント見てみた – https://developer.mozilla.org/id/docs/Apps

/Manifest

• あった – backgroundservice

• Enable a web application to run in the background and perform tasks like syncing or responding to incoming messages.

Page 4: バッテリー監視のためにバックグラウンドタスクについて調べたらなくなってたから泣く泣くタイマーApiを使ってみた話

バックグラウンドタスクで バッテリー監視してみる

• Systemアプリを参考にした

• manifest.webappにbackground_pageプロパティを書く

– バックグラウンド動作するhtmlを指定する

• permissionsでbackgroundserviceを許可

// こんな感じで "background_page": "/index.html", "permissions": { "backgroundservice": {} },

Page 5: バッテリー監視のためにバックグラウンドタスクについて調べたらなくなってたから泣く泣くタイマーApiを使ってみた話

バックグラウンドタスクで バッテリー監視してみる

• background_pageに指定したhtmlでバッテリー監視する – navigator.batteryにリスナを与える

– chargingchangeとlevelchangeがある • chargingchangeは充電器を繋いだり外したりのイベント

• levelchangeは バッテリー残量の変更イベント

// こんな感じで battery.addEventListener(“chargingchange”, リスナ); battery.addEventListener(“levelchange”, リスナ);

Page 6: バッテリー監視のためにバックグラウンドタスクについて調べたらなくなってたから泣く泣くタイマーApiを使ってみた話

なんだか動かない(´・ω・`)

• Certifiedな特権がいるっぽい

– https://developer.mozilla.org/en-US/Apps/Developing/App_permissions

• エミュレータビルドした(v1_train)

– 動いた

• 最近のでは動かないはずなのでもう一度ビルドした(v1.3)

– 動いた(´・ω・`)

Page 7: バッテリー監視のためにバックグラウンドタスクについて調べたらなくなってたから泣く泣くタイマーApiを使ってみた話

バックグラウンドタスクが 削除された経緯を調べた

• なんか前にbackgroundserviceを使ってたgaiaアプリからざくざくbackgroundserviceが削除されたた記憶があるのではてな? となった

• から調べた – この辺でバックグラウンド動作重いから ごにょごにょとか言ってる雰囲気 • https://github.com/mozilla-

b2g/gaia/commit/7f27d41a9202f9390c5e09475fe03fc7f3e77b83

• https://bugzilla.mozilla.org/show_bug.cgi?id=866174

• えいごよめない(´・ω・`)

Page 8: バッテリー監視のためにバックグラウンドタスクについて調べたらなくなってたから泣く泣くタイマーApiを使ってみた話

タイマーAPIで間欠動作

• Certifiedでは配布できない

• そういえばAlermとかあった – https://developer.mozilla.org/id/docs/A

pps/Manifest

– alarm • Schedule a notification, or schedule an

application to be started.

• Certifiedでもない – https://developer.mozilla.org/en-

US/Apps/Developing/App_permissions

Page 9: バッテリー監視のためにバックグラウンドタスクについて調べたらなくなってたから泣く泣くタイマーApiを使ってみた話

タイマーAPIで間欠動作

• SMSアプリを参考にした

• manifest.webappのpermissions プロパティにalarmsを書いておく

• もう一つmessagesプロパティにalarmを書いておく – 値としてアラーム起動す

るhtmlのパスを書く

// こんな感じで "permissions": {

"alarms": {}

},

"messages": {

{ "alarm": "/index.html" }

}

Page 10: バッテリー監視のためにバックグラウンドタスクについて調べたらなくなってたから泣く泣くタイマーApiを使ってみた話

タイマーAPIで間欠動作

• アラームを追加する

– いつ発火するか

– タイムゾーンを考慮するか

– 発火したときに渡されるデータ

• を指定する

var request = navigator.mozAlarms.add(

new Date((new Date())

.getTime() + time),

"ignoreTimezone",

{message:"battery_log"});

request.onsuccess = function () {

alarmId = this.result;

}

Page 11: バッテリー監視のためにバックグラウンドタスクについて調べたらなくなってたから泣く泣くタイマーApiを使ってみた話

タイマーAPIで間欠動作

• あともうひといき!

• メッセージとしてくるのでメッセージハンドラを登録する

– 今回はアラームなので"alarm"のハンドラですよと指定

navigator

.mozSetMessageHandler(

"alarm",

function (mozAlarm) {

なんかなんか

});

Page 12: バッテリー監視のためにバックグラウンドタスクについて調べたらなくなってたから泣く泣くタイマーApiを使ってみた話

タイマーAPIで間欠動作

• バッテリーAPIから バッテリー残量を とって記録 – バッテリー残量は

navigator.battery.levelで取れる

• ついでに充電状態も記録 – 充電状態は

navigator.battery.chargingで取れる

// こんな感じで {

date: "" +

d.getFullYear() + d.getMonth() +

d.getDate() + d.getHours() + d.getMinutes(),

level: battery.level * 100,

charging: battery.charging

}

Page 13: バッテリー監視のためにバックグラウンドタスクについて調べたらなくなってたから泣く泣くタイマーApiを使ってみた話

できた! <!DOCTYPE html PUBLIC ">

<html>

<head>

<title>Battery Logger</title>

<meta charset="utf-8">

<link href="./style/switches.css" rel="stylesheet" type="text/css">

<link href="./style/buttons.css" rel="stylesheet" type="text/css">

<style>

#level_graph {

font: 10px sans-serif;

}

.axis path,

.axis line {

fill: none;

stroke: #000;

shape-rendering: crispEdges;

}

.x.axis path {

display: none;

}

.line {

fill: none;

stroke: steelblue;

stroke-width: 1.5px;

}

</style>

<script src="./js/index.js"></script>

<script>

</script>

</head>

<body>

<!-- グラフ -->

<div id="level_graph"></div>

<script src="./js/d3.v3.js"></script>

<script>

var battery = navigator.battery || navigator.mozBattery || navigator.webkitBattery;

var db;

var req = window.indexedDB.open("BatteryLoggerDB", 1);

req.onerror = function(evt) {

console.log("DB Error(req)");

};

req.onsuccess = function(evt) {

console.log('request.onsuccess');

db = req.result;

var transaction = db.transaction(["battery_log"]);

var objectStore = transaction.objectStore("battery_log");

var data = [];

objectStore.openCursor().onsuccess = function(event) {

color.domain("l");

var cursor = event.target.result;

if (cursor) {

cursor.value.date = parseDate(cursor.value.date);

data.push({ date: cursor.value.date, temperature: cursor.value.level });

cursor.continue();

} else {

var cities = color.domain().map(function(name) {

return {

name: name,

values: data.map(function(d) {

return {date: d.date, temperature: d.temperature};

})

};

});

x.domain(d3.extent(data, function(d) { return d.date; }));

y.domain([

// d3.min(cities, function(c) { return d3.min(c.values, function(v) { return v.temperature; }); }),

// d3.max(cities, function(c) { return d3.max(c.values, function(v) { return v.temperature; }); })

0,

100

]);

svg.append("g")

.attr("class", "x axis")

.attr("transform", "translate(0," + height + ")")

.call(xAxis);

svg.append("g")

.attr("class", "y axis")

.call(yAxis)

.append("text")

.attr("transform", "rotate(-90)")

.attr("y", 6)

.attr("dy", ".71em")

.style("text-anchor", "end")

.text("Temperature (oF)");

var city = svg.selectAll(".city")

.data(cities)

.enter().append("g")

.attr("class", "city");

city.append("path")

.attr("class", "line")

.attr("d", function(d) { return line(d.values); })

.style("stroke", function(d) { return color(d.name); });

city.append("text")

.datum(function(d) {

return {name: d.name, value: d.values[d.values.length - 1]};

})

.attr("transform", function(d) {

return "translate(" + x(d.value.date) + "," + y(d.value.temperature) + ")";

})

.attr("x", 3)

.attr("dy", ".35em")

.text(function(d) { return d.name; });

}

};

};

req.onupgradeneeded = function(event) {

console.log('request.onupgradeneeded');

db = event.target.result;

var objectStore = db.createObjectStore("battery_log", { keyPath: "date" });

objectStore.createIndex("date", "date", { unique: true });

objectStore.createIndex("level", "level", { unique: false });

objectStore.createIndex("charging", "charging", { unique: false });

};

var margin = {top: 10, right: 10, bottom: 30, left: 20}, width = 320 - margin.left - margin.right, height = 240 - margin.top - margin.bottom; var parseDate = d3.time.format("%Y%m%d%H%M").parse; var x = d3.time.scale() .range([0, width]); var y = d3.scale.linear() .range([height, 0]); var color = d3.scale.category10(); var xAxis = d3.svg.axis() .scale(x) .orient("bottom"); var yAxis = d3.svg.axis() .scale(y) .orient("left"); var line = d3.svg.line() //.interpolate("basis") .x(function(d) { return x(d.date); }) .y(function(d) { return y(d.temperature); }); var svg = d3.select("#level_graph").append("svg") .attr("width", width + margin.left + margin.right) .attr("height", height + margin.top + margin.bottom) .append("g") .attr("transform", "translate(" + margin.left + "," + margin.top + ")"); function addObj() { var transaction = db.transaction(["battery_log"], "readwrite"); var objectStore = transaction.objectStore("battery_log"); var d = new Date(); const addData = [ { date: "" + d.getFullYear() + d.getMonth() + d.getDate() + d.getHours() + d.getMinutes(), level: battery.level * 100, charging: battery.charging } // { date: "201311251000", level: 63.4, charging: false }, // { date: "201311251010", level: 58.0, charging: false }, // { date: "201311251020", level: 53.3, charging: false }, // { date: "201311251030", level: 55.7, charging: true }, // { date: "201311251040", level: 64.2, charging: true }, // { date: "201311251050", level: 58.8, charging: false }, // { date: "201311251100", level: 57.9, charging: false }, // { date: "201311251110", level: 61.8, charging: true }, // { date: "201311251120", level: 69.3, charging: true }, // { date: "201311251130", level: 71.2, charging: true } ]; // for (var i in addData) { // objectStore.add(addData[i]); // console.log(i); // } var request = objectStore.add(addData[0]); request.onsuccess = function(e){ console.log("add - success"); } request.onerror = function(e){ console.log("add - error"); } transaction.oncomplete = function(event) { console.log("transaction.oncomplete"); }; transaction.onerror = function(event) { console.log("transaction.onerror"); }; transaction.onabort = function(event) { console.log("transaction.onabort"); }; } function setAlarm() { var time = 10 * 60 * 1000; // 10分後 var request = navigator.mozAlarms.add( new Date((new Date()).getTime() + time), "ignoreTimezone", { message: "battery_log" } ); request.onsuccess = function () { alarmId = this.result; } } setAlarm(); navigator.mozSetMessageHandler("alarm", function (mozAlarm) { addObj(); setAlarm(); }); function updateBatteryStatus() { addObj(); } battery.addEventListener("chargingchange", updateBatteryStatus); battery.addEventListener("levelchange", updateBatteryStatus); </script> <form action="#" method="POST"> <ul> <li> <!-- 間隔を選ぶドロップダウンメニュー (Menu) --> <select id="logspan"> <option> 5 min</option> <option>10 min</option> <option>15 min</option> <option>30 min</option> <option>60 min</option> </select> </li> </ul> <!-- 端末起動時に自動的にアプリを起動するチェックボックス --> <!-- <label class="pack-checkbox"> <input type="checkbox" checked> <span>Auto starting at Booting device?</span> </label> --> <input type="button" onclick="addObj()"> </form> </body> </html>

( ゚д゚)

Page 14: バッテリー監視のためにバックグラウンドタスクについて調べたらなくなってたから泣く泣くタイマーApiを使ってみた話

バックグラウンド動作の仕組みを調べる気に なったので続きはGecko勉強会で!

• FxOS Gecko勉強会

– http://atnd.org/events/44741

時間 発表者 タイトル

19:00 – 19:30 @makoto_kato Moz2D

19:30 – 19:50 にしむねあ Firefox OS パッケージ型アプリ 起動の仕組みを調べてみた

20:00 – 20:30 @aoi_nagatsuki

バッテリー監視の為にバックグラウンドタスクについて調べたらなくなってたから作ってみた話 のはずだった

20:30 – 20:50 @masap Firefox OS 日本語 IME 開発状況

20:50 – 片付け・懇親会準備

Page 15: バッテリー監視のためにバックグラウンドタスクについて調べたらなくなってたから泣く泣くタイマーApiを使ってみた話

今回の詳しい話は

• GCG研究所に書きます – まだ書いてませんごめんなさい。。。

• ちなみにかっしー先生が今回のネタに もろかぶりな記事を書いて下さってます – ほんとバッチリかぶりやがってこの野郎ありがとうございます! • http://mobiletou.ch/2013/11/alarm-api-アラームを利用する

• http://mobiletou.ch/2013/10/battery-status-api-端末のバッテリー状態を取得