Java tutorial
/* * Copyright (C) 2011 mixi, Inc. All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package jp.mixi.android.sdk; import android.annotation.TargetApi; import android.app.Dialog; import android.content.Context; import android.content.Intent; import android.graphics.Bitmap; import android.net.Uri; import android.net.Uri.Builder; import android.os.Build; import android.os.Bundle; import android.os.Handler; import android.util.Log; import android.view.View; import android.view.animation.AnimationUtils; import android.webkit.WebView; import android.webkit.WebViewClient; import android.widget.TextView; import jp.mixi.android.sdk.util.UrlUtils; import org.apache.http.protocol.HTTP; import org.json.JSONException; import org.json.JSONObject; import java.io.UnsupportedEncodingException; import java.net.URLEncoder; import java.util.HashMap; import java.util.Iterator; import java.util.Map; /** * * WebVew */ @TargetApi(8) class MixiDialog extends Dialog { private static final String TAG = "MixiDialog"; /** ??URL */ private String mUrl; /** ??? */ private CallbackListener mListener; private Map<String, String> mParams; private Handler mHandler = new Handler(); /** * ??? * * ???this??????? * * @param context ??????????Activity??????? * @param url ?WebView?????URL??????? * @param params * @param listener ????????DialogListener??????? * @param isCancelable false????????? */ public MixiDialog(Context context, String url, Map<String, String> params, CallbackListener listener, boolean isCancelable) { super(context, R.style.Theme_MixiDialogTheme); this.mUrl = url; this.mListener = listener; this.mParams = params; this.setCancelable(isCancelable); } @Override protected void onCreate(Bundle bundle) { super.onCreate(bundle); setContentView(R.layout.client_authentication_dialog); setUpWebView((WebView) findViewById(R.id.webview)); } private WebView setUpWebView(WebView webView) { Log.v(TAG, "setwebview"); webView.getSettings().setUserAgentString(Constants.USER_AGENT); webView.setVerticalScrollBarEnabled(false); webView.setHorizontalScrollBarEnabled(false); webView.setWebViewClient(new MixiWebviewClient()); webView.getSettings().setJavaScriptEnabled(true); webView.addJavascriptInterface(new JsHandler(), "mixi"); String token = mParams.get("oauth_token"); int sdkInt = Integer.valueOf(Build.VERSION.SDK); // android2.1 if (sdkInt < Constants.SUPPORTED_SDK_VERSION) { Uri uri = Uri.parse(mUrl); if (token != null) { Builder builder = uri.buildUpon(); builder.appendQueryParameter("oauth_token", token); uri = builder.build(); } webView.loadUrl(uri.toString()); } else { HashMap<String, String> extraHeaders = new HashMap<String, String>(); if (token != null) { extraHeaders.put("Authorization", "OAuth " + token); } webView.loadUrl(mUrl, extraHeaders); } return webView; } private void showLoading(int resId) { showLoading(getContext().getText(resId).toString()); } private void showLoading(String message) { ((TextView) findViewById(R.id.progressLabel)).setText(message); View progress = findViewById(R.id.progress); progress.setVisibility(View.VISIBLE); progress.startAnimation(AnimationUtils.loadAnimation(getContext(), android.R.anim.fade_in)); View webView = findViewById(R.id.webview); webView.setVisibility(View.GONE); webView.startAnimation(AnimationUtils.loadAnimation(getContext(), android.R.anim.fade_out)); } private void hideLoading() { View progress = findViewById(R.id.progress); progress.setVisibility(View.GONE); progress.startAnimation(AnimationUtils.loadAnimation(getContext(), android.R.anim.fade_out)); View webView = findViewById(R.id.webview); webView.setVisibility(View.VISIBLE); webView.requestFocus(View.FOCUS_DOWN); webView.startAnimation(AnimationUtils.loadAnimation(getContext(), android.R.anim.fade_in)); } /** * ?????????????? * * @param url url * @param data */ private void postUrl(final String url, final byte[] data) { mHandler.post(new Runnable() { @Override public void run() { WebView webView = (WebView) findViewById(R.id.webview); webView.postUrl(url, data); } }); } /** * ??WebView?Client */ private final class MixiWebviewClient extends WebViewClient { private static final String TAG = "MixiWebviewClient"; @Override public boolean shouldOverrideUrlLoading(WebView view, String url) { // ??? Log.d(TAG, "redirect:" + url); // ?URL??? if (url.startsWith(Constants.REDIRECT_URI)) { Bundle values = UrlUtils.decodeUrlToBundle(url); Log.v(TAG, "onComplete"); MixiDialog.this.dismiss(); mListener.onComplete(values); return true; } else if (url.startsWith(Constants.ERROR_URI)) { Bundle values = UrlUtils.decodeUrlToBundle(url); String error = values.getString("error"); String errorCd = values.getString("code"); MixiDialog.this.dismiss(); if (errorCd == null) { mListener.onError(new ErrorInfo(error)); } else { mListener.onError(new ErrorInfo(error, Integer.parseInt(errorCd), url)); } return true; } else if (url.startsWith(Constants.CANCEL_URI)) { Log.v(TAG, "onCancel"); MixiDialog.this.dismiss(); mListener.onCancel(); return true; } else if (url.startsWith(Constants.GRAPH_BASE_URL)) { // ??????? Log.v(TAG, "inner redirect"); MixiDialog.this.dismiss(); return false; } Log.v(TAG, "nomal redirect"); // ??URL?Intent.ACTION_VIEW??? getContext().startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse(url))); MixiDialog.this.dismiss(); return true; } @Override public void onReceivedError(WebView view, int errorCode, String description, String failingUrl) { super.onReceivedError(view, errorCode, description, failingUrl); hideLoading(); MixiDialog.this.dismiss(); mListener.onFatal(new ErrorInfo(description, errorCode, failingUrl)); } @Override public void onPageStarted(WebView view, String url, Bitmap favicon) { // ??????? super.onPageStarted(view, url, favicon); Log.d(TAG, "page start"); showLoading(R.string.loading_message); } @Override public void onPageFinished(WebView view, String url) { Log.d(TAG, "load success"); // ??????? hideLoading(); super.onPageFinished(view, url); } } /** * */ public class JsHandler { /** * webView???? * * onClick(mixi.post()) * * ?????????js???????????? * * @param endpoint ????API??(???????????) * @param params JSON??? */ public void post(String endpoint, String params) { try { // POST??? JSONObject root = new JSONObject(params); Builder builder = new Builder(); builder.appendQueryParameter("oauth_token", mParams.get("oauth_token")); for (@SuppressWarnings("unchecked") Iterator<String> iterator = root.keys(); iterator.hasNext();) { String key = (String) iterator.next(); builder.appendQueryParameter(key, URLEncoder.encode(root.getString(key), HTTP.UTF_8)); } // webView? postUrl(Constants.GRAPH_BASE_URL + endpoint, builder.build().getQuery().getBytes()); } catch (JSONException e) { MixiDialog.this.dismiss(); mListener.onFatal(new ErrorInfo(e)); } catch (UnsupportedEncodingException e) { MixiDialog.this.dismiss(); mListener.onFatal(new ErrorInfo(e)); } } } }