2017年9月18日月曜日

AndroidでSheetsAPIを使ってみる

自作アプリでGoogleSpreadSheetをつかってデータのImport/Exportの処理を作成した。 あんまり日本語記事書いている人がいなくて結構苦労したので、まとめて置こうと思う。(語尾が乱れているとか読みにくいとかは許してください)

リンク集

SheetsAPIのAndroidQuickStart
チュートリアル。まずこれに沿ってやればデータ取得はできる。
GoogleAPIコンソールのSheetsAPIプロジェクト作成ページ
上記チュートリアルにもあるが一応。ここでプロジェクト作成→証明書を貼り付けてSheetAPIを有効にする。
SheetsAPIのReference
どのようなRequestでどのような結果が返ってくるかが書いてある。ここの名前、場所と、AndroidのSheets.spreadsheets()以下が対応しているので、ここで調べてからJavaDocで調べた方がやりやすい。
SheetsAPIのJavaDoc
JavaDoc. メソッドの詳細とか詳しいところはここ
Google API Explorer
SheetsAPIへのrequestをお試しできる。パラメーターは何を入れればいいかなどのチェックができる。

前準備

データ取得については、前述の上のSheetsAPIのJavaQuickStartの1,2を実施し、3.のコードをコピペすれば取得できます。(雑)

データ取得

ここまでできたら実装開始。 SheetsクラスのインスタンスをSheets.Builder()作成し、そのinstanceでSheets#spreadsheets().values().get(spreadsheetsId:String, range:String).execute().getValue() を呼び出せば、range内の行列データをList>の形で取得してきてくれます。
Sheetsクラスのインスタンスを作成する前に、以下の項目をチェック、NGの場合にはDialogを出す等して対応してください。(以下の項目についてはチュートリアルのコードでもほぼチェックされているので、それを見つつ実装が一番はやいです)
  • GooglePlayServiceが利用可能か
  • GET_ACCOUNTSのPermissionが許可されているか
  • 選択されているGoogleアカウントが存在するか
  • デバイスがOnlineか
また、Sheets#spreadsheets().values().get().execute()のときにはUserRecoverableAuthIOException()というエラーが出たりします。このエラーに関してはpropertyにIntentがついてくるので、そのIntentをstartActivityForResultに投げれば端末側がよきに計らってくれます。

新規シート作成

Sheets#spreadsheets().create(Spreadsheet())を使います。 Spreadsheet()のInstanceに各設定を記載するのですが、何も設定しなくても作成可能です。(Web等で新規作成したのと同じ状態のシートが作成される)
Spreadsheet().spreadsheetIdは自動生成されるので、何か記載しても上書きされます。 また、作成されたシートはhttps://docs.google.com/spreadsheets/d/(spreadsheet().spreadSheetId)でアクセス可能です。
スプレッドシート内のシート(下のタブのやつ)はSpreadsheet().sheetsに設定します。sheetsはListを渡してあげればオーケーです。
多分、上記のAPIs Explorerを試しながら、それに対応するclass,設定値を探していくとできると思います。

シート内の値の更新

ここみるとわかりやすいです。
コード的には、 Sheets#spreadsheets().values().update(spreadsheetId:String, range:String, body:ValueRange()).setValueInputOption(<List<List<Object>>).execute() でできます。

 行列をValueRange().setValues(<List<List<Object>>)の状態で渡すこと(ちゃんと対応する大きさにしておくこと)、setValueInputOption(valueInputOption:String)をすることを忘れなければできると思います。
 ここみるとわかりやすいの先頭にvalueInputOptionに入れる値は書いてあります。(RAWとUSER_ENTERED。後者はWebのUIでSpreadSheetを操作し値を入力したときと同じような処理になります。RAWはStringで入力されるとイコールだと思えばよさそう)


とりあえず自分が使ったのはこの辺までです。
シートのサイズの更新なんかも、SheetsAPIのGUIDESのページを見ればだいたいわかると思います。(逆に一番躓いたのが新規シート作成でした。GUIDESのどこかに書いてあるのかな……) API REFERENCESでやりたいことの実現方法をさぐりつつ、APIs Explorerで試して、最後にJavaで対応するクラスを探す、が王道な気がします。
久々に長く書いた気がする!疲れた!

2017年9月5日火曜日

Roomでの対象テーブルのEntity全削除方法

Android Oから追加されたLibraryでAndroid Architecture Componentsがあるが、その中のSQLITE操作libraryのRoom。

Roomの公式

Update/Deleteに関してはテーブルに沿ったEntityをとり、そのPrimaryKeyを見て自動でUpdate/Deleteしてくれるすぐれもの。

しかし、PrimaryKey以外で条件付けしたり登録されているすべてのEntityにUpdate/Deleteするときはどうするか。

stackoverflowでズバリ書いてる人がいました。
https://stackoverflow.com/a/44249498
DAOのメソッドにつけるアノテーションをDeleteではなくSELECT文と同じ@Queryで好きなDELETE文が書けます。自分はDELETE FROM hogehogeで全削除しかしてませんが、引数をキーにしてのUPDATE/DELETEもこれでできそうです。

2017年8月23日水曜日

AndroidのsqliteでUPDATE時にORDER BYは使えない

久々ですね。今日からちょいちょい今日学んだことでかけそうなことがあったら短文で書こうかなーと思ってます。続かなさそうだけど……

Androidのsqlite3では基本的にはUPDATE/DELETEのときにLIMIT/ORDER BYが使えません。

sqliteのupdateはlimit出来ない by @daiki1003 on @Qiita http://qiita.com/ashdik/items/ec3b3cf7d80182298854

https://www.sqlite.org/lang_update.html
↑はsqlite公式。UPDATEの下の方に明記してあります。LIMITのNO LIMITとORDER BYを使うと大変になるから禁止です、と読み取りました(英語がふわっとしか読めない弊害

まぁ確かにORDER BYの対象カラム更新して不具合出そうだし私もまさにそうしようとしてたしなぁ。

一応、コンパイル時にフラグを設定すれば解除できるらしいですが、ソース取ってきて自前でビルドは必須みたいですね。

P.S. Android版のBloggerアプリ、BackgroundにいってonDestroyが走ったら編集途中の内容が全部消えて萎えた。(のでリンク編集せずに投稿します。