Android
googleapi
NCMB

ニフクラ mobile backend のAndroid SDKでGoogle認証を試す - 開発編

ニフクラ Mobile Backend (NCMB) エバンジェリストの小山(koyhoge)です。

前回の「準備編」を受けて、実際に NCMB と連携して Google 認証を行うアプリを作っていきます。

今回の内容は、基本的に以下のガイドにしたがって進めていきます。

SDKガイド (Android): SNS連携

Android Studio でプロジェクトを作成

Android Studio で新しくプロジェクトを作ります。準備編で決めたようにパッケージ名は「org.koyhoge.ncmbgauth」とすでに決まっているので、「Application name」は「NcmbGauth」にします。

ncmbgauth_2_01.png

「Add an activity to Mobile」で指定するアプリケーションの雛形は「Blank Activity」で良いでしょう。

ncmbgauth_2_02.png

あとは通常通りにプロジェクトを作ります。

プロジェクトの設定

NCMB Android SDK のインストール

まず NCMB Android SDK である NCMB.jar を取得します。NCMB のクイックスタートのページの中ごろにある「Android SDKダウンロードはこちら」というボタンから、NCMB_latest.zip をダウンロードして下さい。

クイックスタート (Android)

NCMB_latest.zip を展開すると NCMB.jar ファイルが現れますので、それを Android Studio で作成したプロジェクトディレクトリの app/libs にコピーします。

Google Play Service をアプリに追加

以下の説明に従い、Google Play Service 用のライブラリをプロジェクトに追加します。

Setting Up Google Play Services

プロジェクトの build.gradle の dependencies セクションに以下を加えます。

build.gradle
dependencies {
// (略)
    compile 'com.google.android.gms:play-services:7.5.0'
    compile 'com.google.android.gms:play-services-identity:7.5.0'
// (略)
}

アプリのネットワークアクセスを許可

プロジェクトの AndroidManifest.xml の の直前に以下を追加して、アプリにネットへのアクセスを許可します。

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

google-services.jsonを配置

準備編でダウンロードした google-services.json をプロジェクトディレクトリの app にコピーします。

ボタンとメッセージ表示枠を配置

次にUI部品を配置します。認証を開始する Button と結果を表示するTextView を1つずつ配置しましょう。

activity_main.xml を RelativeLayout から LinearLayout に変更して、その中に Button と TextView を作ります。最終的には以下のようにになります。

activity_main.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent"
    android:layout_height="match_parent" android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    android:orientation="vertical"
    android:paddingBottom="@dimen/activity_vertical_margin" tools:context=".MainActivity">

    <Button
        android:id="@+id/btn_logingauth"
        android:text="Login with Google"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />

    <TextView
        android:id="@+id/tv_resultmessage"
        android:text="@string/hello_world"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />

</LinearLayout>

NCMB SDKの初期化。

ここから先は MainActivity.java にある MainActivity クラスを編集していきます。まずは onCreate() メソッドの中で、SDK の初期化をしましょう。NCMB.initialize() メソッドで SDK 初期化します。第2,3 引数の文字列は NCMB のアプリに紐付いたアプリケーションキーとクライアントキーです。

またそのあとで NCMBGoogleUtils.initialize(this) で Google 認証関係のライブラリの初期化を行います。

MainAcivity.java
        NCMB.initialize(this,
                "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", // APP KEY
                "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"); // CLIENT KEY
        NCMBGoogleUtils.initialize(this);

イベントハンドラをオーバーライド

以下の2つのイベントハンドラをオーバーライドします。
Google 認証ダイアログから復帰した処理を記述します。

    @Override
    protected void onActivityResult(int requestCode, int responseCode, Intent intent){
        NCMBGoogleUtils.onActivityResult(requestCode, responseCode, intent);
    }

Google Play Service とのコネクションを閉じるための処理を記述します。

    @Override
    public void onStop(){
        super.onStop();
        // GooglePlayServicesとの接続を切断する
        NCMBGoogleUtils.disconnectGooglePlayServices();
    }

Google認証の処理本体を記述

Button が押されたら Google 認証を実行して、その結果得られたユーザ名を TextView に表示してみましょう。該当部分は以下のようになります。

        Button buttonLoginGauth = (Button)findViewById(R.id.btn_logingauth);
        buttonLoginGauth.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                NCMBGoogleUtils.loginWithGoogleAccount(new LogInCallback(){
                    @Override
                    public void done(NCMBUser user, NCMBException e) {
                        if(e == null){
                            if(user.isNew()){
                                Log.d("NCMBGauth", "Googleアカウントで登録");
                            } else {
                                Log.d("NCMBGauth", "Googleアカウントでログイン" );
                            }
                            Log.d("NCMBGauth", "Username: " + user.getUsername());
                            Log.d("NCMBGauth", "Email: " + user.getEmail());

                            String message = "Username: " + user.getUsername();
                            TextView tv = (TextView)findViewById(R.id.tv_resultmessage);
                            tv.setText(message);
                        } else {
                            Log.d( "NCMBGauth", "ログイン失敗" );
                        }
                    }
                });
            }
        });

最終的な MainActivity.java は以下となります。

MainActivity.java
package org.koyhoge.ncmbgauth;

import android.content.Intent;
import android.support.v7.app.ActionBarActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;

import com.nifty.cloud.mb.LogInCallback;
import com.nifty.cloud.mb.NCMB;
import com.nifty.cloud.mb.NCMBException;
import com.nifty.cloud.mb.NCMBGoogleUtils;
import com.nifty.cloud.mb.NCMBUser;


public class MainActivity extends ActionBarActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        Button buttonLoginGauth = (Button)findViewById(R.id.btn_logingauth);
        buttonLoginGauth.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                NCMBGoogleUtils.loginWithGoogleAccount(new LogInCallback(){
                    @Override
                    public void done(NCMBUser user, NCMBException e) {
                        if(e == null){
                            if(user.isNew()){
                                Log.d("NCMBGauth", "Googleアカウントで登録");
                            } else {
                                Log.d("NCMBGauth", "Googleアカウントでログイン" );
                            }
                            Log.d("NCMBGauth", "Username: " + user.getUsername());
                            Log.d("NCMBGauth", "Email: " + user.getEmail());

                            String message = "Username: " + user.getUsername();
                            TextView tv = (TextView)findViewById(R.id.tv_resultmessage);
                            tv.setText(message);
                        } else {
                            Log.d( "NCMBGauth", "ログイン失敗" );
                        }
                    }
                });
            }
        });

        NCMB.initialize(this,
                "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", // APP KEY
                "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"); // CLIENT KEY
        NCMBGoogleUtils.initialize(this);
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.menu_main, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        // Handle action bar item clicks here. The action bar will
        // automatically handle clicks on the Home/Up button, so long
        // as you specify a parent activity in AndroidManifest.xml.
        int id = item.getItemId();

        //noinspection SimplifiableIfStatement
        if (id == R.id.action_settings) {
            return true;
        }

        return super.onOptionsItemSelected(item);
    }

    // added for NCMB Google auth

    @Override
    protected void onActivityResult(int requestCode, int responseCode, Intent intent){
        NCMBGoogleUtils.onActivityResult(requestCode, responseCode, intent);
    }

    @Override
    public void onStop(){
        super.onStop();
        // GooglePlayServicesとの接続を切断する
        NCMBGoogleUtils.disconnectGooglePlayServices();
    }
}

実際に実行してみる

それでは早速、実際にビルドして実行してみましょう。アプリを実行すると以下の画面になります。

ncmbgauth_2_03c.png

「LOGIN WITH GOOGLE」ボタンを押すと、初回はGoogleアカウントに連携したNCMBのユーザアカウントが存在しないので、どの Google アカウントを使用するかというダイアログが表示されます。

ncmbgauth_2_04b.png

ここで自分のアカウントを選択して「OK」を押すと、問題が起きなければ以下のように処理が進みます。

  • Google アカウントが認証される
  • それに連携した NCMB ユーザアカウントが作成される
  • NCMB ユーザアカウント情報がアプリに返される
  • アプリは NCMB ユーザアカウント情報のアカウント名を TextView に表示する

結果として以下のようなメッセージが表示されます。「yGcjH5upSP」という文字列が、私の Google アカウントに紐付いた、このアプリの NCMB 的なユーザ名になります。

ncmbgauth_2_05b.png

最後に

いかがでしたでしょうか。特に前準備の部分がちょっと面倒だったかもしれません。Google 認証に限らず、Twitter や Facebook を用いた SNS 認証は、うまく使うことでユーザ登録の精神的な負担を減らしてくれます。コードの記述自体は、今回の例で見たようにかなり簡単に機能を使うことができますので、NCMB をすでにお使いの方や使用を検討している方は、SNS 認証機能をアプリに追加することもご検討いただいく参考になれば幸いです。