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が走ったら編集途中の内容が全部消えて萎えた。(のでリンク編集せずに投稿します。

2015年11月27日金曜日

Android Framework Code Readingな勉強会に行ってきた。

表題の通りです。昨日勉強会にいってきました。

https://mandroidfcr.doorkeeper.jp/events/33925
みんなでAndroidFrameworkをもくもくと読んで最後に何やったか報告しようーみたいな感じでした。

自分のテーマ


なんでActivity.onKeyDown/UpにDPAD_CENTER来ないんじゃワレ問題
(ちょうどその日の業務でドハマリしたので。本当はRecyclerViewとか見たかったんだけどなー)

内容

Activityを読んで見る。
http://tools.oesf.biz/android-6.0.0_r1.0/xref/frameworks/base/core/java/android/app/Activity.java#2714
onKeyDown/Upに関してはその前にdispatchKeyEvent()を経由してくるので、そこを読む。

decorViewって何
http://stackoverflow.com/questions/23276847/what-is-an-android-decorview”The DecorView is the view that actually holds the window’s background drawable.”
要するに大元の、Window全体のViewってことか?

  2730         return event.dispatch(this, decor != null
   2731                 ? decor.getKeyDispatcherState() : null, this);
   2732     }
return がevent.dispatch()なのでKeyEvent.dispatch()を読んでみる


public final boolean dispatch(Callback receiverDispatcherState stateObject target) {
http://tools.oesf.biz/android-6.0.0_r1.0/xref/frameworks/base/core/java/android/view/KeyEvent.java#2633ここでActionごとにCallbackとして設定しているActivity.thisのonKeyDownとかUpとかを呼び出している
ちなみにonKeyDownでActivity.onKeyDownの戻り値をtrueにするとstate.startTrackingにする。downのときにtrueにするとstaticクラスのstateのtrackingに登録されるっぽい。
→今trackingしているものは何かを取得すると一意で返ってくるのはそのせい。

とりあえずActivityのonKeyDownを見ようかな…と思ったけどDPAD_CENTERが名指しで使われている箇所をあたってみようかな、と思ってみる。

DPAD_CENTERが呼ばれている箇所を見てみる。

これが意外と少なくてよかった。

Activityの方にあるのはコメントアウトされているしStartActivitiyForResult関係っぽいから違いそう。なのでとりあえず無視。
そしてView.onKeyDown/onKeyUpになんかいろいろコメント書いてある かなりそれっぽいけどコードにはいない→なんか怪しいKeyEvent.isFonfirmKey()ってメソッドいる
http://tools.oesf.biz/android-6.0.0_r1.0/xref/frameworks/base/core/java/android/view/KeyEvent.java#1753KeyEvent.isConfirmKey()でDPAD_CENTERまたはENTERの場合にtrueで返している!!
つまりはDPAD_CENTERまたはENTERのときにごにょごにょごにょとしているわけだ。
多分ここでDPAD_CENTERの処理を行っているから、Activityの方に伝わらなかった…?というところで時間切れ。
まぁ1時間くらいだったから仕方ないね…。

わかんなかったこと


ActivityからViewにどうやっていってるんだろうということ。
(ちょっと今ざっと見てもわからなかったので今後の課題にしたいorz)

感想


rebuild.fmがBGMだったのですが、最初は結構耳に入ってきてちょっと集中できなかった。。
途中から気にならなくなってきたが、更に途中でアニメの話になってうっかりと聞きこんでしまった。
私はシュタゲ見てないし、まど☆マギのTV版のラストはハッピーエンドではないがバッドエンドというほどでもないと思います。叛逆はどう考えても最高にバッドエンド。あの終わり方大好き。

主催の方がメルカリの方らしく、また会場もメルカリだったため、メルカリの会社見学させてもらえた。洒落たオフィスや…なんだこの洒落っぷりは…



みんなが気になるなーと思う場所のコードを読んでいるから、結構見ている箇所が多岐に渡っていて、
へーみんなそういうところが気になるんだーとか、そういうきっかけで調べ始めるのかーとか、そういった別の視点があったなと思った。ホーム画面のPagerとか気にしたことがなかったので、そういった気づきもあった。

なかなかじっくりと、ただFrameworkのコードを読むという時間って取れないので、結構貴重な時間だったと思う。
どうしても会社にいる時間は業務でわたわたしてしまうし、プライベートでコード書くときもがりがりと書いてしまうので、もっと他の人のコード読んだほうがいいのかなーとは思った。
ぜひ、次回もあったら参加したい勉強会でした。

はじめまして。

というわけで初めてのブログです。

まれに更新する予定の技術ブログです。
同じ名前のブログで以前やってましたが、いかんせん古くなっちゃったなーというのとあと
後私自身のgoogleアカウントが変わってしまったために今後変更が難しそうだから、みたいな感じです。

ぐだぐだっとやっていこうと思いますのでよろしくお願いします。