LoginSignup
5
13

More than 5 years have passed since last update.

GoogleAppsSriptAPI+Android/NFCで出席をとる

Posted at

今更感はありますが、AppsScriptAPIとNFC搭載のAndroidを使って、出席確認?アプリ的な物を作ってみたいと思います。
ちなみにですが、AppsScriptもAndroidもNFCも少しかじった程度の知識しかございません!
行きます。

GASでAPIを作る

まずはGASで関数を書きます。
とりあえず、ただの文字列をreturnするだけの関数です。

function getIcCardData() {
  var message = 'おつかれさまです';
  return message;
}

作った関数をAPIにし、外部から叩けるようにせねばならない。
以下を参考にさせていただきました。

認証情報の作成についてですが、
今回の呼び出し元はAndroidなので、クライアントIDの作成時に、アプリケーションの種類でAndroidを選びます。
OAuthクライアントIDで。

clientID.png

パッケージ名とSHA-1 署名証明書のフィンガープリントを登録する必要があります。
先に、Androidプロジェクトを作成してしまったほうが良さそうです。

AndroidStudioで、新規Androidプロジェクトを作成します。
上記画像に記載されている通り、作成後のAndroidManifest.xml内のpackage名をコピー、認証情報に貼り付けます。

SHA-1 署名証明書のフィンガープリントですが、こちらも同様に上記の画像の、
コマンドを実行することで、取得可能です。

keytool -exportcert -keystore path-to-debug-or-production-keystore -list -v

太字の部分でkeystoreファイルの場所を指定します。
今回はデバッグ用のkeystoreを使用します。
私の場合(Windows環境)、c:\Users\ユーザー名\.android\debug.keystore でした。
正しくコマンドを入力すると、パスワードを求められます。
debug.keystoreのパスワードはデフォルトだと"Android"となっています。表示されたフィンガープリントのSHA1をコピーし、認証情報に貼り付けて、保存します。

ここまでで、Android QuickstartのSTEP3までが完了しています。

Androidからアクセスしてみる

Android QuickstartのSTEP4~STEP6の対象ファイルを書き換えます。

build.gradleファイルですが、
gradleのバージョンが3.0であったため、以下のように変更しています。
dependencies部分のみの変更で大丈夫そうです。

dependencies {
    configurations.all {
        resolutionStrategy.force 'com.google.code.findbugs:jsr305:1.3.9'
    }
    implementation fileTree(dir: 'libs', include: ['*.jar'])
    implementation 'com.android.support:appcompat-v7:26.1.0'
    implementation 'com.android.support.constraint:constraint-layout:1.0.2'
    implementation 'com.android.support:design:26.1.0'
    testImplementation 'junit:junit:4.12'
    androidTestImplementation 'com.android.support.test:runner:1.0.1'
    androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.1'
    implementation 'com.google.android.gms:play-services-auth:11.8.0'
    implementation 'pub.devrel:easypermissions:0.3.0'
    implementation('com.google.api-client:google-api-client-android:1.23.0') {
        exclude group: 'org.apache.httpcomponents'
    }
    implementation('com.google.apis:google-api-services-script:v1-rev166-1.23.0') {
        exclude group: 'org.apache.httpcomponents'
    }
}

configurations.all {
resolutionStrategy.force 'com.google.code.findbugs:jsr305:1.3.9'
}
と後ろ4つのimplementationを追加しました。

AndroidManifest.xmlですが、
以下の追加のみでokです。

<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.GET_ACCOUNTS" />

MainActivity.javaに関してはAndroidQuickStartのコードを全コピーでいけます。
嘘を付きました。
getDataFromApiを少し変更します。

 private List<String> getDataFromApi()
                throws IOException, GoogleAuthException {
            // ID of the script to call. Acquire this from the Apps Script editor,
            // under Publish > Deploy as API executable.
            String scriptId = "APIIDを入力!";

            List<String> folderList = new ArrayList<String>();

            // Create an execution request object.
            ExecutionRequest request = new ExecutionRequest()
                    .setFunction("API関数名を入力!");

            // Make the request.
            Operation op =
                    mService.scripts().run(scriptId, request).execute();

            // Print results of request.
            if (op.getError() != null) {
                throw new IOException(getScriptError(op));
            }
            if (op.getResponse() != null &&
                    op.getResponse().get("result") != null) {
                //文字列を返すのでStringへキャストする
                 String data = (String)(op.getResponse().get("result"));
                 folderList.add(data);
            }

            return folderList;
        }

APIID、呼び出す関数の指定、加えて今回は文字列を受け取るので、戻り値をStringへキャストしています。

以上で準備完了です。
まだでした。今回のスクリプトはspreadsheetにアクセスして操作しようと思っているので、
spreadsheetに紐づくAppsScriptプロジェクトになっています。
スコープの設定が必要です。
クラス変数のSCOPESを以下に書き換えます。
"https://www.googleapis.com/auth/spreadsheets"

追加が必要なスコープはAppsScriptのスクリプトエディタ→ファイル→プロジェクトのプロパティにて確認可能です。

おそらく完了です。
APKを作成し、とりあえず動かしてみます。

起動した。
CALL GOOGLE APPS SCRIPT APIボタンを押下。

許可&許可。
認証アカウントを選択。(今回のAppsScriptを作成したアカウント)

読み込み中。

文字列が返ってきました。
おつかれさまです。

NFCでの読み取り部分を実装する

ここを参考にします。

AndroidManiFest.xmlにNFC関連のパーミッションを追加する。

<uses-permission android:name="android.permission.NFC" />

実装部分は後々書きます...

動かすまではできました。

カードをタッチして読み込み(結果が既に見えてしまっている...)

結果

スプレッドシートにも書き込み。

ss.png

照会用データはこんな感じ。

aaa.png

A列にIdmを持っている。

AppsScript側はこんな感じ。

var icCardSheetUrl = 'シートURL';

function getIcCardData(idm) {
    var spreadSheet = SpreadsheetApp.openByUrl(icCardSheetUrl);
    var activeSheet = spreadSheet.getSheetByName("icdata");
    var lastRowNum = activeSheet.getLastRow();
    var valueList = activeSheet.getRange(1,1,lastRowNum,2).getValues();
    var map = {};
    for(var i = 0; i < valueList.length; i++){
        var childList = valueList[i];
        map[childList[0]] = childList[1];
    }
    var name = map[String(idm)];
    Logger.log(name);
    writeAttendanceData(name);
    return name;
}

function writeAttendanceData(name){
    var sheet = SpreadsheetApp.openByUrl(icCardSheetUrl);
    var activeSheet = sheet.getSheetByName('attendance');
    var lastRowNum = activeSheet.getLastRow();
    var range = activeSheet.getRange(lastRowNum+1,1,1,2);
    var today = new Date();
    var timeString = today.getHours()+":"+ today.getMinutes()+":"+ today.getSeconds();
    var values = [[name,timeString]];
    range.setValues(values);
}

Androidの画面のデザインを勉強すること。

5
13
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
13