SQLの窓

2012年11月28日


Android(4.0.3) : WebView を使って Google にログインしてアクセストークンを取得する

ログイン画面は Google が提供する画面が表示されます。



そこでログインすると、登録済のアプリケーションの名前が表示されて、処理を許可するかどうかの確認画面が表示されて、許可すると登録済のリダイレクト URL が表示されます。ここで使用している Google API に登録したアプリケーションは、『Client ID for web applications』として、自分の API Console で作成や表示が可能です。

※ Calendar API と Google+ API を ON にしています。

クリップボードアクセスについて

エミュレータでログインする場合、ユーザーの入力を省略する為に、アプリケーションでユーザ文字列をクリップボードにセットしています。その際、ClipboardManager を使うわけですが、android.content.ClipboardManager を使っています。もうひとつ、android.text.ClipboardManager がありますが、これは将来的に廃止するので android.content.ClipboardManager を使うようにと指示されます。これは、Eclipse でのチェック機能でかなり明示されますし、android.content.ClipboardManager を使っても @SuppressLint("NewApi") を記述するようにガイドされました。

WebView の JavaScript 設定

Google 側の処理で、JavaScript が必要になります。もし、JavaScript が使用できない場合はメッセージが表示されて先へ進まなくなりますので、webView.getSettings().setJavaScriptEnabled(true); を実行してからログイン画面を表示しています。

アクセストークンを POST で取得

WevView のアドレスに『仮のアクセストークン』が設定されるので、そこから取り出して正式なアクセストークンを取得する為に『Client secret』をさらにセットして呼び出します。その結果が JSON なので、その中の access_token を GSON で取得するので、プロジェクトの lib フォルダには、GSON の jar を保存しておく必要があります。

Web に対するアクセスの為の AsyncTask

Android 4.0.3 でインターネットにアクセスしようとすると、たとえ SDK のメソッドであっても同期処理の場合は非同期処理として記述しなおす必要があります。その際のむ最も簡単な方法として、無名の AsyncTask のインスタンスを使用しています。

UI 処理は onPostExecute で

doInBackground は、別スレッドなので画面にアクセスはできません。UI スレッドである onPostExecute に必要なデータを return して処理する必要があります。( ジェネリック型の型パラメータの最後のパラメータの型で受け渡しの型を決定します )

※ 『ジェネリック型の型パラメータ』は Microsoft の C# の表現です / <String, Void, String>

※ 最初の型パラメータは doInBackground に対するもので、配列になります
※ 真ん中のパラメータは、doInBackground から publishProgress で投げた内容を配列で受け取ります
※ ここでは使用していないので Void にしています。

AsyncTask | Android Developers
// ****************************************************************
// アクティビティの初期処理
// ****************************************************************
@SuppressLint("NewApi")
@Override
public void onCreate(Bundle savedInstanceState) {
	super.onCreate(savedInstanceState);
	setContentView(R.layout.activity_main);

	// ************************************************************
	// WebView のイベントを処理する
	// ************************************************************
	WebView webView = (WebView)findViewById(R.id.webView1);
	webView.setWebViewClient( new WebViewClient() {
			// ページがユーザに対して表示された時のイベント
			public void onPageFinished (WebView view, String url) {
				Log.i("onPageFinished:", url);
			}
			
			public boolean shouldOverrideUrlLoading(WebView view, String url) {
				Log.i("shouldOverrideUrlLoading:", url);
				if (url.indexOf("https://plus.google.com/u/0/101280392108947207617/posts") == 0) {
					int cur = url.indexOf("=");
					String code = url.substring(cur + 1);
					Log.i("onPageFinished:", code);

					(new AsyncTask<String, Void, String>() {
						@Override
						protected String doInBackground(String... args) {
							String json_string = "";

							try {
								URL url = new URL("https://accounts.google.com/o/oauth2/token");
								// 接続オブジェクト
								HttpURLConnection http = (HttpURLConnection)url.openConnection();
								http.setConnectTimeout(30000);
								http.setReadTimeout(30000);
								http.setDoInput(true);
								http.setRequestMethod("POST");

								// ****************************************************
								// 送信部分
								// ****************************************************
								OutputStreamWriter osw =
									new OutputStreamWriter(http.getOutputStream());
								BufferedWriter bw = new BufferedWriter(osw);
								
								// 送信データ部分
								String client_id = "";
								String client_secret = "";
								String redirect_uri = "https://plus.google.com/u/0/101280392108947207617/posts";
								
								String body = "";
								body = "code=" + args[0];
								body += "&grant_type=authorization_code";
								body += "&redirect_uri=" + redirect_uri;
								body += "&client_id=" + client_id;
								body += "&client_secret=" + client_secret;
								bw.write( body );
		
								bw.close();
								osw.close();
										
								// ****************************************************
								// 受信部分
								// ****************************************************
								// UTF-8 でリーダーを作成
								InputStreamReader isr = new InputStreamReader(http.getInputStream(), "UTF-8");
								
								// 行単位で読み込む為の準備   
								BufferedReader br = new BufferedReader(isr);   
								String line_buffer;   
								// BufferedReader は、readLine が null を返すと読み込み終了   
								while ( null != (line_buffer = br.readLine() ) ) {   
									// コマンドプロンプトに表示   
									json_string += line_buffer;
								}
					 
								br.close();
								isr.close();
		
								http.disconnect();
							}
							catch (Exception e) {
								e.printStackTrace();
							}
							
							// アクセストークン
							return json_string;
						}
						@Override
						protected void onPostExecute(String result) {

							// パーサーを取得
							JsonParser jp = new JsonParser();
							// 文字列をパース
							JsonElement je = jp.parse(result);

							// key と value を取得する為に、JsonObject から、entrySet メソッドを実行
							Set<Map.Entry<String, JsonElement>> entrySet = je.getAsJsonObject().entrySet();

							// イテレータを取得
							Iterator<Map.Entry<String, JsonElement>> it = entrySet.iterator();

							// 一覧表示
							while(it.hasNext())
							{
								Map.Entry<String, JsonElement> entry = it.next();
								
								String key = entry.getKey();
								JsonElement value = entry.getValue();
								
								if ( key.equals("access_token") ) {
									EditText editText = (EditText)findViewById(R.id.editText1);
									editText.setText(value.getAsString());
									break;
								}
							}			
						}
					}).execute(code);
					
				}
				// true を指定すると、リダイレクト処理をしなくなる
				// false でリダイレクトの場合、ここが二度よばれてから onPageFinished が呼ばれる
			    return false;
			}
		}
	);		

	String client_id = "";
	String loginUrl = "https://accounts.google.com/o/oauth2/auth";
	String type = "code";
	String redirect_uri = "https://plus.google.com/u/0/101280392108947207617/posts";
	String scope = "https://www.googleapis.com/auth/calendar+https://www.googleapis.com/auth/calendar.readonly+https://www.googleapis.com/auth/plus.me";

	String access_url = "";

	access_url = loginUrl;
	access_url += "?response_type=" + type;
	access_url += "&client_id=" + client_id;
	access_url += "&redirect_uri=" + redirect_uri;
	access_url += "&scope=" + scope;

	// ログイン画面
	webView.getSettings().setJavaScriptEnabled(true);
	webView.loadUrl(access_url);
	
	ClipboardManager clipboardManager = (ClipboardManager)this.getSystemService(CLIPBOARD_SERVICE);
	
	//クリップボードに格納するItemを作成
	ClipData.Item item = new ClipData.Item("ユーザID");

	// データの種類
	String[] mimeType = new String[1];
	mimeType[0] = ClipDescription.MIMETYPE_TEXT_PLAIN;
	 
	//クリップボードに格納するClipDataオブジェクトの作成
	ClipData cd = new ClipData(new ClipDescription("text_data", mimeType), item);
	
	clipboardManager.setPrimaryClip(cd);

}


タグ:android java
【Androidの最新記事】
posted by lightbox at 2012-11-28 17:14 | Android | このブログの読者になる | 更新情報をチェックする
container 終わり



フリーフォントで簡単ロゴ作成
フリーフォントでボタン素材作成
フリーフォントで吹き出し画像作成
フリーフォントではんこ画像作成
ほぼ自由に利用できるフリーフォント
フリーフォントの書体見本とサンプル
画像を大きく見る為のウインドウを開くボタンの作成

CSS ドロップシャドウの参考デモ
イラストAC
ぱくたそ
写真素材 足成
フリーフォント一覧
utf8 文字ツール
右サイド 終わり
base 終わり