Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
Help us understand the problem. What is going on with this article?

【Mac不要】iOSとAndroidのFlutterアプリから利用者のGoogle Photosにアクセスする手順 - Codemagic編 (後編)

はじめに

※この記事は、以下の記事の続編です。

【Mac不要】iOSとAndroidのFlutterアプリから利用者のGoogle Photosにアクセスする手順 - Codemagic編 (前編)

この記事ではその後、Flutterアプリから利用者のGoogle Photoにアクセスするための手順を説明します。

ただし、具体的な実装方法は Build a Photo Sharing app with Google Photos and Flutter - Codelabs で公開されているので、ここでは主に「Googleアカウント(Firebase認証)からの"Build a Photo Sharing app with Google Photos"」の適用手順を説明します。

では早速始めましょう。

前提

この記事は、以下に当てはまる人向けの iOS/Android 対応アプリにGoogle Sign-in APIを組み込む手順を紹介します。

  • 開発機はWindowsだ
  • Macを持っていない
  • Flutterで開発したい
  • Apple Developer Programに既に登録している。

開発環境の前提

以下の4本の記事の手順に沿ってFlutterアプリの作成を進めてください。

  1. 【Mac不要】開発中のFlutter製アプリをiOSとAndroidに実機配備する手順 - Codemagic編
  2. 【Mac不要】FlutterアプリにFirebase SDKを組み込んでiOSとAndroidに実機配備する手順 - Codemagic編
  3. 【Mac不要】FlutterアプリにFirebase Crashlyticsを組み込んでiOSとAndroidに実機配備する手順 - Codemagic編
  4. 【Mac不要】iOSとAndroidのFlutterアプリから利用者のGoogle Photosにアクセスする手順 - Codemagic編 (前編)

ソースコードの公開

この記事の手順で作成したソースコードはGithubで公開しています。併せてご参照ください。
https://github.com/atsuteru/flutter_firebase_0507/tree/Qiita-GooglePhoto-v1.2

本文

APIのインタフェースを準備する

Google Photos APIを利用して新規アルバムを作成する場合、次のAPIを利用します。

Method: albums.create - Google Photos APIs

そこには、Requestとして必要なJsonデータの形式が記述されていますね。このJsonを組み立てるための型を準備しましょう。
その型は、Codelabsでサンプルを公開してくれているので、それをそのまま利用しちゃいましょう。

次の4つのソースコードをダウンロードしてください。
Github: googlecodelabs/photos-sharing/lib/
* lib/photos_library_api/album.dart
* lib/photos_library_api/album.g.dart
* lib/photos_library_api/create_album_request.dart
* lib/photos_library_api/create_album_request.g.dart

これを、自身のアプリの lib/photos_library_api の下に取り込みます。

取り込んだ後、create_album_request.dartのimport宣言の一部を書き換えてください。

create_album_request.dart
//import 'package:sharing_codelab/photos_library_api/album.dart';
import 'album.dart';

APIの認証ヘッダを準備する

Google Photos APIを利用するためには、送信するHTTPリクエストに認証ヘッダを加える必要があります。
認証ヘッダは、Googleアカウントにサインインした情報から得ることができます。

サインイン処理を、以下のように修正しましょう。

main.dart
class _MyHomePageState extends State<MyHomePage> {
  int _counter = 0;
  FirebaseUser _currentUser;
//...(追加ココカラ)...
  Future<Map<String, String>> _authHeaders;
//...(追加ココマデ)...
  Future<bool> _handleSignIn(GoogleSignInAccount googleSignInAccount) async {
    if (googleSignInAccount == null) {
      return false;
    }
    final GoogleSignInAuthentication googleSignInAuthentication = await googleSignInAccount.authentication;
    final AuthCredential credential = GoogleAuthProvider.getCredential(
      accessToken: googleSignInAuthentication.accessToken,
      idToken: googleSignInAuthentication.idToken,
    );
    final AuthResult authResult = await _auth.signInWithCredential(credential);
    final FirebaseUser user = authResult.user;
    if (user.isAnonymous) {
      return false;
    }
    if (await user.getIdToken() == null) {
      return false;
    }
    final FirebaseUser currentUser = await _auth.currentUser();
    if (user.uid != currentUser.uid) {
      return false;
    }

    setState(() {
      _currentUser = currentUser;
//...(追加ココカラ)...
      _authHeaders = googleSignInAccount.authHeaders;
//...(追加ココマデ)...
    });
    return true;
  }
}

新規アルバムを作成するためのAPI呼び出しをコーディングする

新規アルバムを作成するためのAPI呼び出しの方法は、Codelabsの手順 (5) Create an albumで紹介されています。

それを参考にコーディングすると、例えば「Make Albumボタンが押された際に新規アルバムを作成するメソッド」は以下のように書くことができます。
http.postの引数headersに注目。準備しておいたAPIの認証ヘッダ_authHeadersが指定されていますね。

main.dart
//...(中略)...
import 'dart:convert';
import 'package:http/http.dart' as http;
import 'package:http/http.dart';
import 'photos_library_api/album.dart';
import 'photos_library_api/create_album_request.dart';
//...(中略)...
class _MyHomePageState extends State<MyHomePage> {
//...(中略)...
  Future<void> _handleMakeAlbum() async {
    return http
        .post(
          'https://photoslibrary.googleapis.com/v1/albums',
          body: jsonEncode(CreateAlbumRequest.fromTitle("New Album")),
          headers: await _authHeaders,
        )
        .then(
          (Response response) {
            if (response.statusCode != 200) {
              Crashlytics.instance.log('album create error. reasonPhrase=${response.reasonPhrase}');
            }
            var album = Album.fromJson(jsonDecode(response.body));
            Crashlytics.instance.log('album created. albumId=${album.id}.');
          },
        );
  }

なお、ここまでのコーディング内容では、次のライブラリが利用されています。

これらを pubspec.yamlに追加しましょう。

pubspec.yaml
dependencies:
  flutter:
    sdk: flutter
  firebase_core: ^0.4.4+3
  firebase_crashlytics: ^0.1.3+3
  firebase_auth: ^0.16.0
  google_sign_in: ^4.4.6
  json_annotation: ^3.0.1
  http: ^0.12.1

追加したら、packages getの実行を忘れずに。
ここまでで、ビルドが通るようになります。

新規アルバムを作成するボタンを配置する

サインイン後の画面に、新規アルバムを作成するボタンMake Albumを追加しましょう。

main.dart
class _MyHomePageState extends State<MyHomePage> {
//...(中略)...
  Widget _buildGoogleSignInBody() {
    if (_currentUser != null) {
      return Column(
        mainAxisAlignment: MainAxisAlignment.spaceAround,
        children: <Widget>[
          Card(
            color: Colors.lightBlueAccent,
            child: ListTile(
              leading: CircleAvatar(
                backgroundImage: NetworkImage(
                  _currentUser.photoUrl,
                ),
                radius: 30,
                backgroundColor: Colors.transparent,
              ),
              title: Text(_currentUser.displayName ?? ''),
              subtitle: Text(_currentUser.email ?? ''),
            ),
          ),
          const Text("Signed in successfully."),
          RaisedButton(
            child: const Text('SIGN OUT'),
            onPressed: _handleSignOut,
          ),
//...(追加ココカラ)...
          RaisedButton(
            child: const Text('Make album'),
            onPressed: _handleMakeAlbum,
          ),
//...(追加ココマデ)...
        ],
      );
    } else {
      return Column(
        mainAxisAlignment: MainAxisAlignment.spaceAround,
        children: <Widget>[
          const Text("You are not currently signed in."),
          RaisedButton(
            child: const Text('SIGN IN'),
            onPressed: () async{
              if (await _handleSignIn(await _googleSignIn.signIn())) {
                _handleGetContact();
              }
            }
          ),
        ],
      );
    }
  }

以上でコーディングは完了です。
アプリを実行し、任意のGoogleアカウントでサインインすると、次のようにMake Albumボタンが表示されます。

それをタップし、サインインしたGoogleアカウントのPhotosの「アルバム」のページを表示すると・・・

コメント 2020-06-25 224954.png

New Albumという名の空のアルバムが作成されていますね!

ちなみに、さらにMake Albumボタンをタップすると、New Albumという名の空のアルバムが増えていきます。
同じタイトルが付けられたアルバムですが、内部的にはAlbumIdが異なっているので、複数作られるというからくりです。

外部サービスへのアウトプットができると、いよいよアプリを作ってる!という感じになりますねっ(空のアルバム作っただけ・・・^^;

さて以上で、この記事における手順は終了ですが、この続きはCodeLabsの記事 Build a Photo Sharing app with Google Photos and Flutter - Codelabs を参考に進めることができます。

写真のアップロードとアルバムへの追加方法などが学習できるので、ぜひやってみてください。

さいごに

ここまでの連載?で、Codemagicを利用してビルドしたり、GoogleやFirebaseとの連携を手作業で設定したりすれば、Macがない環境でもFlutterでクロスプラットフォームアプリの開発ができることを紹介しました。

Windowsはある、iPhoneもある。

でもMacやAndroidは持っていない。

そんな私と同じ環境の方も、ご自身のiPhoneで動作するアプリ開発を!
ここまでの連載が、そんなチャレンジのお役に立てば、幸いです。

ありがとうございました。

kami_teru
SIを楽しむプログラマです。いろんなものを作るのが好き。
peoplesoftware
主にJavaやC#を使った受託開発や、BaaSなどのクラウドサービス、スマホアプリの自社開発を行っている会社です。※各記事の内容は個人の見解であり、所属する会社の公式見解ではありません。
http://www.pscsrv.co.jp/
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away