以前にも棚卸パッケージをクラウド対応するっていう話がありました。その概要はGoogle Apps ScriptでAPIを作成して、Androidアプリを改造して通信先をそのAPIに向けるというものでした。今回はちょっとアプローチを変えて、Androidアプリはそのままで、この記事で試したように、WebとはBluetooth経由で通信しようと考えました。
使ったもの
やったこと
クラウド側にはGoogle Spreadsheetを使用しました。アドオンでSpreadsheetに機能を追加できるので、これを使用しました。アドオンでは、呼び出し元をgsで記述、UIをhtmlで作成して、動作をJavascriptで記述することができます。こんな感じです。
呼び出し元
function onInstall(e) {
onOpen(e);
}
function onOpen(e) {
var ui = SpreadsheetApp
.getUi()
.createAddonMenu()
.addItem('リーダ', 'showSidebar')
.addToUi();
}
function showSidebar() {
var sidebarUi = HtmlService
.createTemplateFromFile('Sidebar')
.evaluate()
.setTitle('MANICA');
SpreadsheetApp
.getUi()
.showSidebar(sidebarUi);
}
UI
<!DOCTYPE html>
<html>
<head>
<base target="_top">
<link rel="stylesheet" href="https://ssl.gstatic.com/docs/script/css/add-ons1.css">
</head>
<body>
<div>
<form>
<p>
<select id="inputMode">
<option value="fill">セルへ入力する</option>
<option value="findTag">ICタグを探す</option>
<option value="findCell" selected>セルを探す</option>
</select>
</p>
</form>
<button id="connect" onclick="readerLibrary.start();">接続</button>
</div>
<?!= HtmlService.createHtmlOutputFromFile('ReaderLibrary').getContent(); ?>
</body>
</html>
Javascript(GAS上では拡張子はhtmlしか設定できないみたいです)
<script>
window.readerLibrary = {
writer: undefined,
encoder: undefined,
start: async function () {
const requestOptions = {};
let port;
try {
port = await navigator.serial.requestPort(requestOptions);
await port.open({ baudrate: 115200 });
} catch (err) {
console.log(err);
return;
}
console.log('connected: ' + port);
while (port.readable && port.writable) {
console.log('readable and writable');
this.encoder = new TextEncoder();
this.writer = port.writable.getWriter();
const decoder = new TextDecoder();
const reader = port.readable.getReader();
while (true) {
console.log('while loop');
let value, done;
try {
({ value, done } = await reader.read());
} catch (err) {
console.log(err);
break;
}
if (done) {
break;
}
//this.handleChunk(decoder.decode(value));
// this.dotNet.invokeMethod('OnReceived', value);
console.log(value);
}
this.writer.releaseLock();
reader.releaseLock();
await port.close();
console.log('disconnected');
}
console.log('while loop done');
}
};
</script>
メニューから作ったアドオンを選択すると、こんな感じで表示されます。
あとは接続ボタンを押せばつながるはずと思ったのですが、残念ながら下記のエラーが表示されて、うまくいきませんでした。 userCodeAppPanel:9 [Violation] Feature policy violation: serial is not allowed in this document. |
エラーメッセージを基に調べてみると、下記のIssueが見つかりました。(下記はgeolocationに関するIssueですが、今回のとエラーの原因は同じと思います)
feature policyでserialを許可する必要があるみたいなのですが、Spreadsheetのアドオンからですと、iframeを使った方法もresponse headerを使う方法もどちらも提供されていないようです。そのため、このやり方ではうまく行かず、まったく別の方法を考える必要があるようです。という訳で、うまくいかなかった話でした。
実は上記のあと、Office 365でもチャレンジしてみたのですが、チュートリアルでエラーが出てしまい、挫折しました。
https://issuetracker.google.com/issues/68032861#comment8
返信削除去年の11月にコメントが付いてました。もしかして変わるのかも。