duyojiぶろぐ

技術系ときどき日常系

MixiからAccesstokenを取得して投稿するまでのクラス作ってみた

Mixi SDKを使わなかった理由

mixiSDKはmixi公式アプリがインストールされていること条件で
使えるものだったのでmixi公式アプリをインストールしていない端末
にも対応するため

Mixiクラス

Androidmixiと連携して投稿できるクラスを書いた。
認証画面に行く時ブラウザに飛ばさずダイアログとWebViewを使って
認証画面を開いてコールバックが呼ばれた時にダイアログ+WebViewを
閉じる仕様になっている。

コンストラクタには,ContextとConsumer Key, Consumer Secretを入れる。

ソースコードは以下の通り。

public class Mixi {
	public static boolean loginStatus = false;
	public static final String CALLBACK_URL = "それぞれ設定したコールバックURL";
	public static final String API_URL = "https://mixi.jp/connect_authorize.pl";
	public static final String POST_CODE_URL = "https://secure.mixi-platform.com/2/token";

	private String consumerKey = "";
	private String consumerSecret = "";
	public static final String SCOPE = "w_voice";

	private String authorizeUrl;
	private String accessToken = "";



	static final FrameLayout.LayoutParams FILL = new FrameLayout.LayoutParams(
			ViewGroup.LayoutParams.FILL_PARENT,
			ViewGroup.LayoutParams.FILL_PARENT);

	private Dialog dialog;
	private WebView webView;
	private Context context;

	Mixi(Context _context, String _consumerKey, String _consumerSecret) {
		this.context = _context;
		this.consumerKey = _consumerKey;
		this.consumerSecret = _consumerSecret;
		init();
	}

	private void init() {
		setDialogWebView();
		authorizeUrl = API_URL + "?" + "client_id=" + consumerKey
				+ "&response_type=code" + "&scope=" + SCOPE;
	}

	public String callbackCode(String target) {
		String regex = "code=(.*)";
		Pattern pattern = Pattern.compile(regex);
		Matcher matcher = pattern.matcher(target);
		if (matcher.find()) {
			return matcher.group(1);
		} else {
			return "codeはnull";
		}
	}

	public String parseAccessToken(String target) {
		String regex = "access_token\":\"(.*)\",\"scope";

		Pattern pattern = Pattern.compile(regex);
		Matcher matcher = pattern.matcher(target);
		if (matcher.find()) {
			Log.d("TAG", "accesstoken : " + matcher.group(1));

			return matcher.group(1);
		} else {
			return "codeはnull";
		}
	}

	public String getAccessToken() {
		return this.accessToken;
	}

	public void postVoice() {
		HttpClient objHttp = new DefaultHttpClient();
		String voiceAPI = "http://api.mixi-platform.com/2/voice/statuses?oauth_token="
				+ getAccessToken();

		try {
			HttpPost objPost = new HttpPost(voiceAPI);
			List<NameValuePair> objValuePairs = new ArrayList<NameValuePair>();

			// 投稿内容
			objValuePairs.add(new BasicNameValuePair("status", "voice test"));

			objPost.setEntity(new UrlEncodedFormEntity(objValuePairs, "UTF-8"));
			objHttp.execute(objPost);
		} catch (IOException e) {
			Log.e("TAG", "エラー");
		}
	}

	private String postJsonData(String sUrl, String code) {
		HttpClient objHttp = new DefaultHttpClient();
		String sReturn = "";
		try {
			HttpPost objPost = new HttpPost(sUrl);
			List<NameValuePair> objValuePairs = new ArrayList<NameValuePair>();

			objValuePairs.add(new BasicNameValuePair("grant_type",
					"authorization_code"));
			objValuePairs.add(new BasicNameValuePair("client_id", consumerKey));
			objValuePairs.add(new BasicNameValuePair("client_secret",
					consumerSecret));
			objValuePairs.add(new BasicNameValuePair("code", code));
			objValuePairs.add(new BasicNameValuePair("redirect_uri",
					CALLBACK_URL));

			objPost.setEntity(new UrlEncodedFormEntity(objValuePairs, "UTF-8"));

			HttpResponse objResponse = objHttp.execute(objPost);
			if (objResponse.getStatusLine().getStatusCode() < 400) {
				InputStream objStream = objResponse.getEntity().getContent();
				InputStreamReader objReader = new InputStreamReader(objStream);
				BufferedReader objBuf = new BufferedReader(objReader);
				StringBuilder objJson = new StringBuilder();
				String sLine;
				while ((sLine = objBuf.readLine()) != null) {
					objJson.append(sLine);
				}

				sReturn = objJson.toString();

				Log.d("TAG", "sReturn : " + sReturn);

				objStream.close();
			}
		} catch (IOException e) {
			Log.d("TAG", "postJsonData e : " + e);
			return null;
		}
		return sReturn;
	}

	private void setDialogWebView() {
		this.dialog = new Dialog(context);
		dialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
		this.webView = new WebView(context);
		this.webView.setWebViewClient(new WebViewClient() {

			private ProgressDialog progressDialog;

			@Override
			public boolean shouldOverrideUrlLoading(WebView webView, String url) {
				accessToken = parseAccessToken(postJsonData(POST_CODE_URL,callbackCode(url)));				
				dialog.dismiss();
				dialog = null;
				return false;
			}

			@Override
			public void onPageFinished(WebView view, String url) {				
				progressDialog.dismiss();
				try {
					Thread.sleep(200);
				} catch (InterruptedException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
				webView.setVisibility(View.VISIBLE);
			}

			@Override
			public void onPageStarted(WebView view, String url, Bitmap favicon) {
				webView.setVisibility(View.GONE);
				if(progressDialog == null)
					progressDialog = new ProgressDialog(context);
				
				progressDialog.setProgressStyle(ProgressDialog.STYLE_SPINNER);
				progressDialog.setMessage("Loading...");
				progressDialog.setIndeterminate(false);
				progressDialog.setCancelable(true);
                progressDialog.show();
			}

		});
		this.webView.getSettings().setJavaScriptEnabled(true);
		this.webView.getSettings().setLoadWithOverviewMode(true);
		this.webView.getSettings().setUseWideViewPort(true);
		this.webView.setVerticalScrollBarEnabled(false);
		this.webView.setHorizontalScrollBarEnabled(false);
		this.webView.setLayoutParams(FILL);
		dialog.setContentView(this.webView);
	}

	public void authorize() {
		if (dialog == null)
			setDialogWebView();

		this.webView.loadUrl(this.authorizeUrl);
		this.dialog.show();
	}

}


Mixiクラスのインスタンスを作ったらauthorizeメソッドで認証画面に飛ぶ。

Mixi mixi = new Mixi(Context context , String ConsumerKey, String ConsumerSecret);
mixi.authorize();


これで認証で許可されたら以下の部分でコールバックで帰ってきた
codeを再びmixiに投げてaccesstokenだけを正規表現で取得している。

@Override
public boolean shouldOverrideUrlLoading(WebView webView, String url) {
	accessToken = parseAccessToken(postJsonData(POST_CODE_URL,callbackCode(url)));				
	dialog.dismiss();
	dialog = null;
	return false;
}

注意

ちなみにここでは許可をしなかった場合もここを呼び出すため、
許可した場合のみここを読み込むように各自いじって下さい。

最低限投稿させるために作ったクラスなのでところどころ
未完成な部分があるので、あとはお好きにいじって下さい。