Android
AndroidStudio
android開発
GoogleSpreadSheet

GoogleSpreadSheet APIをAndroidで用いる

公式リファレンス

  1. https://developers.google.com/sheets/api/guides/concepts
  2. https://developers.google.com/sheets/quickstart/android?hl=ja#step_5_setup_the_sample

最初に検索すると1つ目のサイトに行き着くと思う。がとてもあっさり。
2つ目の方にはかなり詳しく書いてくれているのだが、サイト内からは行くことができずURL直入力じゃないとダメなよう。

そもそもこのAPIの情報はバージョンも色々あり情報が錯綜しているとの話もある。

どうやったか

いろいろ探すとそれっぽい記事があったのでそれ通りにやってみた。

主に上記リファレンスの2をメインに参考にしている。

実際の工程は本当に記事のまんまで必要なところを入れているだけなので省略。

問題点

  • 複数のActivityから実行する場合、処理をそれぞれのアクティビティに記述しなければならない。

以下の4行目のCotexstなど、

サンプルコード
//~~~~~~~省略~~~~~~~~
private void chooseAccount() {
        if (EasyPermissions.hasPermissions(
                this, Manifest.permission.GET_ACCOUNTS)) {
            String accountName = getPreferences(Context.MODE_PRIVATE)
                    .getString(PREF_ACCOUNT_NAME, null);
            if (accountName != null) {
//~~~~~~~省略~~~~~~~~

サンプルコード各所でContextを求められがうまく調整できず、データ取得などAPIの呼び出す一連のコードを必要な全てのActivityに入れている。Task部分以外は共通なのでそこを別クラスで書いて呼び出せるといいのだが。。。Contextだけ引数にとってきたら行けるかも。(チャレンジ中)

  • 複数のActivityから実行する場合、Googleアカウントの選択がActivity毎に求められる。(解決)

MainActivity以外でAPIを実行するとき、OnCreateでのmCredentialの代入をMainActivityのmCredentialからの代入にすれば選択は起きなくなった。

元コード
mCredential = GoogleAccountCredential.usingOAuth2(
                    getApplicationContext(), Arrays.asList(SCOPES))
                    .setBackOff(new ExponentialBackOff());
変更後
mCredential = MainActivity.mCredential;
  • 複数のActivityから実行する場合、OnCreateにシート取得を記述するとMainActivityに戻るたびに実行してしまう(解決)

若干力技ではあるが、Applicationのクラスでpublic変数をint型・=0 で宣言し、これをMainActivityのonCreateが1回目の実行かどうかのフラグに使うことで、起動時のみ取得を実行するようにできた。(取得ボタンを別に設置している。)

Applicationを継承したクラス
//以下に書いた項目以外もよしなに記述してOK
public static int a;//起動時フラグメント 毎回の起動時
    @Override
    public void onCreate(){
        super.onCreate();
        a = 0;
    }
MainActivity
//省略部分や前後の部分など、よしなに書いてOK
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
//~~~~~~~~~~省略~~~~~~~~~~
    if(MentorTerminalForCampApplication.a == 0) {
    mCredential = GoogleAccountCredential.usingOAuth2(
            getApplicationContext(), Arrays.asList(SCOPES))
            .setBackOff(new ExponentialBackOff());
    mProgress.setMessage("Calling Google Sheets API ...");
    getResultsFromApi();
    MentorTerminalForCampApplication.a = 1;
//~~~~~~~~~~省略~~~~~~~~~~
}

戻るボタンで対応できる場合は遭遇しないが、今回は下部にMAIN、ページ1、ページ2それぞれに遷移する3つのボタンを設けるため、IntentでMAINへ戻るようにしている。

MainActivityへの遷移
Intent intent = new Intent(v.getContext(), ToDoActivity.class);
        intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
        v.getContext().startActivity(intent);

この結果、onCreateが再度呼び出されるようになっている。
ちなみに3つのActivityのどこでもMainへアクセスできるので、戻る機能だけでは対応できない。
例)Main->page1->page2 ここでMainActivityボタン(戻る) => Main->page1(Mainに遷移できてない。)

・別の解決方法として
Activityを重ねた数を確認し(あるいは記録し続け)、重ねた回数分戻るを実行すれば回避できる。
(for と Flag用int あたり使えばあっさり実装できる)
ただこれよりも前述のほうが汎用性があるのでそちらの方がいいかと。一回しか実行したくないことって他にもある。また、Flagをリセット・Activity再生成するボタンを実装すれば、任意のタイミングで値も含めて再度生成なんていう実装もできる。

まとめ(コメント的な)

  • リファレンス1の方でやるとJsonが絡んできているようなのと、実際の返ってくる値がわからなかった。また、認証周りもAndroidの環境と整合性がとるのに苦労しそうだったので、今回は使わなかった。試してみたい。

  • 認証周りが本当にややこしいので、認証方法&GooglePlayServiceだけで別に調べると良い。Qiita1記事できるくらいには深い。

  • Importの量が一気に増えることからわかるように、コードが複雑に絡まって実際の処理(具体的になんの値を渡しているのかなど)がわかりにくい。全てはまだわからんです。

  • SpreadSheetAPIはやはり闇が深かった。