スポンサーサイト

上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。

Android: Google APIの認証

Googleのサービス(GoogleCalendarとかGoogleTasksとか)を使用する場合、GoogleAPIというのを使って操作すると便利だそうです。が、個人的には、とっても複雑。。。
ということで、認証部分をまとめました。カレンダーの追加登録とかTasksのリスト取得とか、Googleサービスを操作する場合、トークンという認証キーを使うのですが、そのトークンを取得するためのプログラムです。
「携帯(Android)に登録されているGoogleアカウントを利用」するケースと、「べたにID/パスワードを直打ち」するケースの2つ載せてます。

私は、頭が古い分、ベタな方が好きですね。「文書はパソコンで見るより紙にプリントして見たい」という人間ですから。


【追記:2012/4/30】
ベタじゃない方の件です。
よくサンプルとしてインターネットに載ってるやり方だと、token発行処理をコールバックルーチンで呼び出す=別処理に投げて、コールバックルーチンを呼び出す元となるところは処理終了という寸法でした。すなわち、tokenを戻り値とすることができない。。。

なので、
  • トークンを戻す(戻り値とする)関数を宣言
  • もし認証前だったらな、コールバックルーチンで別処理を呼ぶ(その処理自体は空白を戻す)
という2段階の関数としました。

【---追記終わり---】

ちなみに、GoogleAPIをいろいろググってみると「各種JARファイルをインストールする必要あり」みたいな記事が出ていますが、以下のプロジェクトでは特にそれをしていません。
以下のプロジェクト以外でいろいろとあーだこーだやって、“Eclipseにデフォルトで登録”みたいなことをされている可能性もあるのですが、よくわかりません。。。でも、以下のプロジェクトでは、特に何もしていないです。
なお、両方とも、注意点があります。これを知っとかないと、うまくいきません。自分は、かなりはまりました。。。
★☆ 注意点! ☆★
・ターゲットを、Android2.2以上(Platformが8以上)でプロジェクト作成。
・TargetNameを、「Google APIs(Platform=8以上)」でプロジェクト作成。「Android 2.2」とかだと、失敗します。
・ネット接続とかGoogleAccountを利用したりするので、Manifestにパーミッションを書き入れる
詳細は以下をご参考。
■■■■■■■■■■■■■■■■■■■■■■■
 ベタにID/Passwordを直打ちしてトークン取得
■■■■■■■■■■■■■■■■■■■■■■■
ID/PWをベタに入力して、HTTPのPOST接続でおこないます。
ベタな分、パーミッションは最低限(INTERNETだけ)です。
また、携帯に登録されているGoogleアカウントは使用しないので、Android2.2以下でも大丈夫だと思います。たぶん。。
-----------------------------------------------
1.プロジェクトの新規作成
-----------------------------------------------
Eclipseで、プロジェクトを新規作成します。
ちなみに、私は以下の設定で作りました。
・Target Name:Google APIs(Platform=8)
・アプリケーション名:TestGoogleAuth1
・パッケージ名:com.fxscore.testgoogleauth1
・Activity名:TestGoogleAuth1Activity
・Minimum SDK:8
-----------------------------------------------
2.マニュフェストにパーミッションを追加
-----------------------------------------------
プロジェクト名の直下にある「AndroidManifest.xml」に、以下を追加してください。
※ 貼り付け場所は、「<uses-sdk android:minSdkVersion="8" />」の下くらいで。
    <uses-permission android:name="android.permission.INTERNET"/>
-----------------------------------------------
3.プログラム修正
-----------------------------------------------
OnCreateの中に、POST接続部分を追記します。
OnCreate全体は、以下のとおりです。

※ Email(ID)とパスワードは自分のものに書き換えてください!!!


  ↓OnCreateの中身
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
    
        // POST接続でTOKEN取得
        try
        {
            HttpPost method = new HttpPost( "https://www.google.com/accounts/ClientLogin" );
            
            // パラメータを生成
            ArrayList<NameValuePair> params = new ArrayList<NameValuePair>();
            params.add(new BasicNameValuePair("Email", "xxxxx@gmail.com"));
            params.add(new BasicNameValuePair("Passwd", "xxxxxxxx"));
            params.add(new BasicNameValuePair("service", "cl")); //カレンダー
            // パラメータを設定
            method.setHeader( "Content-Type", "application/x-www-form-urlencoded" );
            method.setEntity(new UrlEncodedFormEntity(params, "UTF-8"));
            
            // 実行
            DefaultHttpClient client = new DefaultHttpClient();
            HttpResponse httpResponse = client.execute(method);
            
            // 成功したら、トークン取得
            int status = httpResponse.getStatusLine().getStatusCode();
            if ( status == HttpStatus.SC_OK ) {
                String entity = EntityUtils.toString(httpResponse.getEntity()); //vbでいうresponseText
                //responseTextからベタにTokenを取得
                String token = entity.substring(entity.indexOf("Auth=")+5);
                token = token.substring(0,token.length()-1) ; //最後の改行文字を除去
                Toast.makeText(TestGoogleAuth1Activity.this, "Token=" + token, Toast.LENGTH_LONG).show();
                Log.d("TOKEN", token); //一応ログにも出してます
            } else {
                Log.d("ERR", "Status was not OK..."+String.valueOf(status));
            }
        }
        catch ( Exception e )
        {
            Log.d("ERR", "ERROR!"+e.toString());
        }
    }
以上でトークンが取得できるはずです。
■■■■■■■■■■■■■■■■■■■■■■■
 Google携帯のIDを利用
■■■■■■■■■■■■■■■■■■■■■■■

Google APIを使います。
ソースコードにID/PWを入力する部分を作る必要はありませんが、その分少々面倒かも。。
-----------------------------------------------
0.エミュレーターにGoogleアカウント登録
-----------------------------------------------
携帯に登録されているGoogleアカウントを使うということは、エミュレーターでテストする場合、<b>Googleアカウントを事前に登録</b>しておく必要があります!!
これは、携帯で操作するのと同じく、設定(Settings)の「アカウントと同期」をクリックして登録するのですが、この作業をする時、<b>Android2.2以上</b>じゃないとだめなんです。。
-----------------------------------------------
1.プロジェクトの新規作成
-----------------------------------------------
Eclipseで、プロジェクトを新規作成します。


ちなみに、私は以下の設定で作りました。
  • Target Name:Google APIs(Platform=8)
  • アプリケーション名:TestGoogleAuth2
  • パッケージ名:com.fxscore.testgoogleauth2
  • Activity名:TestGoogleAuth2Activity
  • Minimum SDK:8
-----------------------------------------------
2.マニュフェストにパーミッションを追加
-----------------------------------------------
プロジェクト名の直下にある「AndroidManifest.xml」に、以下を追加してください。
携帯に登録されてあるGoogleアカウントを利用するため、INTERENET以外のパーミッションも必要です。
    <uses-permission android:name="android.permission.GET_ACCOUNTS" />
    <uses-permission android:name="android.permission.USE_CREDENTIALS"/>
    <uses-permission android:name="android.permission.INTERNET"/>
-----------------------------------------------
3.プログラム修正1:Googleアカウントの取得
-----------------------------------------------
今からのプログラム修正は、OnCreateの中にどんどん書き込んでいきます。
まず、Googleアカウントの取得部分です。


    // Googleアカウントの検索
    AccountManager mAccountManager = null;
    Account[] accounts = null;
    if (mAccountManager == null) mAccountManager = AccountManager.get(this);
    accounts = mAccountManager.getAccountsByType("com.google");
    for (Account ac : accounts) Log.d("G_Acc", ac.toString());
これだけです。一応、for文で取得されたアカウント名をログに書き出してます。

-----------------------------------------------
3.プログラム修正2:認証(OnCreateに追記)
-----------------------------------------------

以下の1文を、上のプログラムの下に書き足してください。

ちなみに、1つ目の変数はアカウント名(上のプログラムで取得されたGoogleアカウントの、1つ目(accounts[0])を使ってます)、2つ目は認証の範囲(cl(カレンダーのこと))です。
GetAuthTokenCallbackを呼び出しますが、まだ定義していないので、この時点ではGetAuthTokenCallbackに赤波線が付きます。


// アカウントタイプの一覧
// "cl", // Google Calendar
// "android", 
// "ah", // Google AppEngine 
// "mail", // Gmail
// "reader", // Google Reader
// "talk", // Gtalk
// "youtube", // YouTube 
        AccountManagerFuture<Bundle> future = mAccountManager.getAuthToken (accounts[0], "cl", false, null, null);
        String token = null ;
        try{
            Bundle bundle = future.getResult(); //認証がまだのときはここで例外発生
            token = bundle.getString(AccountManager.KEY_AUTHTOKEN);
            Log.d("Token", token);
  Toast.makeText(this, "token=[" + token + "]", Toast.LENGTH_LONG).show();
        }catch(Exception e){
        // 認証がまだのときは、認証画面を出すよう呼びかけて、ここからは抜ける
mAccountManager.getAuthToken(accounts[0], "cl", false, new GetAuthTokenCallback(), null) ;
        }


-----------------------------------------------
3.プログラム修正2:認証(GetAuthTokenCallback)
-----------------------------------------------
OnCreate文の外に、以下の関数を追記してください。
これで実装はすべて完了ですが、注意点があります。
一発目に実行したら、まずは「このアプリケーションにGoogleアカウントを使わせてもいいか?」という確認画面がでます。
ここで“許可(Allow)”をしてあげたのち、一旦終了してください。
そして、再度このアプリを起動したら、トークンの取得ができるようになります。
    private class GetAuthTokenCallback implements AccountManagerCallback<Bundle> {
        @Override
        public void run(AccountManagerFuture<Bundle> arg0) {
            Bundle bundle;
            try {
                bundle = arg0.getResult();
                Intent intent = (Intent) bundle.get(AccountManager.KEY_INTENT);
                if (intent != null) {
                    Toast.makeText(TestGoogleAuth2Activity.this, "Click 'Allow' and restart this App", Toast.LENGTH_LONG).show();
                    startActivity(intent); //許可画面を出す
                } else {
                    Log.d("Token", bundle.getString(AccountManager.KEY_AUTHTOKEN));
                }
            } catch (OperationCanceledException e) {
                e.printStackTrace();
            } catch (AuthenticatorException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }
        } 
    }



以上です。


■■■■■■■■■■■■■■■■■■■■■■■
 Sample Program : ベタな方
■■■■■■■■■■■■■■■■■■■■■■■
package com.fxscore.testgoogleauth1;
import java.util.ArrayList;
import org.apache.http.HttpResponse;
import org.apache.http.HttpStatus;
import org.apache.http.NameValuePair;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;
import android.app.Activity;
import android.os.Bundle;
import android.util.Log;
import android.widget.Toast;
public class TestGoogleAuth1Activity extends Activity {
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
    
        // POST接続でTOKEN取得
        try
        {
            HttpPost method = new HttpPost( "https://www.google.com/accounts/ClientLogin" );
            
            // パラメータを生成
            ArrayList<NameValuePair> params = new ArrayList<NameValuePair>();
            params.add(new BasicNameValuePair("Email", "shin.oomura@gmail.com"));
            params.add(new BasicNameValuePair("Passwd", "shin9232"));
            params.add(new BasicNameValuePair("service", "cl")); //カレンダー
            // パラメータを設定
            method.setHeader( "Content-Type", "application/x-www-form-urlencoded" );
            method.setEntity(new UrlEncodedFormEntity(params, "UTF-8"));
            
            // 実行
            DefaultHttpClient client = new DefaultHttpClient();
            HttpResponse httpResponse = client.execute(method);
            
            // 成功したら、トークン取得
            int status = httpResponse.getStatusLine().getStatusCode();
            if ( status == HttpStatus.SC_OK ) {
                String entity = EntityUtils.toString(httpResponse.getEntity()); //vbでいうresponseText
                //responseTextからベタにTokenを取得
                String token = entity.substring(entity.indexOf("Auth=")+5);
                token = token.substring(0,token.length()-1) ; //最後の改行文字を除去
                Toast.makeText(TestGoogleAuth1Activity.this, "Token=" + token, Toast.LENGTH_LONG).show();
                Log.d("TOKEN", token); //一応ログにも出してます
            } else {
                Log.d("ERR", "Status was not OK..."+String.valueOf(status));
            }
        }
        catch ( Exception e )
        {
            Log.d("ERR", "ERROR!"+e.toString());
        }
    }
}
■■■■■■■■■■■■■■■■■■■■■■■
 Sample Program : Googleアカウントを使う方
■■■■■■■■■■■■■■■■■■■■■■■
package com.fxscore.testgoogleauth2;
import java.io.IOException;
import android.accounts.Account;
import android.accounts.AccountManager;
import android.accounts.AccountManagerCallback;
import android.accounts.AccountManagerFuture;
import android.accounts.AuthenticatorException;
import android.accounts.OperationCanceledException;
import android.app.Activity;
import android.os.Bundle;
import android.util.Log;
import android.widget.Toast;
import android.content.Intent;
public class TestGoogleAuth2Activity extends Activity {
    /** Called when the activity is first created. */
    
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        
        // Googleアカウントの検索
        AccountManager mAccountManager = null;
        Account[] accounts = null;
        if (mAccountManager == null) mAccountManager = AccountManager.get(this);
        accounts = mAccountManager.getAccountsByType("com.google");
        for (Account ac : accounts) Log.d("G_Acc", ac.toString());

        AccountManagerFuture<Bundle> future = mAccountManager.getAuthToken (accounts[0], "cl", false, null, null);
        String token = null ;
        try{
            Bundle bundle = future.getResult(); //認証がまだのときはここで例外発生
token = bundle.getString(AccountManager.KEY_AUTHTOKEN);
Log.d("Token", token);
Toast.makeText(this, "token=[" + token + "]", Toast.LENGTH_LONG).show();
        }catch(Exception e){
        // 認証がまだのときは、認証画面を出すよう呼びかけて、ここからは抜ける
mAccountManager.getAuthToken(accounts[0], "cl", false, new GetAuthTokenCallback(), null) ;
        }
    }
    
    
    private class GetAuthTokenCallback implements AccountManagerCallback<Bundle> {
        @Override
        public void run(AccountManagerFuture<Bundle> arg0) {
            Bundle bundle;
            try {
                bundle = arg0.getResult();
                Intent intent = (Intent) bundle.get(AccountManager.KEY_INTENT);
                if (intent != null) {
                    Toast.makeText(TestGoogleAuth2Activity.this, "Click 'Allow' and restart this App", Toast.LENGTH_LONG).show();
                    startActivity(intent); //許可画面を出す
                } else {
                    Log.d("Token", bundle.getString(AccountManager.KEY_AUTHTOKEN));
                }
            } catch (OperationCanceledException e) {
                e.printStackTrace();
            } catch (AuthenticatorException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }
        } 
    }
}
スポンサーサイト

トラックバック

コメント

コメントを残す

Secret



上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。