GoogleのアカウントにログオンしてAuthCodeを取得する〜スケジュール管理ソフトをS!アプリで作ってみよう(その28)

前回は、プロキシになるサーバ側のコードを作成した。

今回は、このサーバを呼び出す部分を作成する。こんな感じでAuthCodeを取得する。


package jp.dip.ettem.scheduler;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;

import javax.microedition.io.*;

/**
* Google Calenderと連携するためのクラス
*/
public class GCal implements GCalConstants {

/**
* Client Loginのための、AuthCodeを返します。
*
* @param eMail GoogleのログインのためのE-Mailアドレス
* @param passwd Googleのアカウントのパスワード
* @return
*/
static String getAuthCode(String eMail, String passwd) {
String authCode = new String();
HttpConnection connection = null;
OutputStream oStream = null;
InputStream iStream = null;

try {

// 接続先は、Googleではなく、私のサーバを指定。(しかもHTTPで接続)
// Googleが使っているSSL認証局に、Softbank Mobileが対応したら変更する予定。
connection = (HttpConnection) Connector.open(AUTH_URL);

connection.setRequestMethod(HttpConnection.POST);
byte[] postData =("Email=" + eMail + "&Passwd=" + passwd
+ "&source=jp.dip.ettem-scheduler-1&service=cl\r\n").getBytes();
connection.setRequestProperty("Content-Length", String.valueOf(postData.length));
connection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");

oStream = connection.openOutputStream();
oStream.write(postData);
oStream.flush();

iStream = connection.openInputStream();
int len = (int) connection.getLength();
if (len > 0) {
int actual = 0;
int bytesread = 0 ;
byte[] data = new byte[len];
while ((bytesread != len) && (actual != -1)) {
actual = iStream.read(data, bytesread, len - bytesread);
bytesread += actual;
}
authCode = new String(data);
}

authCode = authCode.substring(authCode.indexOf("Auth=") + "Auth=".length(),
authCode.length() - 2);
} catch (IOException e) {
authCode = e.toString();
} catch (Exception e) {
authCode = e.toString();
} catch (Error e) {
authCode = e.toString();
}

return authCode;
}
}

上記のコードのGCalConstants.AUTH_URLは今のところ公開しない予定。:-P

上記のクラスは以下の様に使う


package jp.dip.ettem.scheduler;

import javax.microedition.lcdui.Command;
import javax.microedition.lcdui.CommandListener;
import javax.microedition.lcdui.Display;
import javax.microedition.lcdui.Displayable;
import javax.microedition.lcdui.Form;
import javax.microedition.lcdui.Item;
import javax.microedition.lcdui.ItemStateListener;
import javax.microedition.lcdui.TextField;

public class GCalAuthForm extends Form implements CommandListener, ItemStateListener {
private Display display;
private Displayable callerDisplayable;

private TextField account;
private final int MAIL_ADDR_LEN = 256; // メールアドレスの長さ(TODO:RFCを調べる)
private TextField passwd;
private final int PASSWD_LEN = 64; // パスワードの長さ(TODO:Googleのアカウントを調べる)

private GCalAccount gCalAccount;

private Command okCommand;

public GCalAuthForm(Display display, Displayable displayable, GCalAccount gCalAccount) {
super("GCal Account");
this.display = display;
this.callerDisplayable = displayable;
this.gCalAccount = gCalAccount;

okCommand = new Command("OK", Command.OK, 1);
addCommand(okCommand);
setCommandListener(this);
setItemStateListener(this);

this.account = new TextField("Mail", gCalAccount.account, MAIL_ADDR_LEN, TextField.ANY);
append(this.account);

this.passwd = new TextField("Password", gCalAccount.passwd, PASSWD_LEN, TextField.PASSWORD);
append(this.passwd);
}

public void commandAction(Command command, Displayable displayable) {
// OKボタンが押されたら、呼び出しに戻る
if (command == okCommand) {

// テストコード(取り敢えず、取得したAuthCodeをaccountに格納している。)
Thread authThread = new Thread () {
public void run () {
gCalAccount.account = GCal.getAuthCode(gCalAccount.account, gCalAccount.passwd);
}
};

authThread.start();
display.setCurrent(callerDisplayable);
}
}

public void itemStateChanged(Item changedItem) {
if (changedItem == account) {
gCalAccount.account = account.getString();
} else if (changedItem == passwd) {
gCalAccount.passwd = passwd.getString();
}
}

}


package jp.dip.ettem.scheduler;

import java.util.Calendar;
import javax.microedition.lcdui.*;

/**
* メインの画面
* カレンダー、予定を表示する。
* (ToDoも表示する予定)
*/
public class MainCanvas extends Canvas {
private Display display;
private Calendar now; // 今日の日付
private Calendar dateToDisplay; // 選択された日付
private MonthlyCalendar calendar; // 月単位のカレンダー
private EventView eventView; // 予定表示部

// テストコード
private GCalAccount account = new GCalAccount();


/**
* メインの画面
* @param display 表示するDisplay。
*/
public MainCanvas(Display display) {
this.display = display;
now = Calendar.getInstance();
dateToDisplay = Calendar.getInstance();
dateToDisplay.setTime(now.getTime());

// カレンダーを上部に表示する。
calendar = new MonthlyCalendar(this, 0, 0, getWidth(), 0, dateToDisplay);

// 予定を下部に表示する。
eventView = new EventView(this, 0, calendar.height + 1, getWidth(), 0, dateToDisplay);
}

protected void paint(Graphics graphics) {
calendar.paint(graphics);
eventView.paint(graphics);
}

/**
* メインの画面でのキーイベントを処理する。
* @param keyCode 押されたキーのkeyCode。
*/
protected void keyPressed(int keyCode) {
int action = getGameAction(keyCode);

if (keyCode == KEY_STAR
|| keyCode == KEY_POUND) {
// KEY_START、KEY_POUNDはGameActionが割当てられていた。
// カレンダーの表示画面単位での移動。
dateToDisplay.setTime(calendar.getMovedDateByKeyCode(keyCode).getTime());
} else if (action == FIRE){
// 予定の入力画面へ移動する。
EventForm eventForm = new EventForm(display, this,
Events.getNewEvent(dateToDisplay.getTime()));
display.setCurrent(eventForm);
} else if (keyCode == KEY_NUM0) {

// テストコード(AuthCodeの取得)
GCalAuthForm authForm = new GCalAuthForm(display, this, account);
display.setCurrent(authForm);

} else {
// 選択日の移動
dateToDisplay.setTime(calendar.getMovedDateByAction(action).getTime());
}

calendar.setDate(dateToDisplay);
eventView.setDate(dateToDisplay);
repaint(); // paintも呼んでいる。
}
}